agent-runtime-infra-adapter 0.1.1

Internal Agent Infra SDK adapter for Agent Runtime ports
Documentation
use std::collections::BTreeMap;

use async_trait::async_trait;
use runtime_ports::{
    OperationContext, PortFailure, PortFailureKind, ResolvedExecutionContext,
    RuntimeInstanceResolver,
};
use runtime_types::{CallerScope, RuntimeInstanceId, WorkspaceId};

#[derive(Debug, Clone)]
pub struct RuntimeBinding {
    pub agent_id: String,
    pub runtime_type: String,
    pub model: String,
    pub workspace_id: WorkspaceId,
    pub definition_id: String,
    pub definition_version: String,
    pub definition_digest: Option<String>,
    pub metadata: BTreeMap<String, String>,
}

pub struct StaticRuntimeBindingResolver {
    bindings: BTreeMap<RuntimeInstanceId, RuntimeBinding>,
}

impl StaticRuntimeBindingResolver {
    pub fn new(bindings: BTreeMap<RuntimeInstanceId, RuntimeBinding>) -> Result<Self, PortFailure> {
        if bindings.is_empty() {
            return Err(PortFailure::new(
                PortFailureKind::Invalid,
                "RUNTIME_BINDINGS_EMPTY",
                "at least one runtime binding is required",
            ));
        }
        for binding in bindings.values() {
            if !binding.agent_id.starts_with("agt_")
                || binding.runtime_type.is_empty()
                || binding.model.is_empty()
                || binding.definition_id.is_empty()
                || binding.definition_version.is_empty()
            {
                return Err(PortFailure::new(
                    PortFailureKind::Invalid,
                    "RUNTIME_BINDING_INVALID",
                    "Infra Agent ID, runtime type, model, definition ID, and definition version are required",
                ));
            }
        }
        Ok(Self { bindings })
    }
}

#[async_trait]
impl RuntimeInstanceResolver for StaticRuntimeBindingResolver {
    async fn resolve(
        &self,
        _: &OperationContext,
        _: &CallerScope,
        id: &RuntimeInstanceId,
    ) -> Result<ResolvedExecutionContext, PortFailure> {
        let binding = self.bindings.get(id).ok_or_else(|| {
            PortFailure::new(
                PortFailureKind::NotFound,
                "RUNTIME_BINDING_NOT_FOUND",
                "runtime binding was not found",
            )
        })?;
        Ok(ResolvedExecutionContext {
            runtime_instance_id: id.clone(),
            agent_id: binding.agent_id.clone(),
            runtime_type: binding.runtime_type.clone(),
            model: binding.model.clone(),
            workspace_id: binding.workspace_id.clone(),
            definition_id: binding.definition_id.clone(),
            definition_version: binding.definition_version.clone(),
            definition_digest: binding.definition_digest.clone(),
            metadata: binding.metadata.clone(),
        })
    }
}