use chio_core::capability::{
CapabilityToken, GovernedApprovalToken, GovernedTransactionIntent, ModelMetadata,
};
use chio_core::receipt::ChioReceipt;
use chio_core::session::{
CreateElicitationOperation, CreateElicitationResult, CreateMessageOperation,
CreateMessageResult, OperationContext, OperationTerminalState, RequestId, RootDefinition,
};
use crate::dpop;
use crate::execution_nonce::SignedExecutionNonce;
use crate::{AgentId, KernelError, ServerId};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Verdict {
Allow,
Deny,
PendingApproval,
}
#[derive(Debug)]
pub struct ToolCallRequest {
pub request_id: String,
pub capability: CapabilityToken,
pub tool_name: String,
pub server_id: ServerId,
pub agent_id: AgentId,
pub arguments: serde_json::Value,
pub dpop_proof: Option<dpop::DpopProof>,
pub governed_intent: Option<GovernedTransactionIntent>,
pub approval_token: Option<GovernedApprovalToken>,
pub model_metadata: Option<ModelMetadata>,
pub federated_origin_kernel_id: Option<String>,
}
#[derive(Debug)]
pub struct ToolCallResponse {
pub request_id: String,
pub verdict: Verdict,
pub output: Option<ToolCallOutput>,
pub reason: Option<String>,
pub terminal_state: OperationTerminalState,
pub receipt: ChioReceipt,
pub execution_nonce: Option<Box<SignedExecutionNonce>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ToolCallChunk {
pub data: serde_json::Value,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ToolCallStream {
pub chunks: Vec<ToolCallChunk>,
}
impl ToolCallStream {
pub fn chunk_count(&self) -> u64 {
self.chunks.len() as u64
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum ToolCallOutput {
Value(serde_json::Value),
Stream(ToolCallStream),
}
#[derive(Debug, Clone, PartialEq)]
pub enum ToolServerStreamResult {
Complete(ToolCallStream),
Incomplete {
stream: ToolCallStream,
reason: String,
},
}
#[derive(Debug, Clone, PartialEq)]
pub enum ToolServerOutput {
Value(serde_json::Value),
Stream(ToolServerStreamResult),
}
pub trait NestedFlowBridge {
fn parent_request_id(&self) -> &RequestId;
fn poll_parent_cancellation(&mut self) -> Result<(), KernelError> {
Ok(())
}
fn list_roots(&mut self) -> Result<Vec<RootDefinition>, KernelError>;
fn create_message(
&mut self,
operation: CreateMessageOperation,
) -> Result<CreateMessageResult, KernelError>;
fn create_elicitation(
&mut self,
operation: CreateElicitationOperation,
) -> Result<CreateElicitationResult, KernelError>;
fn notify_elicitation_completed(&mut self, elicitation_id: &str) -> Result<(), KernelError>;
fn notify_resource_updated(&mut self, uri: &str) -> Result<(), KernelError>;
fn notify_resources_list_changed(&mut self) -> Result<(), KernelError>;
}
pub trait NestedFlowClient {
fn poll_parent_cancellation(
&mut self,
_parent_context: &OperationContext,
) -> Result<(), KernelError> {
Ok(())
}
fn list_roots(
&mut self,
parent_context: &OperationContext,
child_context: &OperationContext,
) -> Result<Vec<RootDefinition>, KernelError>;
fn create_message(
&mut self,
parent_context: &OperationContext,
child_context: &OperationContext,
operation: &CreateMessageOperation,
) -> Result<CreateMessageResult, KernelError>;
fn create_elicitation(
&mut self,
parent_context: &OperationContext,
child_context: &OperationContext,
operation: &CreateElicitationOperation,
) -> Result<CreateElicitationResult, KernelError>;
fn notify_elicitation_completed(
&mut self,
parent_context: &OperationContext,
elicitation_id: &str,
) -> Result<(), KernelError>;
fn notify_resource_updated(
&mut self,
parent_context: &OperationContext,
uri: &str,
) -> Result<(), KernelError>;
fn notify_resources_list_changed(
&mut self,
parent_context: &OperationContext,
) -> Result<(), KernelError>;
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ToolInvocationCost {
pub units: u64,
pub currency: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub breakdown: Option<serde_json::Value>,
}
pub trait ToolServerConnection: Send + Sync {
fn server_id(&self) -> &str;
fn tool_names(&self) -> Vec<String>;
fn invoke(
&self,
tool_name: &str,
arguments: serde_json::Value,
nested_flow_bridge: Option<&mut dyn NestedFlowBridge>,
) -> Result<serde_json::Value, KernelError>;
fn invoke_with_cost(
&self,
tool_name: &str,
arguments: serde_json::Value,
nested_flow_bridge: Option<&mut dyn NestedFlowBridge>,
) -> Result<(serde_json::Value, Option<ToolInvocationCost>), KernelError> {
let value = self.invoke(tool_name, arguments, nested_flow_bridge)?;
Ok((value, None))
}
fn invoke_stream(
&self,
tool_name: &str,
arguments: serde_json::Value,
nested_flow_bridge: Option<&mut dyn NestedFlowBridge>,
) -> Result<Option<ToolServerStreamResult>, KernelError> {
let _ = (tool_name, arguments, nested_flow_bridge);
Ok(None)
}
fn drain_events(&self) -> Result<Vec<ToolServerEvent>, KernelError> {
Ok(vec![])
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ToolServerEvent {
ElicitationCompleted { elicitation_id: String },
ResourceUpdated { uri: String },
ResourcesListChanged,
ToolsListChanged,
PromptsListChanged,
}