agent-context-contract 0.2.2

Transport-neutral contracts for Agent Infra context APIs
Documentation
use serde::{Deserialize, Serialize};
use serde_json::Value;

use crate::{AuthorizedScope, ConversationScope};

pub const WINDOWS_PATH: &str = "/internal/v1/context/windows";
pub const WINDOW_GET_PATH: &str = "/internal/v1/context/windows/get";
pub const DERIVATIONS_PATH: &str = "/internal/v1/context/derivations";
pub const MODEL_INVOCATIONS_PATH: &str = "/internal/v1/context/model-invocations";
pub const MODEL_INVOCATION_GET_PATH: &str = "/internal/v1/context/model-invocations/get";
pub const MAX_WINDOW_ITEMS: usize = 2_000;
pub const MAX_WINDOW_BYTES: usize = 16 * 1024 * 1024;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ContextWindowStage {
    Original,
    Assembled,
    Compressed,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ContextWindowItemKind {
    Message,
    ToolResult,
    ContextInsight,
    KnowledgeEvidence,
}

/// The smallest replayable external-knowledge record. References are opaque to
/// Context Infra and never imply ownership of the provider's source document.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct KnowledgeEvidence {
    pub provider: String,
    pub resource_ref: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub revision_ref: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub segment_ref: Option<String>,
    pub excerpt: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub citation: Option<String>,
    #[serde(default, skip_serializing_if = "Value::is_null")]
    pub metadata: Value,
}

/// One ordered item that was actually visible to the model.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct ContextWindowItem {
    pub id: String,
    pub ordinal: u32,
    pub kind: ContextWindowItemKind,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub role: Option<String>,
    pub content: Value,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub source_record_id: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub knowledge_evidence: Option<KnowledgeEvidence>,
    #[serde(default, skip_serializing_if = "Value::is_null")]
    pub metadata: Value,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct ContextWindow {
    pub id: String,
    pub scope: AuthorizedScope,
    pub conversation: ConversationScope,
    pub stage: ContextWindowStage,
    pub purpose: String,
    pub token_count: u64,
    pub items: Vec<ContextWindowItem>,
    pub created_at_ms: i64,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct CreateContextWindowRequest {
    pub id: String,
    pub conversation: ConversationScope,
    pub stage: ContextWindowStage,
    pub purpose: String,
    pub token_count: u64,
    pub items: Vec<ContextWindowItem>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct GetContextWindowRequest {
    pub window_id: String,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ContextDerivationKind {
    Assemble,
    Compress,
    Trim,
    Reorder,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct ContextDerivation {
    pub id: String,
    pub scope: AuthorizedScope,
    pub source_window_id: String,
    pub target_window_id: String,
    pub kind: ContextDerivationKind,
    pub strategy: String,
    pub strategy_version: String,
    pub input_token_count: u64,
    pub output_token_count: u64,
    pub input_item_count: u32,
    pub output_item_count: u32,
    #[serde(default, skip_serializing_if = "Value::is_null")]
    pub metadata: Value,
    pub created_at_ms: i64,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct CreateContextDerivationRequest {
    pub id: String,
    pub source_window_id: String,
    pub target_window_id: String,
    pub kind: ContextDerivationKind,
    pub strategy: String,
    pub strategy_version: String,
    pub input_token_count: u64,
    pub output_token_count: u64,
    pub input_item_count: u32,
    pub output_item_count: u32,
    #[serde(default, skip_serializing_if = "Value::is_null")]
    pub metadata: Value,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ModelInvocationState {
    Prepared,
    Succeeded,
    Failed,
}

/// Audit record for the exact request snapshot supplied to one model call.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct ModelInvocation {
    pub id: String,
    pub scope: AuthorizedScope,
    pub conversation_id: String,
    pub request_window_id: String,
    pub model: String,
    pub provider: String,
    pub state: ModelInvocationState,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub response: Option<Value>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub error_code: Option<String>,
    #[serde(default, skip_serializing_if = "Value::is_null")]
    pub usage: Value,
    pub created_at_ms: i64,
    pub completed_at_ms: Option<i64>,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct PutModelInvocationRequest {
    pub id: String,
    pub conversation_id: String,
    pub request_window_id: String,
    pub model: String,
    pub provider: String,
    pub state: ModelInvocationState,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub response: Option<Value>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub error_code: Option<String>,
    #[serde(default, skip_serializing_if = "Value::is_null")]
    pub usage: Value,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub completed_at_ms: Option<i64>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct GetModelInvocationRequest {
    pub invocation_id: String,
}