Forge documentation
Library referenceRust

forge-core

Core types, provider traits, telemetry, and configuration for the Forge SDK

Core types, provider traits, telemetry, and configuration for the Forge SDK

Package contract

FieldValue
Languagerust
Source version0.2.0
Manifestforge-rs/crates/forge-core/Cargo.toml
Source files18
EvidenceSource reference; registry publication and runtime conformance are separate checks

Import boundary

use forge_core;

Use a source checkout or your verified private registry. Manifest coordinates identify the package; they do not establish that a public registry release exists.

Crate boundary

The following entries are taken from src/lib.rs. Feature conditions in the exact source still apply.

pub mod brew;

pub mod brew_builder;

pub mod brew_resolver;

pub mod config;

pub mod error;

pub mod message;

pub mod model;

pub mod output;

pub mod provider;

pub mod provider_runtime;

pub mod replay;

pub mod routing;

pub mod schema;

pub mod telemetry;

pub mod tool;

pub mod topology;

pub mod types;

pub mod prelude;

pub use crate::brew::{
        Brew, BrewEdge, BrewEdgeKind, BrewId, BrewNode, BrewNodeKind, BrewVersion, JoinMode, NodeId,
    };

pub use crate::brew_builder::BrewBuilder;

pub use crate::brew_resolver::{
        BrewEnvironment, BrewResolutionError, BrewResolutionErrorKind, ResolvedBrewPlan,
        ResolvedNode, ResolvedNodeKind,
    };

pub use crate::config::{EmbedOptions, GenerateOptions};

pub use crate::error::{ForgeError, ForgeResult};

pub use crate::message::{MessagePart, ModelMessage, Role};

pub use crate::model::LanguageModel;

pub use crate::output::{FinishReason, GenerateResult, StreamChunk, Usage};

pub use crate::provider::{ProviderRef, ProviderRegistry};

pub use crate::provider_runtime::{
        ProviderNegotiationRequest, ProviderNegotiationResult, ProviderRuntimeCapabilities,
        ProviderSessionEvent, ProviderSessionState, ProviderUsageSummary, RuntimeCapability,
    };

pub use crate::replay::{
        legacy_accept_from_env, ReplayConfig, ReplayError, ReplayValidator, DEFAULT_CLOCK_SKEW,
        DEFAULT_NONCE_CACHE_SIZE,
    };

pub use crate::routing::{
        DefaultModelRouter, ExecutionTopology, ModelRouter, ResolvedRoute, RoutingContext, TaskMode,
    };

pub use crate::schema::JsonSchema;

pub use crate::telemetry::{ForgeEvent, ForgeSpan, TelemetryEmitter};

pub use crate::tool::{ToolApproval, ToolCall, ToolDefinition, ToolResult, ToolTier};

pub use crate::topology::{
        CostPreference, LatencyPreference, ModelSlot, ModelTopology, TopologyBuilder,
    };

pub use crate::types::{AgentDid, Timestamp};

Source reference

Download package reference JSON. Each original source file and generated declaration artifact has its own SHA-256 digest. Function bodies and constant values are omitted from downloads. These are source declaration inventories, not compiler-resolved rustdoc, TypeDoc, DocC, or Dokka output. Private modules can contain public declarations that are not reachable through the package boundary; consult the entry point before importing.

brew.rs

Read declaration text · 15 declaration entries

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct BrewId(String);

pub fn new(id: impl Into<String>) -> Self;

pub fn as_str(&self) -> &str;

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct NodeId(String);

pub fn new(id: impl Into<String>) -> Self;

pub fn as_str(&self) -> &str;

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct BrewVersion(String);

pub fn new(version: impl Into<String>) -> Self;

pub fn as_str(&self) -> &str;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum JoinMode {
    /// Wait for all branches to complete. Fail if any branch fails.
    AwaitAll,
    /// Return as soon as one branch completes successfully.
    FirstSuccess,
    /// Return as soon as N branches complete successfully.
    FirstN(u32),
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum BrewNodeKind {
    /// An agent step: send a prompt to a model, optionally with tools.
    ///
    /// Maps to a single invocation of the Forge agent execution loop.
    AgentStep {
        /// Provider reference (e.g., `openai:gpt-4o`). Symbolic -- resolved
        /// during the freeze step.
        provider: ProviderRef,
        /// Optional system prompt for this step.
        #[serde(default, skip_serializing_if = "Option::is_none")]
        system_prompt: Option<String>,
        /// Maximum tool-loop steps for this agent invocation.
        max_steps: u32,
    },

    /// A direct tool invocation without an LLM in the loop.
    ToolInvocation {
        /// Tool identifier. Must resolve to a registered tool at freeze time.
        tool_id: String,
        /// Tool tier classification.
        tier: ToolTier,
    },

    /// An MCP tool call routed through a connected MCP server.
    McpCall {
        /// MCP server identifier (URI or alias).
        server_id: String,
        /// MCP tool name on the remote server.
        tool_name: String,
    },

    /// A web operation (HTTP request, browser action, etc.).
    WebOperation {
        /// The operation kind identifier.
        operation: String,
    },

    /// A conditional branch that routes to one of two targets based on a
    /// condition expression.
    ConditionalBranch {
        /// JSONPath or simple expression evaluated against incoming data.
        condition_expr: String,
        /// The node to route to when the condition is true.
        true_target: NodeId,
        /// The node to route to when the condition is false.
        false_target: NodeId,
    },

    /// A parallel fork that spawns concurrent execution of multiple
    /// downstream paths, then joins their results.
    ParallelFork {
        /// The set of branch targets to execute concurrently.
        branches: Vec<NodeId>,
        /// Strategy for joining parallel results.
        join_mode: JoinMode,
    },

    /// A reference to another brew, enabling composition. The referenced
    /// brew is resolved and inlined at freeze time.
    SubBrewRef {
        /// The referenced brew's identifier.
        brew_id: BrewId,
    },

    /// A human-in-the-loop checkpoint that suspends execution until a
    /// human provides approval or input.
    HumanCheckpoint {
        /// The prompt displayed to the human reviewer.
        prompt: String,
        /// Maximum wait time in milliseconds before timeout. `None` means
        /// wait indefinitely.
        #[serde(default, skip_serializing_if = "Option::is_none")]
        timeout_ms: Option<u64>,
    },
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BrewNode {
/// Stable identifier within this brew.

pub id: NodeId,
/// The node's execution semantics.

pub kind: BrewNodeKind,
/// Arbitrary key-value metadata for tooling and visualization.

#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub metadata: BTreeMap<String, String>
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum BrewEdgeKind {
    /// Data flow: output of source is fed as input to target.
    DataFlow,
    /// Control flow: target executes after source completes.
    ControlFlow,
    /// Error flow: target executes when source fails.
    ErrorFlow,
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct BrewEdge {
/// Source node.

pub from: NodeId,
/// Target node.

pub to: NodeId,
/// Edge semantics.

pub kind: BrewEdgeKind
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Brew {
/// Unique identifier for this brew definition.

pub id: BrewId,
/// Semantic version of this brew definition.

pub version: BrewVersion,
/// The graph's nodes, keyed by stable node ID.

/// `BTreeMap` ensures deterministic serialization order.

pub nodes: BTreeMap<NodeId, BrewNode>,
/// The graph's edges. `BTreeSet` ensures deterministic ordering

/// by `(from, to, kind)`.

pub edges: BTreeSet<BrewEdge>,
/// Designated entry nodes. Execution begins at these nodes.

pub entry_nodes: Vec<NodeId>,
/// Designated exit nodes. When all exit nodes complete, the brew

/// execution is complete.

pub exit_nodes: Vec<NodeId>,
/// Optional model topology for this brew. When set, it provides

/// the multi-model slot configuration for agent steps.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub topology: Option<ModelTopology>
}

brew_builder.rs

Read declaration text · 9 declaration entries

#[derive(Debug)]
pub struct BrewBuilder {

}

pub fn new(id: impl Into<String>, version: impl Into<String>) -> Self;

pub fn add_node(&mut self, node_id: impl Into<String>, kind: BrewNodeKind) -> &mut Self;

pub fn add_edge(
        &mut self,
        from: impl Into<String>,
        to: impl Into<String>,
        edge_kind: BrewEdgeKind,
    ) -> &mut Self;

pub fn set_entry(&mut self, node_id: impl Into<String>) -> &mut Self;

pub fn set_exit(&mut self, node_id: impl Into<String>) -> &mut Self;

pub fn with_topology(&mut self, topology: ModelTopology) -> &mut Self;

pub fn with_metadata(
        &mut self,
        node_id: impl AsRef<str>,
        key: impl Into<String>,
        value: impl Into<String>,
    ) -> &mut Self;

pub fn build(&mut self) -> ForgeResult<Brew>;

brew_resolver.rs

Read declaration text · 7 declaration entries

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BrewEnvironment {
/// Registered model providers, keyed by their `namespace:model` string.

pub providers: BTreeMap<String, ProviderRef>,
/// Registered tool names available in this environment.

pub tools: BTreeSet<String>,
/// Connected MCP server identifiers (URIs or aliases).

pub mcp_servers: BTreeSet<String>,
/// Web capabilities available in this environment.

pub web_capabilities: BTreeSet<String>,
/// Brew definitions available for sub-brew composition.

pub sub_brews: BTreeSet<BrewId>
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum BrewResolutionErrorKind {
    /// A provider reference in an `AgentStep` node is not registered.
    ProviderUnavailable,
    /// A tool name in a `ToolInvocation` node is not registered.
    ToolNotFound,
    /// An MCP server in an `McpCall` node is not connected.
    McpServerNotFound,
    /// A web capability in a `WebOperation` node is not available.
    WebCapabilityUnavailable,
    /// A sub-brew reference in a `SubBrewRef` node is not in the registry.
    SubBrewNotFound,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct BrewResolutionError {
/// The node that failed resolution.

pub node_id: NodeId,
/// What went wrong.

pub error_kind: BrewResolutionErrorKind
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ResolvedNodeKind {
    /// Agent step with verified provider.
    AgentStep {
        /// Verified provider reference.
        provider: ProviderRef,
        /// Optional system prompt.
        #[serde(default, skip_serializing_if = "Option::is_none")]
        system_prompt: Option<String>,
        /// Maximum tool-loop steps.
        max_steps: u32,
    },
    /// Tool invocation with verified tool name.
    ToolInvocation {
        /// Verified tool identifier.
        tool_id: String,
        /// Tool tier classification.
        tier: ToolTier,
    },
    /// MCP call with verified server and tool.
    McpCall {
        /// Verified MCP server identifier.
        server_id: String,
        /// Tool name on the remote server.
        tool_name: String,
    },
    /// Web operation with verified capability.
    WebOperation {
        /// Verified operation kind.
        operation: String,
    },
    /// Conditional branch with verified targets.
    ConditionalBranch {
        /// Condition expression.
        condition_expr: String,
        /// Verified true target.
        true_target: NodeId,
        /// Verified false target.
        false_target: NodeId,
    },
    /// Parallel fork with verified branches.
    ParallelFork {
        /// Verified branch targets.
        branches: Vec<NodeId>,
        /// Join strategy.
        join_mode: JoinMode,
    },
    /// Sub-brew reference (verified to exist).
    SubBrewRef {
        /// Verified brew identifier.
        brew_id: BrewId,
    },
    /// Human checkpoint (no external references to verify).
    HumanCheckpoint {
        /// Prompt text.
        prompt: String,
        /// Optional timeout.
        #[serde(default, skip_serializing_if = "Option::is_none")]
        timeout_ms: Option<u64>,
    },
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResolvedNode {
/// The node identifier.

pub id: NodeId,
/// The resolved (verified) node kind.

pub kind: ResolvedNodeKind
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResolvedBrewPlan {
/// Deterministic plan identifier: `BLAKE3(brew_id || brew_version ||

/// environment_hash)`. Does **not** include timestamps.

pub plan_id: String,
/// The source brew's identifier.

pub brew_id: BrewId,
/// The source brew's version.

pub brew_version: BrewVersion,
/// ISO 8601 timestamp of when resolution occurred. Runtime metadata,

/// **not** included in `plan_id`.

pub resolved_at: String,
/// BLAKE3 hash of the serialized `BrewEnvironment`.

pub environment_hash: String,
/// Resolved nodes keyed by node ID.

pub nodes: BTreeMap<NodeId, ResolvedNode>,
/// Edges from the original brew (unchanged -- edges carry no symbolic

/// references that need resolution).

pub edges: BTreeSet<BrewEdge>,
/// Topologically sorted execution order.

pub execution_order: Vec<NodeId>,
/// Entry nodes from the original brew.

pub entry_nodes: Vec<NodeId>,
/// Exit nodes from the original brew.

pub exit_nodes: Vec<NodeId>
}

pub fn resolve(
    brew: &Brew,
    environment: &BrewEnvironment,
) -> Result<ResolvedBrewPlan, Vec<BrewResolutionError>>;

config.rs

Read declaration text · 13 declaration entries

pub use crate::replay::{ReplayConfig, DEFAULT_CLOCK_SKEW, DEFAULT_NONCE_CACHE_SIZE};

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct GenerateOptions {
/// Sampling temperature (0.0 = deterministic, 2.0 = maximum randomness).

#[serde(skip_serializing_if = "Option::is_none")]
pub temperature: Option<f64>,
/// Maximum tokens to generate.

#[serde(skip_serializing_if = "Option::is_none")]
pub max_tokens: Option<u32>,
/// Top-p (nucleus) sampling threshold.

#[serde(skip_serializing_if = "Option::is_none")]
pub top_p: Option<f64>,
/// Stop sequences — generation stops when any of these are produced.

#[serde(skip_serializing_if = "Option::is_none")]
pub stop_sequences: Option<Vec<String>>,
/// Frequency penalty (-2.0 to 2.0).

#[serde(skip_serializing_if = "Option::is_none")]
pub frequency_penalty: Option<f64>,
/// Presence penalty (-2.0 to 2.0).

#[serde(skip_serializing_if = "Option::is_none")]
pub presence_penalty: Option<f64>,
/// Seed for deterministic generation (if supported by provider).

#[serde(skip_serializing_if = "Option::is_none")]
pub seed: Option<u64>,
/// JSON schema for structured output enforcement.

#[serde(skip_serializing_if = "Option::is_none")]
pub output_schema: Option<JsonSchema>
}

pub fn with_temperature(mut self, temperature: f64) -> Self;

pub fn with_max_tokens(mut self, max_tokens: u32) -> Self;

pub fn with_top_p(mut self, top_p: f64) -> Self;

pub fn with_stop_sequences(mut self, sequences: Vec<String>) -> Self;

pub fn with_frequency_penalty(mut self, penalty: f64) -> Self;

pub fn with_presence_penalty(mut self, penalty: f64) -> Self;

pub fn with_seed(mut self, seed: u64) -> Self;

pub fn with_output_schema(mut self, schema: JsonSchema) -> Self;

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct EmbedOptions {
/// The embedding model to use (if different from default).

#[serde(skip_serializing_if = "Option::is_none")]
pub model: Option<String>,
/// Dimensionality of the output embeddings (if configurable).

#[serde(skip_serializing_if = "Option::is_none")]
pub dimensions: Option<u32>
}

pub fn with_model(mut self, model: impl Into<String>) -> Self;

pub fn with_dimensions(mut self, dimensions: u32) -> Self;

error.rs

Read declaration text · 2 declaration entries

#[derive(Debug, Error)]
pub enum ForgeError {
    /// A provider was not found in the registry.
    #[error("provider '{provider_ref}' not found in registry; register it with ProviderRegistry::register() before use")]
    ProviderNotFound {
        /// The provider reference that was looked up (e.g., "openai:gpt-4o").
        provider_ref: String,
    },

    /// A provider reference string is malformed.
    #[error("invalid provider reference '{input}': expected format 'namespace:model' (e.g., 'openai:gpt-4o')")]
    InvalidProviderRef {
        /// The malformed input string.
        input: String,
    },

    /// JSON schema validation failed.
    #[error("schema validation failed at path '{path}': {reason}")]
    SchemaValidation {
        /// JSON pointer path to the failing field.
        path: String,
        /// Human-readable description of what was expected.
        reason: String,
    },

    /// An invalid lifecycle state transition was attempted.
    ///
    /// See ANVIL Spec §5.1 — Lifecycle State Machine for valid transitions.
    #[error("invalid lifecycle transition from {from} to {to}: {reason} (see ANVIL Spec §5.1)")]
    InvalidLifecycleTransition {
        /// The current state.
        from: String,
        /// The attempted target state.
        to: String,
        /// Why this transition is invalid.
        reason: String,
    },

    /// A tool invocation was denied due to insufficient capabilities.
    #[error("tool '{tool_name}' invocation denied: agent {agent_did} lacks capability '{required_capability}' in Arsenal ACT {act_id}")]
    ToolInvocationDenied {
        /// The tool that was being invoked.
        tool_name: String,
        /// The agent's DID.
        agent_did: String,
        /// The capability that was required but missing.
        required_capability: String,
        /// The ACT that was checked.
        act_id: String,
    },

    /// A tool execution failed.
    #[error("tool '{tool_name}' execution failed: {reason}")]
    ToolExecutionFailed {
        /// The tool that failed.
        tool_name: String,
        /// What went wrong.
        reason: String,
    },

    /// JSON serialization or deserialization failed.
    #[error("JSON error: {0}")]
    Json(#[from] serde_json::Error),

    /// A required configuration value is missing.
    #[error("missing configuration: {field} is required ({hint})")]
    MissingConfig {
        /// The configuration field name.
        field: String,
        /// A hint about where to set this value.
        hint: String,
    },

    /// The stop condition limit was reached.
    #[error("generation stopped: {reason} (steps={steps}, tokens={tokens})")]
    StopConditionReached {
        /// Why generation was stopped.
        reason: String,
        /// Number of steps completed.
        steps: u32,
        /// Total tokens consumed.
        tokens: u64,
    },

    /// A telemetry emission failed. Non-fatal but logged.
    #[error("telemetry emission failed: {reason}")]
    TelemetryError {
        /// What went wrong with telemetry.
        reason: String,
    },

    /// The model does not support the requested operation.
    #[error("model '{model}' does not support {operation}")]
    UnsupportedOperation {
        /// The model identifier.
        model: String,
        /// The operation that was requested.
        operation: String,
    },

    /// The provider exists but is not currently available.
    #[error("provider '{provider_ref}' is unavailable: {reason}")]
    ProviderUnavailable {
        /// The provider reference that could not be used.
        provider_ref: String,
        /// Human-readable unavailability reason.
        reason: String,
    },

    /// Provider authentication failed.
    #[error("provider '{provider_ref}' authentication failed: {reason}")]
    ProviderAuthenticationFailed {
        /// The provider reference that failed authentication.
        provider_ref: String,
        /// Human-readable authentication failure reason.
        reason: String,
    },

    /// The provider does not support a required runtime capability.
    #[error("provider '{provider_ref}' does not support runtime capability '{capability}'")]
    CapabilityUnsupported {
        /// The provider reference that was negotiated.
        provider_ref: String,
        /// The missing runtime capability.
        capability: String,
    },

    /// Provider runtime negotiation failed.
    #[error("provider '{provider_ref}' negotiation failed: {reason}")]
    ProviderNegotiationFailed {
        /// The provider reference that was negotiated.
        provider_ref: String,
        /// Human-readable negotiation failure reason.
        reason: String,
    },

    /// The provider session expired before the requested action could complete.
    #[error("provider '{provider_ref}' session '{session_id}' expired before the requested action completed")]
    ProviderSessionExpired {
        /// The provider reference for the expired session.
        provider_ref: String,
        /// The expired session identifier.
        session_id: String,
    },

    /// The provider does not support interrupts.
    #[error("provider '{provider_ref}' does not support session interrupts")]
    ProviderInterruptUnsupported {
        /// The provider reference that lacks interrupt support.
        provider_ref: String,
    },

    /// The provider does not support resuming sessions.
    #[error("provider '{provider_ref}' does not support session resume")]
    ProviderResumeUnsupported {
        /// The provider reference that lacks resume support.
        provider_ref: String,
    },

    /// An internal error that should not occur in normal operation.
    #[error("internal error: {0}")]
    Internal(String),
}

pub type ForgeResult<T> = Result<T, ForgeError>;

lib.rs

Read declaration text · 35 declaration entries

pub mod brew;

pub mod brew_builder;

pub mod brew_resolver;

pub mod config;

pub mod error;

pub mod message;

pub mod model;

pub mod output;

pub mod provider;

pub mod provider_runtime;

pub mod replay;

pub mod routing;

pub mod schema;

pub mod telemetry;

pub mod tool;

pub mod topology;

pub mod types;

pub mod prelude;

pub use crate::brew::{
        Brew, BrewEdge, BrewEdgeKind, BrewId, BrewNode, BrewNodeKind, BrewVersion, JoinMode, NodeId,
    };

pub use crate::brew_builder::BrewBuilder;

pub use crate::brew_resolver::{
        BrewEnvironment, BrewResolutionError, BrewResolutionErrorKind, ResolvedBrewPlan,
        ResolvedNode, ResolvedNodeKind,
    };

pub use crate::config::{EmbedOptions, GenerateOptions};

pub use crate::error::{ForgeError, ForgeResult};

pub use crate::message::{MessagePart, ModelMessage, Role};

pub use crate::model::LanguageModel;

pub use crate::output::{FinishReason, GenerateResult, StreamChunk, Usage};

pub use crate::provider::{ProviderRef, ProviderRegistry};

pub use crate::provider_runtime::{
        ProviderNegotiationRequest, ProviderNegotiationResult, ProviderRuntimeCapabilities,
        ProviderSessionEvent, ProviderSessionState, ProviderUsageSummary, RuntimeCapability,
    };

pub use crate::replay::{
        legacy_accept_from_env, ReplayConfig, ReplayError, ReplayValidator, DEFAULT_CLOCK_SKEW,
        DEFAULT_NONCE_CACHE_SIZE,
    };

pub use crate::routing::{
        DefaultModelRouter, ExecutionTopology, ModelRouter, ResolvedRoute, RoutingContext, TaskMode,
    };

pub use crate::schema::JsonSchema;

pub use crate::telemetry::{ForgeEvent, ForgeSpan, TelemetryEmitter};

pub use crate::tool::{ToolApproval, ToolCall, ToolDefinition, ToolResult, ToolTier};

pub use crate::topology::{
        CostPreference, LatencyPreference, ModelSlot, ModelTopology, TopologyBuilder,
    };

pub use crate::types::{AgentDid, Timestamp};

message.rs

Read declaration text · 17 declaration entries

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Role {
    /// System instructions that configure agent behavior.
    System,
    /// User-provided input.
    User,
    /// Model-generated output.
    Assistant,
    /// Tool execution results.
    Tool,
}

pub fn as_str(&self) -> &'static str;

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum MessagePart {
    /// Plain text content.
    Text {
        /// The text content.
        text: String,
    },

    /// An image (base64 or URL).
    Image {
        /// Base64-encoded image data, or a URL.
        data: String,
        /// MIME type (e.g., "image/png").
        media_type: String,
    },

    /// A tool call request from the model.
    ToolCall {
        /// Unique identifier for this tool call.
        id: String,
        /// The tool name.
        name: String,
        /// JSON arguments for the tool.
        arguments: serde_json::Value,
    },

    /// A result from a tool execution.
    ToolResult {
        /// The tool call ID this result corresponds to.
        tool_call_id: String,
        /// The tool name.
        name: String,
        /// The result content (typically stringified).
        content: String,
        /// Whether the tool execution resulted in an error.
        is_error: bool,
    },
}

pub fn text(text: impl Into<String>) -> Self;

pub fn image(data: impl Into<String>, media_type: impl Into<String>) -> Self;

pub fn tool_call(
        id: impl Into<String>,
        name: impl Into<String>,
        arguments: serde_json::Value,
    ) -> Self;

pub fn tool_result(
        tool_call_id: impl Into<String>,
        name: impl Into<String>,
        content: impl Into<String>,
        is_error: bool,
    ) -> Self;

pub fn is_tool_call(&self) -> bool;

pub fn is_tool_result(&self) -> bool;

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ModelMessage {

}

pub fn new(role: Role, parts: Vec<MessagePart>) -> Self;

pub fn text(role: Role, text: impl Into<String>) -> Self;

pub fn role(&self) -> Role;

pub fn parts(&self) -> &[MessagePart];

pub fn parts_mut(&mut self) -> &mut Vec<MessagePart>;

pub fn tool_calls(&self) -> Vec<&MessagePart>;

pub fn text_content(&self) -> String;

model.rs

Read declaration text · 5 declaration entries

pub type StreamChunkResult = ForgeResult<StreamChunk>;

pub type ChunkStream<'a> = Pin<Box<dyn Stream<Item = StreamChunkResult> + Send + 'a>>;

pub fn buffered_into_chunks(chunks: Vec<StreamChunk>) -> ChunkStream<'static>;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelCapabilities {
/// Whether the model supports text generation.

pub text_generation: bool,
/// Whether the model supports structured output (JSON mode).

pub structured_output: bool,
/// Whether the model supports tool calling.

pub tool_calling: bool,
/// Whether the model supports vision (image input).

pub vision: bool,
/// Whether the model supports audio input/output.

pub audio: bool,
/// Whether the model supports embedding generation.

pub embedding: bool,
/// Maximum number of tokens in the context window.

pub max_context_tokens: u32,
/// Maximum number of tokens the model can generate in a single response.

pub max_output_tokens: u32
}

#[async_trait]
pub trait LanguageModel: Send + Sync {
    /// Returns the model identifier (e.g., "gpt-4o", "claude-sonnet-4-5-20250929").
    fn model_id(&self) -> &str;

    /// Returns the provider namespace (e.g., "openai", "anthropic").
    fn provider(&self) -> &str;

    /// Generates a complete response from the model.
    ///
    /// # Arguments
    ///
    /// * `messages` - The conversation history.
    /// * `tools` - Available tool definitions for this inference call.
    /// * `options` - Generation options (temperature, max_tokens, etc.).
    ///
    /// # Returns
    ///
    /// A `GenerateResult` containing the model's response, usage statistics,
    /// and finish reason.
    ///
    /// # Errors
    ///
    /// Returns `ForgeError` if the provider call fails, times out, or returns
    /// an invalid response.
    async fn generate(
        &self,
        messages: &[ModelMessage],
        tools: &[ToolDefinition],
        options: &GenerateOptions,
    ) -> ForgeResult<GenerateResult>;

    /// Streams a response from the model as chunks.
    ///
    /// **Deprecated.** Returns the full `Vec<StreamChunk>` after the upstream
    /// provider has yielded its terminal `Done`. Despite the name, this
    /// method does not deliver chunks incrementally — use
    /// [`stream_chunks`](Self::stream_chunks) for real per-token streaming.
    ///
    /// Will be removed in v0.3.0 once every in-tree provider has a native
    /// [`stream_chunks`] implementation.
    ///
    /// # Errors
    ///
    /// Returns `ForgeError` if the provider call fails.
    #[deprecated(
        since = "0.2.0",
        note = "use `stream_chunks` for real per-token streaming; this method buffers the entire response before returning. Will be removed in 0.3.0."
    )]
    async fn stream(
        &self,
        messages: &[ModelMessage],
        tools: &[ToolDefinition],
        options: &GenerateOptions,
    ) -> ForgeResult<Vec<StreamChunk>>;

    /// **Real per-token streaming.** Returns a stream that yields each chunk
    /// as soon as the upstream provider produces it on the wire.
    ///
    /// Per RFC 0001 (`rfcs/0001-stream-chunks.md`): each item is itself a
    /// `Result` so mid-stream errors don't lose already-received chunks. The
    /// outer `Result` covers connect-time failures (DNS, TLS, auth, malformed
    /// request); per-item `Err` covers mid-stream failures.
    ///
    /// # Default implementation (TRANSITIONAL)
    ///
    /// The default impl calls the (deprecated) [`stream`](Self::stream) method
    /// and wraps the resulting `Vec<StreamChunk>` via [`buffered_into_chunks`].
    /// **This is a transitional shim — it is NOT real streaming.** It exists
    /// only so existing providers compile against the new trait method while
    /// they are being rewritten one at a time for native streaming.
    ///
    /// **Providers MUST override this method with a native streaming
    /// implementation before 0.3.0.** Once every in-tree provider has a
    /// native `stream_chunks`, the default will be removed (the trait method
    /// becomes required) and `stream` will be deleted entirely.
    ///
    /// To find providers that still rely on the default impl, grep for
    /// `buffered_into_chunks` in their `stream_chunks` method body — that's
    /// the native-streaming migration checklist.
    ///
    /// # Arguments
    ///
    /// * `messages` - The conversation history.
    /// * `tools` - Available tool definitions for this inference call.
    /// * `options` - Generation options.
    ///
    /// # Returns
    ///
    /// A [`ChunkStream`] that yields [`StreamChunkResult`] items.
    ///
    /// # Errors
    ///
    /// - Outer `ForgeResult<...>` returns `Err` for connect-time failures.
    /// - Per-item `Err` for mid-stream failures (caller decides whether to
    ///   abort the stream).
    async fn stream_chunks(
        &self,
        messages: &[ModelMessage],
        tools: &[ToolDefinition],
        options: &GenerateOptions,
    ) -> ForgeResult<ChunkStream<'static>> ;

    /// Returns `true` if this model supports tool calling.
    fn supports_tool_calling(&self) -> bool ;

    /// Returns `true` if this model supports structured output (JSON mode).
    fn supports_structured_output(&self) -> bool ;

    /// Returns `true` if this model supports image input.
    fn supports_image_input(&self) -> bool ;

    /// Returns `true` if this model supports streaming.
    fn supports_streaming(&self) -> bool ;

    /// Returns the model's capabilities.
    ///
    /// The default implementation constructs a [`ModelCapabilities`] from the
    /// individual `supports_*` methods. Override this to provide accurate values
    /// for `max_context_tokens` and `max_output_tokens`.
    ///
    /// # ANVIL Spec Reference
    ///
    /// ANVIL Spec section 6.2 -- Model Capabilities.
    ///
    /// # Returns
    ///
    /// A [`ModelCapabilities`] describing what this model can do.
    fn capabilities(&self) -> ModelCapabilities ;
}

output.rs

Read declaration text · 23 declaration entries

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GenerateResult {
/// The model's response message.

pub message: ModelMessage,
/// Why generation stopped.

pub finish_reason: FinishReason,
/// Token usage statistics.

pub usage: Usage
}

pub fn text(&self) -> String;

pub fn has_tool_calls(&self) -> bool;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum FinishReason {
    /// The model produced a natural stop.
    Stop,
    /// The maximum token limit was reached.
    MaxTokens,
    /// The model requested tool calls.
    ToolCalls,
    /// A stop sequence was matched.
    StopSequence,
    /// A content filter blocked the output.
    ContentFilter,
    /// An error occurred during generation.
    Error,
}

pub fn is_complete(&self) -> bool;

pub fn is_tool_call(&self) -> bool;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct Usage {
/// Tokens consumed by the input prompt.

pub prompt_tokens: u64,
/// Tokens generated in the response.

pub completion_tokens: u64,
/// Total tokens (prompt + completion).

pub total_tokens: u64
}

pub fn zero() -> Self;

pub fn add(&self, other: &Usage) -> Usage;

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum StreamChunk {
    /// A text content delta.
    TextDelta {
        /// The text fragment.
        text: String,
    },

    /// A tool call delta (streaming tool arguments).
    ToolCallDelta {
        /// The tool call index (for parallel tool calls).
        index: u32,
        /// The tool call ID (may be empty until fully received).
        id: String,
        /// The tool name (may be empty until fully received).
        name: String,
        /// Partial JSON arguments.
        arguments_delta: String,
    },

    /// Signals the start of a tool call.
    ///
    /// Emitted when the model begins a tool invocation. The `id` uniquely
    /// identifies the tool call, and `name` is the tool being invoked.
    ToolCallStart {
        /// The tool call ID.
        id: String,
        /// The tool name being called.
        name: String,
    },

    /// Signals the end of a tool call.
    ///
    /// Emitted when a tool invocation completes. The `id` matches the
    /// corresponding `ToolCallStart`.
    ToolCallEnd {
        /// The tool call ID.
        id: String,
    },

    /// Metadata chunk with usage information.
    ///
    /// Emitted at any point during streaming to provide intermediate or
    /// final token usage statistics.
    Metadata {
        /// Token usage statistics.
        usage: Usage,
    },

    /// An error occurred during streaming.
    ///
    /// The stream may continue after an error or terminate, depending on
    /// the provider implementation.
    Error {
        /// The error message.
        message: String,
    },

    /// The stream has finished.
    Done {
        /// Why generation stopped.
        finish_reason: FinishReason,
        /// Final usage statistics.
        usage: Usage,
    },
}

pub fn text_delta(text: impl Into<String>) -> Self;

pub fn done(finish_reason: FinishReason, usage: Usage) -> Self;

pub fn tool_call_start(id: impl Into<String>, name: impl Into<String>) -> Self;

pub fn tool_call_end(id: impl Into<String>) -> Self;

pub fn metadata(usage: Usage) -> Self;

pub fn error(message: impl Into<String>) -> Self;

pub fn is_text_delta(&self) -> bool;

pub fn is_done(&self) -> bool;

pub fn is_tool_call_start(&self) -> bool;

pub fn is_tool_call_end(&self) -> bool;

pub fn is_metadata(&self) -> bool;

pub fn is_error(&self) -> bool;

pub fn as_text(&self) -> Option<&str>;

provider.rs

Read declaration text · 17 declaration entries

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct ProviderRef {

}

pub fn parse(input: &str) -> ForgeResult<Self>;

pub fn namespace(&self) -> &str;

pub fn model(&self) -> &str;

pub fn as_str(&self) -> &str;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProviderMetadata {
/// Human-readable name.

pub name: String,
/// Provider namespace (e.g., "openai").

pub namespace: String,
/// Whether the provider supports tool calling.

pub supports_tool_calling: bool,
/// Whether the provider supports structured output.

pub supports_structured_output: bool,
/// Whether the provider supports streaming.

pub supports_streaming: bool,
/// Whether the provider supports image input.

pub supports_image_input: bool,
/// Runtime capabilities advertised by the provider (coding-provider negotiation).

#[serde(default)]
pub runtime_capabilities: ProviderRuntimeCapabilities
}

pub struct ProviderRegistry {

}

pub fn new() -> Self;

pub fn register(
        &mut self,
        provider_ref: &str,
        model: Arc<dyn LanguageModel>,
    ) -> ForgeResult<()>;

pub fn register_with_runtime(
        &mut self,
        provider_ref: &str,
        model: Arc<dyn LanguageModel>,
        runtime: ProviderRuntimeCapabilities,
    ) -> ForgeResult<()>;

pub fn negotiate(
        &self,
        request: &ProviderNegotiationRequest,
    ) -> ForgeResult<ProviderNegotiationResult>;

pub fn get(&self, provider_ref: &str) -> Option<Arc<dyn LanguageModel>>;

pub fn require(&self, provider_ref: &str) -> ForgeResult<Arc<dyn LanguageModel>>;

pub fn metadata(&self, provider_ref: &str) -> Option<&ProviderMetadata>;

pub fn list(&self) -> Vec<&str>;

pub fn len(&self) -> usize;

pub fn is_empty(&self) -> bool;

provider_runtime.rs

Read declaration text · 10 declaration entries

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub enum RuntimeCapability {
    ToolCalls,
    DelegatedAgents,
    TerminalSession,
    StructuredPatch,
    Attachments,
    Interrupts,
    ResumeSession,
    ApprovalCheckpoints,
    UsageStreaming,
    TranscriptExport,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct ProviderRuntimeCapabilities {
/// Whether the provider satisfies the mandatory Forge coding baseline.

pub baseline_contract: bool,
/// Explicit advanced capabilities advertised by the provider.

pub capabilities: BTreeSet<RuntimeCapability>
}

pub fn baseline() -> Self;

pub fn with_capability(mut self, capability: RuntimeCapability) -> Self;

pub fn supports(&self, capability: &RuntimeCapability) -> bool;

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProviderNegotiationRequest {
pub provider_ref: String,
pub require_baseline_contract: bool,
pub required_capabilities: Vec<RuntimeCapability>
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProviderNegotiationResult {
pub provider_ref: String,
pub baseline_contract: bool,
pub negotiated_capabilities: Vec<RuntimeCapability>
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ProviderSessionState {
    Created,
    Ready,
    Running,
    Interrupted,
    Completed,
    Cancelled,
    Failed,
    Expired,
    Closed,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct ProviderUsageSummary {
pub input_tokens: u64,
pub output_tokens: u64,
pub total_tokens: u64
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProviderSessionEvent {
pub session_id: String,
pub state: ProviderSessionState,
pub message: Option<String>,
pub usage: Option<ProviderUsageSummary>
}

replay.rs

Read declaration text · 14 declaration entries

pub const DEFAULT_CLOCK_SKEW: Duration;

pub const DEFAULT_NONCE_CACHE_SIZE: usize;

#[derive(Debug, Clone)]
pub struct ReplayConfig {
/// Maximum allowed clock skew between sender and receiver, applied in

/// both directions. A timestamp that is more than this far in the past

/// or future (relative to the receiver's wall clock) is rejected.

pub max_clock_skew: Duration,
/// Maximum number of nonces to remember. When full, the least-recently-used

/// nonce is evicted to make room for a new entry. Must be non-zero.

pub nonce_cache_size: usize,
/// If `true`, messages lacking a nonce/timestamp (legacy wire format)

/// are accepted with a `WARN` log line. If `false` (default), legacy

/// messages are rejected with [`ReplayError::LegacyMessageFormat`].

///

/// This flag is also controllable via the `FORGE_ACCEPT_LEGACY_MESSAGES`

/// environment variable; see [`legacy_accept_from_env`].

pub accept_legacy: bool
}

pub fn with_max_clock_skew(mut self, skew: Duration) -> Self;

pub fn with_nonce_cache_size(mut self, size: usize) -> Self;

pub fn with_accept_legacy(mut self, accept: bool) -> Self;

pub fn legacy_accept_from_env() -> bool;

#[derive(Debug, Error, PartialEq, Eq)]
pub enum ReplayError {
    /// The envelope timestamp is outside the accepted clock-skew window.
    #[error(
        "replay protection rejected message: timestamp {timestamp_ms}ms is outside the \
         ±{max_skew_ms}ms clock-skew window (now={now_ms}ms)"
    )]
    TimestampExpired {
        /// The timestamp carried by the message, in milliseconds since epoch.
        timestamp_ms: i64,
        /// The receiver's current wall-clock time, in milliseconds since epoch.
        now_ms: i64,
        /// The configured maximum skew, in milliseconds.
        max_skew_ms: i64,
    },

    /// The envelope's nonce was already seen within the validity window.
    #[error(
        "replay protection rejected message: nonce {nonce_hex} has already been accepted \
         within the clock-skew window"
    )]
    NonceReplay {
        /// Hex-encoded nonce, included for operator diagnostics.
        nonce_hex: String,
    },

    /// The envelope is missing nonce and/or timestamp and legacy acceptance
    /// is disabled.
    #[error(
        "replay protection rejected message: legacy wire format (no nonce/timestamp); \
         set FORGE_ACCEPT_LEGACY_MESSAGES=true to opt into legacy acceptance"
    )]
    LegacyMessageFormat,

    /// The validator's internal cache lock was poisoned. This indicates that
    /// another thread panicked while holding the lock; callers should treat
    /// this as an unrecoverable condition for that validator instance.
    #[error("replay validator internal lock poisoned (a prior thread panicked)")]
    LockPoisoned,
}

pub struct ReplayValidator {

}

pub fn new(config: ReplayConfig) -> Self;

pub fn config(&self) -> &ReplayConfig;

pub fn validate(&self, timestamp_ms: i64, nonce: &[u8; 16]) -> Result<(), ReplayError>;

pub fn accept_legacy(&self, context: &str) -> Result<(), ReplayError>;

#[doc(hidden)]
pub fn nonce_cache_len(&self) -> usize;

routing.rs

Read declaration text · 7 declaration entries

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TaskMode {
    /// Strategic reasoning, goal decomposition, plan generation.
    Planning,
    /// Direct task execution (code generation, content creation, data processing).
    Execution,
    /// Reviewing, grading, or verifying outputs from prior steps.
    Evaluation,
    /// Condensing, abstracting, or reformatting prior outputs.
    Summarization,
}

pub fn as_role_name(&self) -> &'static str;

#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ExecutionTopology {
    /// A single sequential call.
    #[default]
    Sequential,
    /// One of N parallel calls that will be aggregated.
    ParallelFanOut,
    /// The aggregation call after a fan-out completes.
    FanIn,
    /// A call within a retry/fallback chain.
    Retry,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct RoutingContext {
/// The domain classification for this call.

///

/// Examples: "code", "math", "creative", "analysis", "general".

/// When `None`, the router does not attempt domain-based matching.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub domain: Option<String>,
/// The task mode for this call.

///

/// When `None`, the router does not attempt task-mode-based matching.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub task_mode: Option<TaskMode>,
/// The execution topology for this call.

///

/// Describes how this inference call relates to other concurrent calls.

/// When `None`, defaults to `Sequential`.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub execution_topology: Option<ExecutionTopology>,
/// Tool capabilities required for the model selected by this route.

///

/// Specific tool names that must be callable. The router may use this

/// information to select a model that supports the required tools.

#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub tool_requirements: Vec<String>,
/// Explicit role override.

///

/// When set, the router returns the slot with this role name without

/// applying strategy logic. Analogous to `tier_override` in the

/// Aut0 Router.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub role_override: Option<String>
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResolvedRoute {
/// The role name of the selected slot.

pub slot_role: String,
/// The specific `ProviderRef` to use (primary or one of the fallbacks).

pub provider: ProviderRef,
/// The model capabilities of the selected provider.

pub model_capabilities: ModelCapabilities,
/// Whether a fallback model was selected instead of the primary.

pub fallback_used: bool
}

pub trait ModelRouter: Send + Sync {
    /// Returns the name of this routing strategy (for telemetry and debugging).
    fn name(&self) -> &str;

    /// Selects a slot from the topology.
    ///
    /// The router must return a `ResolvedRoute` that references a slot present
    /// in the topology. Returning a role name that does not exist in the
    /// topology is a routing error.
    ///
    /// # Arguments
    ///
    /// * `context` - The routing context describing the current task.
    /// * `topology` - The model topology to select from.
    ///
    /// # Returns
    ///
    /// A `ResolvedRoute` identifying the selected slot and provider.
    ///
    /// # Errors
    ///
    /// Returns `ForgeError` if routing fails (e.g., requested role not found).
    fn route(
        &self,
        context: &RoutingContext,
        topology: &ModelTopology,
    ) -> ForgeResult<ResolvedRoute>;
}

pub struct DefaultModelRouter;

schema.rs

Read declaration text · 20 declaration entries

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct JsonSchema {
/// The schema type.

#[serde(rename = "type")]
pub schema_type: SchemaType,
/// Human-readable description of this schema element.

#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
/// Properties (for object type).

#[serde(skip_serializing_if = "Option::is_none")]
pub properties: Option<BTreeMap<String, JsonSchema>>,
/// Required property names (for object type).

#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "required")]
pub required_fields: Option<Vec<String>>,
/// Whether additional properties are allowed (for object type).

#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "additionalProperties")]
pub additional_properties: Option<bool>,
/// Items schema (for array type).

#[serde(skip_serializing_if = "Option::is_none")]
pub items: Option<Box<JsonSchema>>,
/// Allowed string values.

#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "enum")]
pub enum_values: Option<Vec<serde_json::Value>>,
/// Minimum numeric value.

#[serde(skip_serializing_if = "Option::is_none")]
pub minimum: Option<f64>,
/// Maximum numeric value.

#[serde(skip_serializing_if = "Option::is_none")]
pub maximum: Option<f64>,
/// Minimum string length.

#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "minLength")]
pub min_length: Option<u64>,
/// Maximum string length.

#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "maxLength")]
pub max_length: Option<u64>
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum SchemaType {
    /// A JSON string.
    String,
    /// A JSON number (floating point).
    Number,
    /// A JSON integer.
    Integer,
    /// A JSON boolean.
    Boolean,
    /// A JSON array.
    Array,
    /// A JSON object.
    Object,
    /// A JSON null.
    Null,
}

pub fn string() -> Self;

pub fn number() -> Self;

pub fn integer() -> Self;

pub fn boolean() -> Self;

pub fn array() -> Self;

pub fn object() -> Self;

pub fn null() -> Self;

pub fn description(mut self, desc: impl Into<String>) -> Self;

pub fn property(mut self, name: impl Into<String>, schema: JsonSchema) -> Self;

pub fn required(mut self, name: impl Into<String>) -> Self;

pub fn items_schema(mut self, schema: JsonSchema) -> Self;

pub fn enum_values(mut self, values: Vec<serde_json::Value>) -> Self;

pub fn minimum(mut self, min: impl Into<f64>) -> Self;

pub fn maximum(mut self, max: impl Into<f64>) -> Self;

pub fn min_length(mut self, len: u64) -> Self;

pub fn max_length(mut self, len: u64) -> Self;

pub fn additional_properties(mut self, allowed: bool) -> Self;

pub fn validate(&self, value: &serde_json::Value) -> ForgeResult<()>;

telemetry.rs

Read declaration text · 21 declaration entries

pub const SPAN_GENERATE: &str;

pub const SPAN_TOOL_INVOKE: &str;

pub const SPAN_TASK_DELEGATE: &str;

pub const SPAN_TASK_EXECUTE: &str;

pub const SPAN_SESSION: &str;

pub const SPAN_LIFECYCLE: &str;

pub const SPAN_MESSAGE_SEND: &str;

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AuditEventKind {
    /// An agent was instantiated with identity and capabilities.
    AgentInstantiated,
    /// A capability check was performed against an Arsenal ACT.
    CapabilityCheck,
    /// A tool was invoked by the agent.
    ToolInvocation,
    /// A network access operation occurred (HTTP, WebSocket, etc.).
    NetworkAccess,
    /// An inter-agent message was sent or received.
    InterAgentMessage,
    /// A lifecycle state transition occurred.
    LifecycleTransition,
    /// A resource quota event was triggered (usage approaching or exceeding limits).
    ResourceQuota,
    /// An agent joined a session.
    SessionJoin,
    /// An agent left a session.
    SessionLeave,
    /// A task was delegated to a sub-agent.
    TaskDelegation,
    /// An interrupt signal was received and processed.
    Interrupt,
    /// A write to the agent's context or memory occurred.
    ContextWrite,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ForgeSpan {
/// The span name (e.g., "forge.agent.generate", "forge.tool.execute").

pub name: String,
/// Span start time.

pub start_time: Timestamp,
/// Span end time (set when span completes).

pub end_time: Option<Timestamp>,
/// Key-value attributes.

pub attributes: HashMap<String, SpanAttribute>,
/// Span status.

pub status: SpanStatus,
/// Parent span ID for distributed tracing.

pub parent_id: Option<String>,
/// This span's unique ID.

pub span_id: String
}

pub fn new(name: impl Into<String>) -> Self;

pub fn set_attribute(&mut self, key: impl Into<String>, value: impl Into<SpanAttribute>);

pub fn end(&mut self);

pub fn end_with_error(&mut self, message: impl Into<String>);

pub fn with_parent(mut self, parent_id: impl Into<String>) -> Self;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ForgeEvent {
/// The event name.

pub name: String,
/// When the event occurred.

pub timestamp: Timestamp,
/// Key-value attributes.

pub attributes: HashMap<String, SpanAttribute>
}

pub fn new(name: impl Into<String>) -> Self;

pub fn set_attribute(&mut self, key: impl Into<String>, value: impl Into<SpanAttribute>);

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "code", rename_all = "snake_case")]
pub enum SpanStatus {
    /// Status not set (default).
    Unset,
    /// Operation completed successfully.
    Ok,
    /// Operation failed with an error.
    Error {
        /// Error message.
        message: String,
    },
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum SpanAttribute {
    /// A string value.
    String(String),
    /// An integer value.
    Int(i64),
    /// A floating-point value.
    Float(f64),
    /// A boolean value.
    Bool(bool),
}

pub trait TelemetryEmitter: Send + Sync {
    /// Emits a completed span.
    fn emit_span(&self, span: &ForgeSpan);
    /// Emits an event.
    fn emit_event(&self, event: &ForgeEvent);
}

pub struct NoopEmitter;

tool.rs

Read declaration text · 17 declaration entries

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ToolTier {
    /// Tier 1 -- Platform tools provided by the runtime.
    ///
    /// Always available, no authorization needed. Examples: clock, crypto, logging.
    #[serde(rename = "platform")]
    Platform,

    /// Tier 2 -- External tools that execute outside the sandbox.
    ///
    /// Require Arsenal ACT authorization. Examples: web browsing, database, APIs.
    #[serde(rename = "external", alias = "host")]
    External,

    /// Tier 3 -- Embedded tools compiled into the agent WASM module.
    ///
    /// Scoped to the module. Examples: data parsing, computation, pure functions.
    #[serde(rename = "embedded")]
    Embedded,
}

pub fn requires_authorization(&self) -> bool;

pub fn as_str(&self) -> &'static str;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolDefinition {

}

pub fn builder(name: impl Into<String>) -> ToolDefinitionBuilder;

pub fn name(&self) -> &str;

pub fn description(&self) -> &str;

pub fn parameters(&self) -> &JsonSchema;

pub fn tier(&self) -> ToolTier;

pub struct ToolDefinitionBuilder {

}

pub fn description(mut self, desc: impl Into<String>) -> Self;

pub fn parameters(mut self, schema: JsonSchema) -> Self;

pub fn tier(mut self, tier: ToolTier) -> Self;

pub fn build(self) -> ToolDefinition;

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ToolCall {
/// Unique identifier for this call (used to match with results).

pub id: String,
/// The tool name being invoked.

pub name: String,
/// JSON arguments for the tool.

pub arguments: serde_json::Value
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ToolResult {
/// The tool call ID this result corresponds to.

pub tool_call_id: String,
/// The tool name.

pub name: String,
/// The result content (stringified).

pub content: String,
/// Whether the tool execution resulted in an error.

pub is_error: bool
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ToolApproval {
    /// The tool call is approved as-is.
    Approve,
    /// The tool call is denied with a reason.
    Deny {
        /// Why the tool call was denied.
        reason: String,
    },
    /// The tool call is approved but with modified arguments.
    Modify {
        /// The modified arguments to use instead.
        arguments: serde_json::Value,
    },
}

topology.rs

Read declaration text · 24 declaration entries

pub const DEFAULT_ROLE: &str;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum CostPreference {
    /// Prefer the cheapest model that satisfies requirements.
    Minimize,
    /// Accept moderate cost for better quality.
    Balanced,
    /// Ignore cost; select the best model regardless of price.
    Ignore,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum LatencyPreference {
    /// Prefer the lowest-latency model.
    Low,
    /// Accept moderate latency for better quality.
    Balanced,
    /// Ignore latency; select the best model regardless of response time.
    Tolerant,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelSlot {
/// The role name for this slot (e.g., "planner", "coder", "default").

///

/// Role names are freeform strings. The reserved name "default" designates

/// the slot used when no routing decision applies. Every topology must

/// have exactly one slot with role "default".

pub role: String,
/// Primary model for this slot.

pub primary: ProviderRef,
/// Ordered fallback models. Tried in sequence when the primary is

/// unavailable or fails negotiation.

#[serde(default)]
pub fallbacks: Vec<ProviderRef>,
/// Runtime capabilities required for this slot. The router validates

/// that the selected model satisfies these before returning a route.

#[serde(default)]
pub required_capabilities: Vec<RuntimeCapability>,
/// Optional cost preference for the router.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub cost_preference: Option<CostPreference>,
/// Optional latency preference for the router.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub latency_preference: Option<LatencyPreference>,
/// Optional Arsenal scope narrowing applied when this slot is selected.

/// If set, the agent's ACT is intersected with these scopes before

/// the model call. The intersection can only narrow, never widen.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub arsenal_scope_narrowing: Option<Vec<String>>
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelTopology {

}

pub fn single(provider_ref: ProviderRef) -> Self;

pub fn builder() -> TopologyBuilder;

pub fn name(&self) -> &str;

pub fn default_role(&self) -> &str;

pub fn default_slot(&self) -> &ModelSlot;

pub fn slot_for_role(&self, role: &str) -> &ModelSlot;

pub fn slots(&self) -> &BTreeMap<String, ModelSlot>;

pub fn all_provider_refs(&self) -> Vec<&ProviderRef>;

pub fn has_role(&self, role: &str) -> bool;

pub fn slot_count(&self) -> usize;

#[derive(Debug)]
pub struct TopologyBuilder {

}

pub fn name(mut self, name: impl Into<String>) -> Self;

pub fn slot(mut self, role: impl Into<String>, primary: ProviderRef) -> Self;

pub fn with_fallback(mut self, role: impl AsRef<str>, fallback: ProviderRef) -> Self;

pub fn with_required_capability(
        mut self,
        role: impl AsRef<str>,
        cap: RuntimeCapability,
    ) -> Self;

pub fn with_cost_preference(mut self, role: impl AsRef<str>, pref: CostPreference) -> Self;

pub fn with_latency_preference(
        mut self,
        role: impl AsRef<str>,
        pref: LatencyPreference,
    ) -> Self;

pub fn with_scope_narrowing(mut self, role: impl AsRef<str>, scopes: Vec<String>) -> Self;

pub fn build(self) -> ForgeResult<ModelTopology>;

types.rs

Read declaration text · 10 declaration entries

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct AgentDid(String);

pub fn new(did: &str) -> Option<Self>;

pub fn from_trusted(did: String) -> Self;

pub fn as_str(&self) -> &str;

pub fn into_string(self) -> String;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Timestamp(chrono::DateTime<chrono::Utc>);

pub fn now() -> Self;

pub fn from_iso8601(s: &str) -> Option<Self>;

pub fn to_iso8601(self) -> String;

pub fn as_chrono(&self) -> &chrono::DateTime<chrono::Utc>;

Continue

On this page