{
  "name": "forge-agent",
  "language": "rust",
  "version": "0.2.0",
  "description": "ANVIL-compliant agent execution loop, workflows, and multi-agent orchestration for the Forge SDK",
  "manifest": "forge-rs/crates/forge-agent/Cargo.toml",
  "manifestSha256": "c88f2e967d0141dde0c1c61e04b364dc16f467f63421c5625c83b1fb7923aac3",
  "status": "source-reference",
  "registryPublicationVerified": false,
  "route": "/libraries/rust/forge-agent",
  "features": {},
  "files": [
    {
      "path": "forge-rs/crates/forge-agent/src/agent.rs",
      "sha256": "8c7c889ebea73ce8d66dc6dea8423514b4491404b1b301fef701f21b44290503",
      "artifactSha256": "42875006811f206660b912ecc8ab556155731249acd328abacdab942c49e1b8d",
      "url": "/reference/source/forge-rs/crates/forge-agent/src/agent.rs.txt",
      "declarations": [
        {
          "name": "::BoundaryContract",
          "line": 54,
          "signature": "#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]\npub struct BoundaryContract {\n\n}",
          "documentation": "The boundary contract enforced before any coding-provider session begins.\n\nThis is intentionally narrow for the first provider-security slice. It\ncovers the privilege checks the runtime must enforce before calling an\nexternal coding provider: network execution, delegated execution, and the\nlist of provider namespaces the agent may use."
        },
        {
          "name": "::BoundaryContract::new",
          "line": 62,
          "signature": "pub fn new() -> Self;",
          "documentation": "Creates an empty fail-closed boundary contract."
        },
        {
          "name": "::BoundaryContract::with_network_access",
          "line": 67,
          "signature": "pub fn with_network_access(mut self) -> Self;",
          "documentation": "Grants outbound network authority for coding-provider execution."
        },
        {
          "name": "::BoundaryContract::with_delegation_access",
          "line": 73,
          "signature": "pub fn with_delegation_access(mut self) -> Self;",
          "documentation": "Grants delegated execution authority for providers that may create sub-runs."
        },
        {
          "name": "::BoundaryContract::allow_provider_namespace",
          "line": 79,
          "signature": "pub fn allow_provider_namespace(mut self, namespace: impl Into<String>) -> Self;",
          "documentation": "Allows provider execution for a specific provider namespace."
        },
        {
          "name": "::ProviderIdentityVerification",
          "line": 99,
          "signature": "#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ProviderIdentityVerification {\n/// The DID that was verified.\n\npub did: String,\n/// Whether the DID document's signature validated successfully.\n\npub signature_valid: bool,\n/// Whether the DID's lineage chain validated successfully.\n\npub lineage_valid: bool,\n/// Forge-owned conformance level derived from the upstream verification pipeline.\n\npub conformance_level: u8\n}",
          "documentation": "Result of verifying an agent DID through the execution authority backend."
        },
        {
          "name": "::ProviderAuthorityVerifier",
          "line": 112,
          "signature": "#[async_trait]\npub trait ProviderAuthorityVerifier: Send + Sync {\n    /// Verifies the given DID and returns the normalized authority result.\n    async fn verify_did(&self, did: &str) -> Result<ProviderIdentityVerification, ForgeAgentError>;\n}",
          "documentation": "Stable verification contract used by provider execution preflight."
        },
        {
          "name": "::CodingProviderPreflight",
          "line": 119,
          "signature": "#[derive(Debug, Clone, PartialEq, Eq)]\npub struct CodingProviderPreflight {\n/// The negotiated provider contract.\n\npub negotiation: ProviderNegotiationResult,\n/// The DID that passed execution-authority verification.\n\npub verified_did: String,\n/// The provider scopes that were validated against the active ACT.\n\npub required_scopes: Vec<String>\n}",
          "documentation": "Preflight result for an authorized coding-provider execution."
        },
        {
          "name": "::AegisProviderAuthorityVerifier",
          "line": 129,
          "signature": "#[cfg(not(target_arch = \"wasm32\"))]\npub struct AegisProviderAuthorityVerifier {\n\n}",
          "documentation": ""
        },
        {
          "name": "::AegisProviderAuthorityVerifier::new",
          "line": 136,
          "signature": "#[cfg(not(target_arch = \"wasm32\"))]\npub fn new(\n        registry: std::sync::Arc<aegis_core::PluginRegistry>,\n        config: aegis_core::VerificationConfig,\n    ) -> Self;",
          "documentation": "Creates a production verifier backed by the AEGIS verification pipeline."
        },
        {
          "name": "::AegisProviderAuthorityVerifier::from_pipeline",
          "line": 146,
          "signature": "#[cfg(not(target_arch = \"wasm32\"))]\npub fn from_pipeline(pipeline: aegis_verify::VerificationPipeline) -> Self;",
          "documentation": "Wraps an existing AEGIS verification pipeline."
        },
        {
          "name": "::AgentConfig",
          "line": 206,
          "signature": "#[derive(Clone, Serialize, Deserialize)]\npub struct AgentConfig {\n\n}",
          "documentation": "Configuration for creating an agent.\n\n`AgentConfig` captures the immutable configuration that defines an agent's\nidentity, model, tools, behavior limits, and system prompt. Once an agent\nis created from a config, the config is not modified.\n\n# ANVIL Spec SS7.1\n\nThe agent execution loop is parameterized by a config that includes the\nmodel reference, available tools, maximum steps, and system prompt.\n\n# Examples\n\n```\nuse forge_agent::agent::AgentConfig;\nuse forge_core::tool::ToolDefinition;\nuse forge_core::tool::ToolTier;\n\nlet tool = ToolDefinition::builder(\"search\")\n    .description(\"Search the web\")\n    .tier(ToolTier::External)\n    .build();\n\nlet config = AgentConfig::new(\"researcher\", \"anthropic:claude-sonnet-4-5-20250929\")\n    .with_system_prompt(\"You are a research assistant.\")\n    .with_max_steps(15)\n    .with_tool(tool);\n\nassert_eq!(config.name(), \"researcher\");\nassert_eq!(config.tools().len(), 1);\n```"
        },
        {
          "name": "::AgentConfig::new",
          "line": 314,
          "signature": "pub fn new(name: impl Into<String>, model: impl Into<String>) -> Self;",
          "documentation": "Creates a new `AgentConfig` with the given name and model reference.\n\n# Arguments\n\n* `name` - A human-readable name for the agent (e.g., \"data-analyst\").\n* `model` - A provider reference string (e.g., \"openai:gpt-4o\").\n\n# Returns\n\nAn `AgentConfig` with default settings: no tools, max_steps=10, no system prompt.\n\n# Panics\n\nThis function does not panic. If the model reference is invalid, the error\nwill surface at agent creation time when the provider is resolved.\n\n# Examples\n\n```\nuse forge_agent::agent::AgentConfig;\n\nlet config = AgentConfig::new(\"bot\", \"openai:gpt-4o\");\nassert_eq!(config.name(), \"bot\");\nassert_eq!(config.max_steps(), 10);\nassert!(config.tools().is_empty());\nassert!(config.system_prompt().is_none());\n```"
        },
        {
          "name": "::AgentConfig::with_system_prompt",
          "line": 391,
          "signature": "pub fn with_system_prompt(mut self, prompt: impl Into<String>) -> Self;",
          "documentation": "Sets the system prompt for this agent.\n\nThe system prompt is prepended as a `System` role message to every\nLLM call made by the agent.\n\n# Arguments\n\n* `prompt` - The system prompt text.\n\n# Returns\n\nThe modified `AgentConfig` (builder pattern).\n\n# Examples\n\n```\nuse forge_agent::agent::AgentConfig;\n\nlet config = AgentConfig::new(\"bot\", \"openai:gpt-4o\")\n    .with_system_prompt(\"You are a helpful assistant.\");\nassert_eq!(config.system_prompt(), Some(\"You are a helpful assistant.\"));\n```"
        },
        {
          "name": "::AgentConfig::with_max_steps",
          "line": 415,
          "signature": "pub fn with_max_steps(mut self, max: u32) -> Self;",
          "documentation": "Sets the maximum number of tool loop steps.\n\n# Arguments\n\n* `max` - The maximum step count. Must be at least 1.\n\n# Returns\n\nThe modified `AgentConfig` (builder pattern).\n\n# Examples\n\n```\nuse forge_agent::agent::AgentConfig;\n\nlet config = AgentConfig::new(\"bot\", \"openai:gpt-4o\")\n    .with_max_steps(50);\nassert_eq!(config.max_steps(), 50);\n```"
        },
        {
          "name": "::AgentConfig::with_tool",
          "line": 441,
          "signature": "pub fn with_tool(mut self, tool: ToolDefinition) -> Self;",
          "documentation": "Adds a tool definition to this agent's available tools.\n\n# Arguments\n\n* `tool` - The tool definition to add.\n\n# Returns\n\nThe modified `AgentConfig` (builder pattern).\n\n# Examples\n\n```\nuse forge_agent::agent::AgentConfig;\nuse forge_core::tool::{ToolDefinition, ToolTier};\n\nlet config = AgentConfig::new(\"bot\", \"openai:gpt-4o\")\n    .with_tool(ToolDefinition::builder(\"clock\").tier(ToolTier::Platform).build())\n    .with_tool(ToolDefinition::builder(\"search\").tier(ToolTier::External).build());\nassert_eq!(config.tools().len(), 2);\n```"
        },
        {
          "name": "::AgentConfig::with_tools",
          "line": 455,
          "signature": "pub fn with_tools(mut self, tools: Vec<ToolDefinition>) -> Self;",
          "documentation": "Sets all tool definitions at once, replacing any previously added tools.\n\n# Arguments\n\n* `tools` - The complete list of tool definitions.\n\n# Returns\n\nThe modified `AgentConfig` (builder pattern)."
        },
        {
          "name": "::AgentConfig::with_tool_registry",
          "line": 501,
          "signature": "pub fn with_tool_registry(mut self, registry: &forge_tool::registry::ToolRegistry) -> Self;",
          "documentation": "Imports every tool definition from a [`ToolRegistry`] into this config.\n\nIn Forge's tool model, a tool needs to be present in two places to work\nend-to-end: the [`ToolRegistry`] (so the loop can EXECUTE the tool) and\n`AgentConfig.tools` (so the model SEES it in its system prompt). Forgetting\nthe second registration is a silent foot-gun -- the executor exists but\nthe model never knows the tool is available, so the tool just does\nnothing.\n\n`with_tool_registry` removes that hazard. Pass a built registry, get every\ndefinition appended to the agent config in one call:\n\n```\nuse forge_agent::agent::AgentConfig;\nuse forge_tool::registry::ToolRegistry;\nuse forge_tool::execution::FnToolExecutor;\nuse forge_core::tool::{ToolDefinition, ToolTier, ToolCall, ToolResult};\nuse std::sync::Arc;\n\nlet mut registry = ToolRegistry::new();\nlet def = ToolDefinition::builder(\"clock\").tier(ToolTier::Platform).build();\nlet exec = Arc::new(FnToolExecutor::new(\"clock\", |call: &ToolCall| {\n    Ok(ToolResult {\n        tool_call_id: call.id.clone(),\n        name: call.name.clone(),\n        content: \"2026-04-29T00:00:00Z\".to_string(),\n        is_error: false,\n    })\n}));\nregistry.register(def, exec).unwrap();\n\nlet config = AgentConfig::new(\"bot\", \"openai:gpt-4o\")\n    .with_tool_registry(&registry);\n\nassert_eq!(config.tools().len(), 1);\nassert_eq!(config.tools()[0].name(), \"clock\");\n```\n\nDefinitions already on the config are preserved -- this method *appends*.\nTo replace, call [`with_tools`](Self::with_tools) with an empty Vec first\nor build a fresh `AgentConfig`."
        },
        {
          "name": "::AgentConfig::with_boundary_contract",
          "line": 507,
          "signature": "pub fn with_boundary_contract(mut self, boundary_contract: BoundaryContract) -> Self;",
          "documentation": "Sets the provider execution boundary contract for coding-provider sessions."
        },
        {
          "name": "::AgentConfig::with_identity",
          "line": 544,
          "signature": "pub fn with_identity(mut self, identity: ForgeAgentIdentity) -> Self;",
          "documentation": "Sets the OAS identity for this agent.\n\nWhen an identity is configured, the agent carries a `did:oas` identifier\nwith an Ed25519 keypair and lineage proof chain. This enables:\n- Audit trail entries signed by the agent's key.\n- Identity-aware telemetry spans.\n- Arsenal ACT authorization checks for Tier 2 (Host) tools.\n\nSee ANVIL Spec SS11.1 -- OAS Identity Binding.\n\n# Arguments\n\n* `identity` - The agent's `ForgeAgentIdentity`.\n\n# Returns\n\nThe modified `AgentConfig` (builder pattern).\n\n# Examples\n\n```\nuse forge_agent::agent::AgentConfig;\nuse forge_identity::lineage::{create_hmr_identity, derive_agent_identity};\n\nlet hmr = create_hmr_identity(\"test\", \"alice\").unwrap();\nlet agent_id = derive_agent_identity(&hmr, \"bot\", \"test\").unwrap();\n\nlet config = AgentConfig::new(\"bot\", \"openai:gpt-4o\")\n    .with_identity(agent_id);\nassert!(config.identity().is_some());\nassert_eq!(config.agent_did(), Some(\"did:oas:test:agent:bot\"));\n```"
        },
        {
          "name": "::AgentConfig::with_act",
          "line": 577,
          "signature": "pub fn with_act(mut self, act: AgentCapabilityToken) -> Self;",
          "documentation": "Sets the Arsenal ACT (Agent Capability Token) for this agent.\n\nWhen an ACT is configured, Tier 2 (Host) tool invocations are checked\nagainst the ACT's scopes. Without an ACT, host tools execute in legacy\nmode (no authorization enforcement).\n\nSee ANVIL Spec SS8.7 -- Tool Authorization Gate.\n\n# Arguments\n\n* `act` - The agent's Arsenal capability token.\n\n# Returns\n\nThe modified `AgentConfig` (builder pattern).\n\n# Examples\n\n```no_run\nuse forge_agent::agent::AgentConfig;\n# use arsenal_core::token::AgentCapabilityToken;\n\n# fn example(act: AgentCapabilityToken) {\nlet config = AgentConfig::new(\"bot\", \"openai:gpt-4o\")\n    .with_act(act);\nassert!(config.act().is_some());\n# }\n```"
        },
        {
          "name": "::AgentConfig::name",
          "line": 583,
          "signature": "pub fn name(&self) -> &str;",
          "documentation": "Returns the agent's name."
        },
        {
          "name": "::AgentConfig::model",
          "line": 588,
          "signature": "pub fn model(&self) -> &ProviderRef;",
          "documentation": "Returns the provider reference for this agent's model."
        },
        {
          "name": "::AgentConfig::tools",
          "line": 593,
          "signature": "pub fn tools(&self) -> &[ToolDefinition];",
          "documentation": "Returns the tool definitions available to this agent."
        },
        {
          "name": "::AgentConfig::max_steps",
          "line": 598,
          "signature": "pub fn max_steps(&self) -> u32;",
          "documentation": "Returns the maximum number of tool loop steps."
        },
        {
          "name": "::AgentConfig::system_prompt",
          "line": 603,
          "signature": "pub fn system_prompt(&self) -> Option<&str>;",
          "documentation": "Returns the system prompt, if configured."
        },
        {
          "name": "::AgentConfig::boundary_contract",
          "line": 608,
          "signature": "pub fn boundary_contract(&self) -> Option<&BoundaryContract>;",
          "documentation": "Returns the configured provider execution boundary contract, if present."
        },
        {
          "name": "::AgentConfig::identity",
          "line": 619,
          "signature": "pub fn identity(&self) -> Option<&ForgeAgentIdentity>;",
          "documentation": "Returns the agent's OAS identity, if configured.\n\nWhen `Some`, the agent carries a cryptographic identity with an\nEd25519 keypair, signed OAS document, and lineage proof chain.\nWhen `None`, the agent is in legacy mode without identity binding.\n\nSee ANVIL Spec SS11.1 -- OAS Identity Binding."
        },
        {
          "name": "::AgentConfig::act",
          "line": 629,
          "signature": "pub fn act(&self) -> Option<&AgentCapabilityToken>;",
          "documentation": "Returns the agent's Arsenal ACT (Agent Capability Token), if configured.\n\nWhen `Some`, tool invocations for Tier 2 (Host) tools are checked\nagainst the ACT's scopes. When `None`, tools run in legacy mode.\n\nSee ANVIL Spec SS8.7 -- Tool Authorization Gate."
        },
        {
          "name": "::AgentConfig::agent_did",
          "line": 647,
          "signature": "pub fn agent_did(&self) -> Option<&str>;",
          "documentation": "Returns the agent's OAS DID string, if an identity is configured.\n\nThis is a convenience accessor equivalent to\n`config.identity().map(|id| id.did())`.\n\n# Examples\n\n```\nuse forge_agent::agent::AgentConfig;\n\n// No identity \u2014 returns None\nlet config = AgentConfig::new(\"bot\", \"openai:gpt-4o\");\nassert!(config.agent_did().is_none());\n```"
        },
        {
          "name": "::AgentConfig::preflight_coding_provider_execution",
          "line": 652,
          "signature": "pub async fn preflight_coding_provider_execution<V: ProviderAuthorityVerifier>(\n        &self,\n        registry: &ProviderRegistry,\n        request: &ProviderNegotiationRequest,\n        verifier: &V,\n    ) -> Result<CodingProviderPreflight, ForgeAgentError>;",
          "documentation": "Performs fail-closed provider security checks before coding-provider execution."
        },
        {
          "name": "::ToolInvocationRecord",
          "line": 815,
          "signature": "#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\npub struct ToolInvocationRecord {\n/// The tool call id that the model assigned.\n\npub id: String,\n/// The tool's registered name.\n\npub name: String,\n/// Wall-clock timestamp at which the agent began executing the tool.\n\n///\n\n/// Serialized as RFC 3339. Set from `chrono::Utc::now()` immediately\n\n/// before the executor (or authorization gate / lookup) is invoked.\n\n#[serde(with = \"tool_invocation_started_at_serde\")]\npub started_at: chrono::DateTime<chrono::Utc>,\n/// Time elapsed between the start and the resolution of the invocation.\n\n///\n\n/// Captures the full latency: authorization check + executor + approval\n\n/// handler. Serialized as a struct (`{ \"secs\": u64, \"nanos\": u32 }`).\n\npub duration: std::time::Duration,\n/// Final status of the invocation.\n\npub status: ToolInvocationStatus\n}",
          "documentation": "Outcome of a single tool invocation captured during an agent's run.\n\nRecorded for every tool call the agent made, regardless of whether the\ninvocation succeeded, was denied by authorization, was rejected by the\napproval handler, or failed to find the tool. Pairs naturally with\n[`AgentOutput::tool_invocations`] for per-tool latency analysis,\nhistogram emission, or session telemetry.\n\nSee ANVIL Spec \u00a714.1 \u2014 Telemetry, \u00a78.5 \u2014 Tool Execution."
        },
        {
          "name": "::ModelInferenceRecord",
          "line": 842,
          "signature": "#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\npub struct ModelInferenceRecord {\n/// Host or loop assigned id for this model call.\n\npub id: String,\n/// Model identifier selected for the call.\n\npub model: String,\n/// Provider identifier or namespace that served the call.\n\npub provider_id: String,\n/// Optional model-router or Foundry route id.\n\npub route_id: Option<String>,\n/// Governed artifact ref for the prompt payload.\n\npub prompt_ref: Option<String>,\n/// Governed artifact ref for the completion payload.\n\npub completion_ref: Option<String>,\n/// Prompt/input token count, when reported.\n\npub prompt_tokens: Option<u64>,\n/// Completion/output token count, when reported.\n\npub completion_tokens: Option<u64>,\n/// Wall-clock timestamp at which the model call began.\n\n#[serde(with = \"tool_invocation_started_at_serde\")]\npub started_at: chrono::DateTime<chrono::Utc>,\n/// Time elapsed between model call start and stream completion.\n\npub duration: std::time::Duration,\n/// Canonical Cambium outcome label, such as `success` or `failed`.\n\npub outcome: String\n}",
          "documentation": "Outcome of a single language-model inference captured during an agent run.\n\nThe record carries provider/model identifiers, governed prompt/completion\nrefs, token counts, and latency. It intentionally excludes raw prompt and\ncompletion text so telemetry sinks can project model activity without\nstoring sensitive payloads."
        },
        {
          "name": "::SubAgentDelegationRecord",
          "line": 873,
          "signature": "#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\npub struct SubAgentDelegationRecord {\n/// OAS/stable child agent id.\n\npub subagent_id: String,\n/// Host-assigned run id for the delegated sub-agent.\n\npub subagent_run_id: String,\n/// Optional summary of why the delegation happened.\n\npub delegation_reason: Option<String>,\n/// Governed artifact ref for the delegated instruction.\n\npub instruction_ref: Option<String>,\n/// Capability refs granted to the child.\n\npub capability_refs: Vec<String>,\n/// Governed artifact ref for handoff state.\n\npub handoff_ref: Option<String>,\n/// Wall-clock timestamp at which delegation started.\n\n#[serde(with = \"tool_invocation_started_at_serde\")]\npub started_at: chrono::DateTime<chrono::Utc>\n}",
          "documentation": "Semantic record for a parent agent delegating work to a sub-agent.\n\nRefs point to governed artifacts for instructions and handoff context.\nRaw instructions are intentionally not modeled here."
        },
        {
          "name": "::AgentEvent",
          "line": 900,
          "signature": "#[derive(Debug, Clone, PartialEq, Eq)]\npub enum AgentEvent {\n    /// A user message was added to the conversation.\n    UserMessage(String),\n    /// A system message was added to the conversation.\n    SystemMessage(String),\n    /// The assistant produced a text turn (no tool calls).\n    AssistantText(String),\n    /// The assistant called a tool. Pairs with a later [`AgentEvent::ToolResult`]\n    /// (matched on `id`) and, if the run captured timing,\n    /// [`AgentEvent::ToolInvocationCompleted`].\n    AssistantToolCall {\n        id: String,\n        name: String,\n        arguments: serde_json::Value,\n    },\n    /// The tool returned a result (already in the conversation as a `Role::Tool`\n    /// message). `is_error` reflects the tool result's own flag.\n    ToolResult {\n        id: String,\n        name: String,\n        content: String,\n        is_error: bool,\n    },\n    /// A timed tool invocation completed (lifted from\n    /// [`AgentOutput::tool_invocations`]). Carries the typed status, the\n    /// captured duration, and the wall-clock start.\n    ToolInvocationCompleted(ToolInvocationRecord),\n}",
          "documentation": "Typed agent execution event derived from a completed [`AgentOutput`].\n\nProvides a structured view over the messages and tool invocations of a\nrun so consumers can iterate semantic boundaries (assistant text, tool\ncalls, tool results) without walking `output.messages` and pattern\nmatching `MessagePart` themselves.\n\nBuild via [`AgentOutput::events`]."
        },
        {
          "name": "::ToolInvocationStatus",
          "line": 932,
          "signature": "#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"snake_case\")]\npub enum ToolInvocationStatus {\n    /// The executor returned `Ok` and the tool result is not flagged as an error.\n    Succeeded,\n    /// The executor returned `Ok` but the tool result is flagged as an error.\n    /// Distinguished from `Failed` so callers can see \"the tool ran fine but\n    /// the model's request was wrong\" vs. \"the tool itself blew up.\"\n    SucceededWithToolError,\n    /// The tool name was not present in the registry.\n    NotFound,\n    /// Authorization (ACT scope check) denied the invocation.\n    AuthorizationDenied,\n    /// The executor returned `Err`.\n    Failed,\n}",
          "documentation": "Outcome status for a [`ToolInvocationRecord`]."
        },
        {
          "name": "tool_invocation_started_at_serde::serialize",
          "line": 951,
          "signature": "pub fn serialize<S>(value: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: Serializer,;",
          "documentation": ""
        },
        {
          "name": "tool_invocation_started_at_serde::deserialize",
          "line": 958,
          "signature": "pub fn deserialize<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>\n    where\n        D: Deserializer<'de>,;",
          "documentation": ""
        },
        {
          "name": "::AGENT_RUN_CHECKPOINT_SCHEMA",
          "line": 970,
          "signature": "pub const AGENT_RUN_CHECKPOINT_SCHEMA: &str;",
          "documentation": "Schema id for Forge agent run checkpoints."
        },
        {
          "name": "::AgentRunCheckpoint",
          "line": 979,
          "signature": "#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct AgentRunCheckpoint {\n/// Stable schema id. Must be [`AGENT_RUN_CHECKPOINT_SCHEMA`].\n\npub schema: String,\n/// Host-assigned run identifier.\n\npub run_id: String,\n/// Agent name from the originating [`AgentConfig`].\n\npub agent_name: String,\n/// Provider model reference from the originating [`AgentConfig`].\n\npub model: String,\n/// Number of tool-loop steps already consumed.\n\npub step_count: u32,\n/// Maximum steps allowed for the originating run.\n\npub max_steps: u32,\n/// Conversation state to pass back into [`Agent::run_with_messages`].\n\npub messages: Vec<ModelMessage>,\n/// Usage accumulated before the checkpoint was written.\n\npub usage: Usage,\n/// Final or latest assistant text available when the checkpoint was written.\n\npub final_text: String,\n/// Tool invocation audit records accumulated before the checkpoint was\n\n/// written.\n\n#[serde(default)]\npub tool_invocations: Vec<ToolInvocationRecord>\n}",
          "documentation": "Serializable checkpoint for resuming a Forge agent run.\n\nThis is a runtime checkpoint envelope, not a storage backend. Hosts such as\nKin, Flocks, or a custom scheduler can persist this value anywhere, validate\nit against the intended [`AgentConfig`], and resume with\n[`Agent::run_with_messages`] using [`Self::resume_messages`]."
        },
        {
          "name": "::AgentRunCheckpoint::validate_for",
          "line": 1014,
          "signature": "pub fn validate_for(&self, config: &AgentConfig) -> Result<(), AgentCheckpointValidationError>;",
          "documentation": "Validate this checkpoint against the config that will resume it.\n\nThis prevents a host from accidentally resuming a checkpoint under the\nwrong agent, model, or step budget.\n\n# Errors\n\nReturns [`AgentCheckpointValidationError`] when the schema, run id,\nagent name, model reference, or step budget does not match."
        },
        {
          "name": "::AgentRunCheckpoint::resume_messages",
          "line": 1054,
          "signature": "pub fn resume_messages(&self) -> &[ModelMessage];",
          "documentation": "Returns the conversation messages to resume with\n[`Agent::run_with_messages`]."
        },
        {
          "name": "::AgentRunCheckpoint::remaining_steps",
          "line": 1059,
          "signature": "pub fn remaining_steps(&self) -> u32;",
          "documentation": "Returns how many tool-loop steps remain before max-step exhaustion."
        },
        {
          "name": "::AgentRunCheckpoint::resume_config_for",
          "line": 1075,
          "signature": "pub fn resume_config_for(\n        &self,\n        config: &AgentConfig,\n    ) -> Result<AgentConfig, AgentCheckpointValidationError>;",
          "documentation": "Validate this checkpoint and build an [`AgentConfig`] for resume that\nuses only the remaining step budget.\n\nHosts that recreate agents for resumed runs should use this instead of\nreusing the original config unchanged; otherwise a resumed agent could\nreceive a fresh full step budget after already consuming part of the\noriginal run.\n\n# Errors\n\nReturns [`AgentCheckpointValidationError`] when the checkpoint does not\nmatch the supplied config or when no step budget remains."
        },
        {
          "name": "::AgentRunCheckpoint::digest_sha256",
          "line": 1099,
          "signature": "pub fn digest_sha256(&self) -> Result<String, serde_json::Error>;",
          "documentation": "Compute a stable SHA-256 digest over the serialized checkpoint envelope.\n\nHosts can persist this digest next to the checkpoint reference so another\nagent, scheduler, or launch gate can detect tampering after storage or\ntransfer without changing the checkpoint schema.\n\n# Errors\n\nReturns the underlying JSON serialization error if the checkpoint cannot\nbe serialized."
        },
        {
          "name": "::AgentRunCheckpoint::verify_digest_sha256",
          "line": 1115,
          "signature": "pub fn verify_digest_sha256(\n        &self,\n        expected: &str,\n    ) -> Result<(), AgentCheckpointValidationError>;",
          "documentation": "Verify this checkpoint against an expected SHA-256 digest.\n\nThis helper keeps host launch gates from hand-rolling digest-shape and\nmismatch checks differently across Kin, Flocks, AGX, or custom\nschedulers.\n\n# Errors\n\nReturns [`AgentCheckpointValidationError`] when the expected digest is\nmalformed, the checkpoint cannot be serialized for hashing, or the\ncomputed checkpoint digest does not match."
        },
        {
          "name": "::AgentCheckpointValidationError",
          "line": 1156,
          "signature": "#[derive(Debug, Clone, PartialEq, Eq)]\npub enum AgentCheckpointValidationError {\n    /// Checkpoint schema is not the supported Forge checkpoint schema.\n    SchemaMismatch {\n        /// Expected schema id.\n        expected: String,\n        /// Schema id found in the checkpoint.\n        found: String,\n    },\n    /// Checkpoint run id is empty.\n    EmptyRunId,\n    /// Checkpoint belongs to a different agent name.\n    AgentNameMismatch {\n        /// Expected agent name.\n        expected: String,\n        /// Agent name found in the checkpoint.\n        found: String,\n    },\n    /// Checkpoint belongs to a different model reference.\n    ModelMismatch {\n        /// Expected provider model reference.\n        expected: String,\n        /// Model reference found in the checkpoint.\n        found: String,\n    },\n    /// Checkpoint max-step budget differs from the resume config.\n    MaxStepsMismatch {\n        /// Expected max-step budget.\n        expected: u32,\n        /// Max-step budget found in the checkpoint.\n        found: u32,\n    },\n    /// Checkpoint has already consumed more steps than the budget allows.\n    StepCountExceedsMax {\n        /// Steps already consumed.\n        step_count: u32,\n        /// Maximum allowed steps.\n        max_steps: u32,\n    },\n    /// Checkpoint has no remaining steps for a resumed run.\n    StepBudgetExhausted {\n        /// Original maximum allowed steps.\n        max_steps: u32,\n    },\n    /// Expected checkpoint digest is not a SHA-256 hex string.\n    InvalidDigest {\n        /// Digest value that failed shape validation.\n        found: String,\n    },\n    /// Checkpoint could not be serialized for digest verification.\n    DigestSerializationFailed {\n        /// Serialization failure message.\n        message: String,\n    },\n    /// Checkpoint digest does not match expected evidence.\n    DigestMismatch {\n        /// Expected checkpoint digest.\n        expected: String,\n        /// Actual checkpoint digest.\n        found: String,\n    },\n}",
          "documentation": "Validation failure for a Forge agent run checkpoint."
        },
        {
          "name": "::AgentOutput",
          "line": 1303,
          "signature": "#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct AgentOutput {\n/// The complete conversation history including all user, assistant,\n\n/// and tool messages exchanged during execution.\n\npub messages: Vec<ModelMessage>,\n/// Cumulative token usage across all LLM calls during execution.\n\npub usage: Usage,\n/// The number of tool loop steps taken (each LLM call counts as one step).\n\npub steps_taken: u32,\n/// The final text response produced by the agent.\n\n///\n\n/// This is the text content of the last assistant message that did not\n\n/// contain tool calls (i.e., the terminal response).\n\npub final_text: String,\n/// Per-tool invocation records collected during the run.\n\n///\n\n/// One entry per tool call attempted, in the order they were executed.\n\n/// Includes name, wall-clock start, duration, and final status (succeeded /\n\n/// failed / authorization-denied / not-found). Backfilled to an empty\n\n/// `Vec` when constructing `AgentOutput` from older code paths or when\n\n/// deserializing payloads that pre-date this field.\n\n#[serde(default)]\npub tool_invocations: Vec<ToolInvocationRecord>\n}",
          "documentation": "The output produced by an agent's execution.\n\nContains the complete conversation history, token usage statistics,\nthe number of steps taken, the final text response, and per-tool\ninvocation records.\n\n# ANVIL Spec SS7.1\n\nAgent output includes the final response text, accumulated usage\nstatistics, step count, and tool invocation history for observability\nand audit purposes.\n\n# Examples\n\n```\nuse forge_agent::agent::AgentOutput;\nuse forge_core::message::{ModelMessage, Role};\nuse forge_core::output::Usage;\n\nlet output = AgentOutput {\n    messages: vec![\n        ModelMessage::text(Role::User, \"What is 2+2?\"),\n        ModelMessage::text(Role::Assistant, \"The answer is 4.\"),\n    ],\n    usage: Usage { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 },\n    steps_taken: 1,\n    final_text: \"The answer is 4.\".to_string(),\n    tool_invocations: Vec::new(),\n};\nassert_eq!(output.steps_taken, 1);\nassert_eq!(output.final_text, \"The answer is 4.\");\nassert!(output.tool_invocations.is_empty());\n```"
        },
        {
          "name": "::AgentOutput::to_checkpoint",
          "line": 1337,
          "signature": "pub fn to_checkpoint(\n        &self,\n        run_id: impl Into<String>,\n        config: &AgentConfig,\n    ) -> AgentRunCheckpoint;",
          "documentation": "Build a serializable checkpoint from this completed or partial output.\n\nHosts can persist the returned [`AgentRunCheckpoint`] and later validate\nit with [`AgentRunCheckpoint::validate_for`] before resuming with\n[`Agent::run_with_messages`]."
        },
        {
          "name": "::AgentOutput::events",
          "line": 1391,
          "signature": "pub fn events(&self) -> impl Iterator<Item = AgentEvent> + '_;",
          "documentation": "Returns a typed event stream derived from `messages` and `tool_invocations`.\n\nWalks the conversation in order and emits one [`AgentEvent`] per\nsemantic boundary -- user message, system message, assistant text turn,\nassistant tool call, tool result -- followed by every\n[`ToolInvocationRecord`] as a [`AgentEvent::ToolInvocationCompleted`]\nat the end. The trailing block lets observers do per-tool latency\nanalysis without walking `tool_invocations` separately.\n\nThis is a non-allocating projection: the iterator clones strings as\nit goes but never materializes the full event vector. Consumers that\nneed a `Vec` can call `.collect()`.\n\n# Examples\n\n```\nuse forge_agent::agent::{AgentEvent, AgentOutput};\nuse forge_core::message::{ModelMessage, Role};\nuse forge_core::output::Usage;\n\nlet output = AgentOutput {\n    messages: vec![\n        ModelMessage::text(Role::User, \"hi\"),\n        ModelMessage::text(Role::Assistant, \"hello\"),\n    ],\n    usage: Usage::zero(),\n    steps_taken: 1,\n    final_text: \"hello\".to_string(),\n    tool_invocations: Vec::new(),\n};\nlet events: Vec<_> = output.events().collect();\nassert_eq!(events.len(), 2);\nassert!(matches!(events[0], AgentEvent::UserMessage(_)));\nassert!(matches!(events[1], AgentEvent::AssistantText(_)));\n```"
        },
        {
          "name": "::Agent",
          "line": 1504,
          "signature": "#[async_trait]\npub trait Agent: Send + Sync {\n    /// Returns the agent's configuration.\n    ///\n    /// # Returns\n    ///\n    /// A reference to the [`AgentConfig`] used to create this agent.\n    fn config(&self) -> &AgentConfig;\n\n    /// Returns a snapshot of the agent's current health profile.\n    ///\n    /// The health profile contains runtime metrics: uptime, error counts,\n    /// tool invocations, inference statistics, and resource usage. Returns\n    /// a clone because the profile is mutated concurrently during execution\n    /// (behind interior mutability).\n    ///\n    /// # ANVIL Spec SS14.1\n    ///\n    /// Health profiles are part of the telemetry contract. They are exposed\n    /// for monitoring and audit trail consumption.\n    ///\n    /// # Returns\n    ///\n    /// A cloned snapshot of the agent's [`HealthProfile`].\n    fn health(&self) -> HealthProfile;\n\n    /// Returns the agent's current lifecycle state.\n    ///\n    /// # ANVIL Spec SS13.2\n    ///\n    /// The lifecycle state machine has six states: Initializing, Ready,\n    /// Running, Paused, Error, Terminated. See the spec for the complete\n    /// transition table.\n    ///\n    /// # Returns\n    ///\n    /// The current [`LifecycleState`].\n    fn lifecycle(&self) -> LifecycleState;\n\n    /// Runs the agent with a text prompt.\n    ///\n    /// This is the primary entry point for agent execution. It creates an\n    /// initial user message from the prompt and delegates to\n    /// [`run_with_messages`](Self::run_with_messages).\n    ///\n    /// # ANVIL Spec SS7.1\n    ///\n    /// The agent execution loop:\n    /// 1. Send messages to the LLM.\n    /// 2. If the response contains tool calls, execute them and loop.\n    /// 3. If the response is text only, return the final result.\n    /// 4. Check stop conditions after each step.\n    ///\n    /// # Arguments\n    ///\n    /// * `prompt` - The user's text prompt to process.\n    ///\n    /// # Returns\n    ///\n    /// An [`AgentOutput`] containing the final response, conversation history,\n    /// usage statistics, and step count.\n    ///\n    /// # Errors\n    ///\n    /// * [`ForgeAgentError::ToolLoopFailed`] -- if a tool loop step fails.\n    /// * [`ForgeAgentError::LifecycleError`] -- if the agent is not in a runnable state.\n    /// * [`ForgeAgentError::StopConditionReached`] -- if max steps or tokens are exceeded.\n    /// * [`ForgeAgentError::Generate`] -- if the underlying model call fails.\n    /// * [`ForgeAgentError::Tool`] -- if a tool execution fails.\n    async fn run(&self, prompt: &str) -> Result<AgentOutput, ForgeAgentError>;\n\n    /// Runs the agent with a pre-constructed message list.\n    ///\n    /// This is the lower-level entry point that allows callers to provide\n    /// the complete conversation history, including system messages, tool\n    /// results, and previous exchanges.\n    ///\n    /// # Arguments\n    ///\n    /// * `messages` - The initial message list to process.\n    ///\n    /// # Returns\n    ///\n    /// An [`AgentOutput`] containing the final response and metadata.\n    ///\n    /// # Errors\n    ///\n    /// Same error variants as [`run()`](Self::run).\n    async fn run_with_messages(\n        &self,\n        messages: Vec<ModelMessage>,\n    ) -> Result<AgentOutput, ForgeAgentError>;\n}",
          "documentation": "The core agent trait.\n\nAll agent implementations -- tool loop agents, workflow agents, sub-agents --\nimplement this trait. It provides a uniform interface for running agents and\ninspecting their state.\n\n# ANVIL Spec Reference\n\n- SS5.1 -- Lifecycle State Machine: `lifecycle()` returns the current state.\n- SS7.1 -- Agent Execution Loop: `run()` executes the agent.\n- SS14.1 -- Telemetry: `health()` returns the health profile.\n\n# Thread Safety\n\nAgents must be `Send + Sync` because they may be shared across async tasks\n(e.g., in parallel workflows or agent pools).\n\n# Examples\n\n```no_run\nuse forge_agent::agent::{Agent, AgentOutput};\nuse forge_agent::error::ForgeAgentError;\nuse forge_core::message::ModelMessage;\n\nasync fn run_agent(agent: &dyn Agent) -> Result<AgentOutput, ForgeAgentError> {\n    agent.run(\"What is 2+2?\").await\n}\n```"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-agent/src/cambium.rs",
      "sha256": "d55ca139681664d21857ea2529daf61e330c3e5279d496213b4c9f7dc53e00f2",
      "artifactSha256": "8bcc78b6ec8a26df4cc3ef0e95c9e6065cd19b1185ef4bf254dd58ed84daf3ad",
      "url": "/reference/source/forge-rs/crates/forge-agent/src/cambium.rs.txt",
      "declarations": [
        {
          "name": "pub use cambium_sdk_rs::{CambiumEvent, CambiumJson, CambiumScope};",
          "line": 15,
          "signature": "pub use cambium_sdk_rs::{CambiumEvent, CambiumJson, CambiumScope};",
          "documentation": ""
        },
        {
          "name": "::ForgeCambiumObserverConfig",
          "line": 24,
          "signature": "#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ForgeCambiumObserverConfig {\n/// Cambium tenant/product scope assigned by the embedding host.\n\npub scope: CambiumScope,\n/// Host-assigned Forge run id.\n\npub run_id: String,\n/// OAS agent id or stable agent identifier for lineage.\n\npub agent_id: String,\n/// Principal that requested or authorized the Forge run.\n\npub principal_id: String,\n/// Authentication authority for the principal, when known.\n\npub authenticated_by: Option<String>,\n/// Stable event id prefix used with each Forge tool call id.\n\npub event_id_prefix: String,\n/// Optional distributed trace id.\n\npub trace_id: Option<String>,\n/// Optional span id paired with `trace_id`.\n\npub span_id: Option<String>,\n/// Initial producer sequence. The first emitted event increments from this.\n\npub producer_sequence_start: u64\n}",
          "documentation": "Configuration for projecting Forge observer callbacks into Cambium events."
        },
        {
          "name": "::CambiumAgentLoopObserver",
          "line": 46,
          "signature": "pub struct CambiumAgentLoopObserver {\n\n}",
          "documentation": "Forge [`AgentLoopObserver`] that records Cambium events in a drainable outbox."
        },
        {
          "name": "::CambiumAgentLoopObserver::try_new",
          "line": 59,
          "signature": "pub fn try_new(config: ForgeCambiumObserverConfig) -> Result<Self, String>;",
          "documentation": "Create a Cambium observer after validating static launch context fields.\n\n# Errors\n\nReturns an error if required scope, run, agent, principal, or event id\nprefix fields are blank."
        },
        {
          "name": "::CambiumAgentLoopObserver::events",
          "line": 76,
          "signature": "#[must_use]\npub fn events(&self) -> Vec<CambiumEvent>;",
          "documentation": "Return a snapshot of buffered Cambium events without clearing them."
        },
        {
          "name": "::CambiumAgentLoopObserver::drain_events",
          "line": 85,
          "signature": "#[must_use]\npub fn drain_events(&self) -> Vec<CambiumEvent>;",
          "documentation": "Drain buffered Cambium events for host-side signing and delivery."
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-agent/src/context_manager.rs",
      "sha256": "fffd8cfc51712e9c21f0c9fdfe862e616c5374cc18fe8c99acac5e32fe4e6f83",
      "artifactSha256": "a19e59b9dd0ec89a3512f5401f010421e2d5dfdc4f3374939b5fa7febf3bf9a9",
      "url": "/reference/source/forge-rs/crates/forge-agent/src/context_manager.rs.txt",
      "declarations": [
        {
          "name": "::PruningStrategy",
          "line": 22,
          "signature": "#[derive(Debug, Clone, Copy)]\npub enum PruningStrategy {\n    /// Remove the oldest non-system messages first.\n    RemoveOldest,\n    /// Keep system prompt + the last N messages (sliding window).\n    SlidingWindow {\n        /// Maximum number of recent messages to keep (in addition to system).\n        keep_last: usize,\n    },\n    /// Summarize older messages into a single system message.\n    /// (Future: will use the model to generate a summary.)\n    Summarize,\n}",
          "documentation": "Strategy for pruning messages when the context window is nearly full."
        },
        {
          "name": "::ContextWindowConfig",
          "line": 37,
          "signature": "#[derive(Debug, Clone)]\npub struct ContextWindowConfig {\n/// Maximum number of tokens the model supports.\n\npub max_context_tokens: u64,\n/// Threshold ratio (0.0\u20131.0) at which to start pruning.\n\n/// Default: 0.85 (prune when 85% of context is used).\n\npub threshold_ratio: f64,\n/// Estimated tokens per message for the simple estimator.\n\n/// Default: 4 (roughly 4 tokens per word, ~100 words per message = 400).\n\npub tokens_per_char: f64,\n/// Pruning strategy to use when threshold is exceeded.\n\npub strategy: PruningStrategy\n}",
          "documentation": "Configuration for context window management."
        },
        {
          "name": "::ContextWindowManager",
          "line": 80,
          "signature": "pub struct ContextWindowManager {\n\n}",
          "documentation": "Manages the conversation context window to prevent overflow.\n\nImplements [`PrepareStep`] so it can be plugged into the agent's tool loop\nas a pre-step hook. Before each LLM call, it estimates the token count and\nprunes messages if the threshold is exceeded.\n\n# Examples\n\n```\nuse forge_agent::context_manager::{ContextWindowManager, ContextWindowConfig, PruningStrategy};\n\nlet config = ContextWindowConfig {\n    max_context_tokens: 128_000,\n    threshold_ratio: 0.85,\n    strategy: PruningStrategy::SlidingWindow { keep_last: 20 },\n    ..ContextWindowConfig::default()\n};\nlet manager = ContextWindowManager::new(config);\n```"
        },
        {
          "name": "::ContextWindowManager::new",
          "line": 86,
          "signature": "pub fn new(config: ContextWindowConfig) -> Self;",
          "documentation": "Create a new context window manager with the given configuration."
        },
        {
          "name": "::ContextWindowManager::for_context_size",
          "line": 91,
          "signature": "pub fn for_context_size(max_tokens: u64) -> Self;",
          "documentation": "Create a manager with default settings for a given context size."
        },
        {
          "name": "::ContextWindowManager::estimate_tokens",
          "line": 102,
          "signature": "pub fn estimate_tokens(&self, messages: &[ModelMessage]) -> u64;",
          "documentation": "Estimate the token count for a set of messages.\n\nUses a simple character-based estimation. Production implementations\nshould use a proper tokenizer."
        },
        {
          "name": "::ContextWindowManager::threshold_tokens",
          "line": 116,
          "signature": "pub fn threshold_tokens(&self) -> u64;",
          "documentation": "Returns the configured threshold in tokens."
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-agent/src/error.rs",
      "sha256": "a14655daf1adde0a63aecf6d3b61545a56aa6a704bbe2315a506fcdffb7e0f69",
      "artifactSha256": "39d3e58075bc57924ee7dddf99a6064631dbf54eba57a72f1713471ad225ac0d",
      "url": "/reference/source/forge-rs/crates/forge-agent/src/error.rs.txt",
      "declarations": [
        {
          "name": "::ForgeAgentError",
          "line": 35,
          "signature": "#[derive(Debug, Error)]\npub enum ForgeAgentError {\n    /// The agent's tool loop failed during execution.\n    ///\n    /// This error indicates that a step within the agent's tool loop encountered\n    /// an unrecoverable failure. The `step` field indicates which iteration\n    /// failed, and `reason` explains what went wrong.\n    ///\n    /// See ANVIL Spec SS7.1 -- Agent Execution Loop.\n    #[error(\"agent '{agent_name}' tool loop failed at step {step}: {reason}\")]\n    ToolLoopFailed {\n        /// The name of the agent whose tool loop failed.\n        agent_name: String,\n        /// The step number (1-indexed) at which the failure occurred.\n        step: u32,\n        /// A human-readable description of what went wrong.\n        reason: String,\n    },\n\n    /// A workflow orchestration step failed.\n    ///\n    /// This error wraps failures that occur during sequential, parallel, or\n    /// router workflow execution. It identifies which agent within the workflow\n    /// caused the failure.\n    ///\n    /// See ANVIL Spec SS7.2 -- Agent Workflows.\n    #[error(\"workflow '{workflow_name}' failed at agent '{agent_name}': {reason}\")]\n    WorkflowFailed {\n        /// The name of the workflow that failed.\n        workflow_name: String,\n        /// The name of the agent within the workflow that caused the failure.\n        agent_name: String,\n        /// A human-readable description of the failure.\n        reason: String,\n    },\n\n    /// A sub-agent delegation failed.\n    ///\n    /// This error occurs when creating or executing a sub-agent that was\n    /// delegated work from a parent agent. The parent-child relationship\n    /// is captured in the error context.\n    ///\n    /// See ANVIL Spec SS11.2 -- Lineage Propagation.\n    #[error(\n        \"sub-agent delegation failed: parent '{parent_name}' -> child '{child_name}': {reason}\"\n    )]\n    SubAgentFailed {\n        /// The parent agent that initiated the delegation.\n        parent_name: String,\n        /// The child agent that failed.\n        child_name: String,\n        /// A human-readable description of the failure.\n        reason: String,\n    },\n\n    /// A lifecycle state machine violation occurred.\n    ///\n    /// This error wraps [`forge_health::error::ForgeHealthError`] when an agent\n    /// attempts an invalid lifecycle transition (e.g., running a terminated agent).\n    ///\n    /// See ANVIL Spec SS5.1 -- Lifecycle State Machine.\n    #[error(\"lifecycle error in agent '{agent_name}': {reason}\")]\n    LifecycleError {\n        /// The agent whose lifecycle is in an invalid state.\n        agent_name: String,\n        /// A human-readable explanation of the lifecycle violation.\n        reason: String,\n    },\n\n    /// An inter-agent messaging operation failed.\n    ///\n    /// This error occurs when sending or receiving messages between agents\n    /// via agent channels. Common causes include channel closure and capacity\n    /// exhaustion.\n    #[error(\"agent messaging error: {reason}\")]\n    MessageError {\n        /// A human-readable description of the messaging failure.\n        reason: String,\n    },\n\n    /// The agent's stop condition was reached.\n    ///\n    /// This is a structured termination, not a failure. The agent stopped\n    /// because its configured stop condition (max steps, max tokens, or a\n    /// custom predicate) was satisfied.\n    ///\n    /// See ANVIL Spec SS7.1 -- Agent Execution Loop, stop conditions.\n    #[error(\"agent '{agent_name}' stopped: {reason} (steps={steps_taken}, tokens={tokens_used})\")]\n    StopConditionReached {\n        /// The agent that was stopped.\n        agent_name: String,\n        /// Why the agent stopped.\n        reason: String,\n        /// Number of tool loop steps completed.\n        steps_taken: u32,\n        /// Total tokens consumed across all steps.\n        tokens_used: u64,\n    },\n\n    /// Tool invocation was denied by the authorization gate (ANVIL Spec SS8.7).\n    ///\n    /// This error occurs when a Host (Tier 2) tool is invoked but the agent's\n    /// Arsenal ACT does not grant the required scope. Platform (Tier 1) and\n    /// Embedded (Tier 3) tools are never denied.\n    ///\n    /// See ANVIL Spec SS8.7 -- Tool Authorization Gate.\n    #[error(\"tool '{tool_name}' authorization denied for agent '{agent_did}': {reason}\")]\n    AuthorizationDenied {\n        /// The DID of the agent that was denied.\n        agent_did: String,\n        /// The tool that was requested.\n        tool_name: String,\n        /// A human-readable explanation of the denial.\n        reason: String,\n    },\n\n    /// Coding-provider execution was denied by the active boundary contract.\n    #[error(\"coding-provider execution denied for agent '{agent_name}' on provider '{provider_ref}': {reason}\")]\n    BoundaryContractDenied {\n        /// The human-readable agent name.\n        agent_name: String,\n        /// The provider reference that was denied.\n        provider_ref: String,\n        /// Why the boundary contract denied the execution.\n        reason: String,\n    },\n\n    /// AEGIS-backed delegation or authority validation failed before provider execution.\n    #[error(\"coding-provider delegation denied for agent '{agent_name}' on provider '{provider_ref}': {reason}\")]\n    DelegationDenied {\n        /// The human-readable agent name.\n        agent_name: String,\n        /// The provider reference that was denied.\n        provider_ref: String,\n        /// Why the delegation or authority check failed.\n        reason: String,\n    },\n\n    /// The agent's ACT does not grant the provider scope required for execution.\n    #[error(\"coding-provider scope denied for agent '{agent_name}' on provider '{provider_ref}': missing scope '{required_scope}' in ACT {act_id}\")]\n    CredentialScopeDenied {\n        /// The human-readable agent name.\n        agent_name: String,\n        /// The provider reference being executed.\n        provider_ref: String,\n        /// The scope required by the provider execution preflight.\n        required_scope: String,\n        /// The ACT that was checked, or `[missing]` when no ACT was configured.\n        act_id: String,\n    },\n\n    /// Identity derivation failed during sub-agent creation.\n    ///\n    /// This error occurs when a parent agent attempts to derive a child agent\n    /// identity, but the OAS key derivation or document construction fails.\n    ///\n    /// See ANVIL Spec SS11.2 -- Lineage Propagation.\n    #[error(\"identity derivation failed for sub-agent '{child_name}' from parent '{parent_did}': {reason}\")]\n    IdentityDerivationFailed {\n        /// The parent agent's OAS DID.\n        parent_did: String,\n        /// The child agent's intended name.\n        child_name: String,\n        /// A human-readable description of what went wrong.\n        reason: String,\n    },\n\n    /// A `forge-core` error occurred during agent execution.\n    #[error(\"core error: {0}\")]\n    Core(#[from] forge_core::error::ForgeError),\n\n    /// A `forge-generate` error occurred during inference.\n    #[error(\"generation error: {0}\")]\n    Generate(#[from] forge_generate::ForgeGenerateError),\n\n    /// A `forge-tool` error occurred during tool execution.\n    #[error(\"tool error: {0}\")]\n    Tool(#[from] forge_tool::error::ForgeToolError),\n\n    /// A `forge-health` error occurred during lifecycle management.\n    #[error(\"health error: {0}\")]\n    Health(#[from] forge_health::error::ForgeHealthError),\n\n    /// A `forge-identity` error occurred during identity operations.\n    #[error(\"identity error: {0}\")]\n    Identity(#[from] forge_identity::error::ForgeIdentityError),\n\n    /// A `forge-auth` error occurred during authorization operations.\n    #[error(\"auth error: {0}\")]\n    Auth(#[from] forge_auth::error::ForgeAuthError),\n}",
          "documentation": "Error type for agent execution, workflow orchestration, and inter-agent\ncommunication operations.\n\nEvery variant includes actionable context: what failed, why, and what the\ndeveloper should check. No generic \"something went wrong\" messages.\n\n# Examples\n\n```\nuse forge_agent::error::ForgeAgentError;\n\nlet err = ForgeAgentError::ToolLoopFailed {\n    agent_name: \"data-analyst\".to_string(),\n    step: 3,\n    reason: \"tool 'search' execution failed: connection timeout\".to_string(),\n};\nlet msg = err.to_string();\nassert!(msg.contains(\"data-analyst\"));\nassert!(msg.contains(\"step 3\"));\n```"
        },
        {
          "name": "::ForgeAgentResult",
          "line": 227,
          "signature": "pub type ForgeAgentResult<T> = Result<T, ForgeAgentError>;",
          "documentation": "A specialized `Result` type for `forge-agent` operations."
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-agent/src/lib.rs",
      "sha256": "9ed2d7c04865c5d9d24374495ca8870a865cfd97dbf51bb9d1630bc98204345f",
      "artifactSha256": "7098062faf907fb3c3697f6adc3effbc19a4e0e2476043c5b42f1e8b42d596ff",
      "url": "/reference/source/forge-rs/crates/forge-agent/src/lib.rs.txt",
      "declarations": [
        {
          "name": "agent",
          "line": 59,
          "signature": "pub mod agent;",
          "documentation": "# forge-agent\n\nANVIL-compliant agent execution loop, workflows, and multi-agent orchestration\nfor the Forge SDK.\n\nThis crate provides the core agent abstractions for building AI agents:\n\n| Module | Purpose |\n|--------|---------|\n| [`agent`] | The [`Agent`](agent::Agent) trait, [`AgentConfig`](agent::AgentConfig), and [`AgentOutput`](agent::AgentOutput) |\n| [`tool_loop`] | [`ToolLoopAgent`](tool_loop::ToolLoopAgent) -- the reference ANVIL agent execution loop |\n| [`workflow`] | Sequential, parallel, and router workflow orchestration |\n| [`subagent`] | Sub-agent creation with narrowed capabilities |\n| [`messaging`] | Inter-agent communication via bounded async channels |\n| [`loop_control`] | Stop conditions and pre-step hooks |\n| [`error`] | Typed error types for all agent operations |\n\n# ANVIL Spec Reference\n\nThis crate implements:\n- **SS13.2** -- Lifecycle State Machine (6 states, immutable transitions)\n- **SS7.1** -- Agent Execution Loop (tool loop algorithm)\n- **SS7.2** -- Agent Workflows (sequential, parallel, router)\n- **SS8.5** -- Tool Execution (3-tier classification, approval pipeline)\n- **SS11.2** -- Lineage Propagation (sub-agent delegation)\n- **SS14.1** -- Telemetry (health profiles, tracing spans)\n\n# Quick Start\n\n```no_run\nuse forge_agent::prelude::*;\nuse forge_core::model::LanguageModel;\nuse forge_tool::registry::ToolRegistry;\nuse forge_tool::approval::AutoApprove;\nuse std::sync::Arc;\n\nasync fn run(model: Arc<dyn LanguageModel>) {\n    let config = AgentConfig::new(\"assistant\", \"openai:gpt-4o\")\n        .with_system_prompt(\"You are a helpful assistant.\")\n        .with_max_steps(10);\n\n    let registry = ToolRegistry::new();\n    let approval = Arc::new(AutoApprove);\n\n    let agent = ToolLoopAgent::new(config, model, registry, approval);\n    let output = agent.run(\"What is 2+2?\").await;\n}\n```"
        },
        {
          "name": "cambium",
          "line": 60,
          "signature": "pub mod cambium;",
          "documentation": ""
        },
        {
          "name": "context_manager",
          "line": 61,
          "signature": "pub mod context_manager;",
          "documentation": ""
        },
        {
          "name": "error",
          "line": 62,
          "signature": "pub mod error;",
          "documentation": ""
        },
        {
          "name": "loop_control",
          "line": 63,
          "signature": "pub mod loop_control;",
          "documentation": ""
        },
        {
          "name": "messaging",
          "line": 65,
          "signature": "#[cfg(not(target_arch = \"wasm32\"))]\npub mod messaging;",
          "documentation": ""
        },
        {
          "name": "observer",
          "line": 66,
          "signature": "pub mod observer;",
          "documentation": ""
        },
        {
          "name": "streaming_tool_loop",
          "line": 67,
          "signature": "pub mod streaming_tool_loop;",
          "documentation": ""
        },
        {
          "name": "subagent",
          "line": 68,
          "signature": "pub mod subagent;",
          "documentation": ""
        },
        {
          "name": "tool_loop",
          "line": 69,
          "signature": "pub mod tool_loop;",
          "documentation": ""
        },
        {
          "name": "workflow",
          "line": 70,
          "signature": "pub mod workflow;",
          "documentation": ""
        },
        {
          "name": "prelude",
          "line": 81,
          "signature": "pub mod prelude;",
          "documentation": "Prelude module for convenient imports.\n\nImport everything you need for typical agent usage with:\n\n```\nuse forge_agent::prelude::*;\n```\n\nThis re-exports the most commonly used types from all modules."
        },
        {
          "name": "pub use crate::agent::AegisProviderAuthorityVerifier;",
          "line": 83,
          "signature": "#[cfg(not(target_arch = \"wasm32\"))]\npub use crate::agent::AegisProviderAuthorityVerifier;",
          "documentation": ""
        },
        {
          "name": "pub use crate::agent::{\n        Agent, AgentCheckpointValidationError, AgentConfig, AgentEvent, AgentOutput,\n        AgentRunCheckpoint, BoundaryContract, CodingProviderPreflight, ModelInferenceRecord,\n        ProviderAuthorityVerifier, ProviderIdentityVerification, SubAgentDelegationRecord,\n        ToolInvocationRecord, ToolInvocationStatus, AGENT_RUN_CHECKPOINT_SCHEMA,\n    };",
          "line": 84,
          "signature": "pub use crate::agent::{\n        Agent, AgentCheckpointValidationError, AgentConfig, AgentEvent, AgentOutput,\n        AgentRunCheckpoint, BoundaryContract, CodingProviderPreflight, ModelInferenceRecord,\n        ProviderAuthorityVerifier, ProviderIdentityVerification, SubAgentDelegationRecord,\n        ToolInvocationRecord, ToolInvocationStatus, AGENT_RUN_CHECKPOINT_SCHEMA,\n    };",
          "documentation": ""
        },
        {
          "name": "pub use crate::cambium::{\n        CambiumAgentLoopObserver, CambiumEvent, CambiumJson, CambiumScope,\n        ForgeCambiumObserverConfig,\n    };",
          "line": 90,
          "signature": "pub use crate::cambium::{\n        CambiumAgentLoopObserver, CambiumEvent, CambiumJson, CambiumScope,\n        ForgeCambiumObserverConfig,\n    };",
          "documentation": ""
        },
        {
          "name": "pub use crate::context_manager::{ContextWindowConfig, ContextWindowManager, PruningStrategy};",
          "line": 94,
          "signature": "pub use crate::context_manager::{ContextWindowConfig, ContextWindowManager, PruningStrategy};",
          "documentation": ""
        },
        {
          "name": "pub use crate::error::{ForgeAgentError, ForgeAgentResult};",
          "line": 95,
          "signature": "pub use crate::error::{ForgeAgentError, ForgeAgentResult};",
          "documentation": ""
        },
        {
          "name": "pub use crate::loop_control::{\n        AgentStopCondition, NoOpPrepare, PrepareStep, StopWhen, StopWhenCustom, StopWhenMaxSteps,\n        StopWhenTextGenerated, StopWhenToolCalled,\n    };",
          "line": 96,
          "signature": "pub use crate::loop_control::{\n        AgentStopCondition, NoOpPrepare, PrepareStep, StopWhen, StopWhenCustom, StopWhenMaxSteps,\n        StopWhenTextGenerated, StopWhenToolCalled,\n    };",
          "documentation": ""
        },
        {
          "name": "pub use crate::messaging::{\n        AgentChannel, AgentChannelReceiver, AgentChannelSender, AgentMessage,\n    };",
          "line": 101,
          "signature": "#[cfg(not(target_arch = \"wasm32\"))]\npub use crate::messaging::{\n        AgentChannel, AgentChannelReceiver, AgentChannelSender, AgentMessage,\n    };",
          "documentation": ""
        },
        {
          "name": "pub use crate::observer::{AgentLoopObserver, NoOpObserver};",
          "line": 104,
          "signature": "pub use crate::observer::{AgentLoopObserver, NoOpObserver};",
          "documentation": ""
        },
        {
          "name": "pub use crate::streaming_tool_loop::{StreamingLoopConfig, StreamingToolLoopAgent};",
          "line": 105,
          "signature": "pub use crate::streaming_tool_loop::{StreamingLoopConfig, StreamingToolLoopAgent};",
          "documentation": ""
        },
        {
          "name": "pub use crate::subagent::{\n        create_subagent, create_subagent_with_observer, SubAgentConfig, SubAgentDelegationContext,\n    };",
          "line": 106,
          "signature": "pub use crate::subagent::{\n        create_subagent, create_subagent_with_observer, SubAgentConfig, SubAgentDelegationContext,\n    };",
          "documentation": ""
        },
        {
          "name": "pub use crate::tool_loop::ToolLoopAgent;",
          "line": 109,
          "signature": "pub use crate::tool_loop::ToolLoopAgent;",
          "documentation": ""
        },
        {
          "name": "pub use crate::workflow::{\n        ParallelWorkflow, RouterWorkflow, SequentialWorkflow, WorkflowOutput,\n    };",
          "line": 110,
          "signature": "pub use crate::workflow::{\n        ParallelWorkflow, RouterWorkflow, SequentialWorkflow, WorkflowOutput,\n    };",
          "documentation": ""
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-agent/src/loop_control.rs",
      "sha256": "c4f923438df92e802bb29640ae0d09666872aa85bba295e29f24dd39fd22b032",
      "artifactSha256": "51bf1e22eb53c0390368c170d16e8b798bb0eeece733339f40ced60e419d9378",
      "url": "/reference/source/forge-rs/crates/forge-agent/src/loop_control.rs.txt",
      "declarations": [
        {
          "name": "::AgentStopCondition",
          "line": 58,
          "signature": "pub enum AgentStopCondition {\n    /// Stop when the step count reaches or exceeds this value.\n    ///\n    /// Steps are counted starting from 1 (the first LLM call is step 1).\n    MaxSteps(u32),\n\n    /// Stop when cumulative token usage reaches or exceeds this value.\n    ///\n    /// Token count includes both prompt and completion tokens across all steps.\n    MaxTokens(u64),\n\n    /// Stop when a custom predicate returns `true`.\n    ///\n    /// The predicate receives the current step count and total token usage.\n    /// It must be `Send + Sync` for use in async contexts.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use forge_agent::loop_control::AgentStopCondition;\n    ///\n    /// let stop = AgentStopCondition::Custom(Box::new(|steps, tokens| {\n    ///     steps >= 5 && tokens >= 2000\n    /// }));\n    /// assert!(stop.should_stop(5, 2000));\n    /// assert!(!stop.should_stop(4, 2000));\n    /// assert!(!stop.should_stop(5, 1999));\n    /// ```\n    Custom(Box<dyn Fn(u32, u64) -> bool + Send + Sync>),\n}",
          "documentation": "A condition that determines when the agent's tool loop should terminate.\n\nStop conditions are checked after each tool loop step. If any configured\nstop condition fires, the loop terminates and returns the accumulated output.\n\n# ANVIL Spec SS7.1\n\nThe agent execution loop must respect stop conditions to prevent runaway\nexecution. At minimum, `MaxSteps` should always be configured as a safety\nbound.\n\n# Examples\n\n```\nuse forge_agent::loop_control::AgentStopCondition;\n\n// Stop after 20 steps\nlet by_steps = AgentStopCondition::MaxSteps(20);\nassert!(!by_steps.should_stop(19, 0));\nassert!(by_steps.should_stop(20, 0));\n\n// Stop after 10000 tokens\nlet by_tokens = AgentStopCondition::MaxTokens(10000);\nassert!(!by_tokens.should_stop(1, 9999));\nassert!(by_tokens.should_stop(1, 10000));\n```"
        },
        {
          "name": "::AgentStopCondition::should_stop",
          "line": 111,
          "signature": "pub fn should_stop(&self, steps: u32, total_tokens: u64) -> bool;",
          "documentation": "Evaluates whether the stop condition is satisfied.\n\n# Arguments\n\n* `steps` - The current step count (1-indexed).\n* `total_tokens` - The cumulative token usage across all steps.\n\n# Returns\n\n`true` if the loop should stop, `false` to continue.\n\n# Examples\n\n```\nuse forge_agent::loop_control::AgentStopCondition;\n\nlet stop = AgentStopCondition::MaxSteps(5);\nassert!(!stop.should_stop(4, 0));\nassert!(stop.should_stop(5, 0));\nassert!(stop.should_stop(6, 0));\n```"
        },
        {
          "name": "::AgentStopCondition::description",
          "line": 138,
          "signature": "pub fn description(&self) -> String;",
          "documentation": "Returns a human-readable description of this stop condition.\n\nUsed for logging and error messages.\n\n# Returns\n\nA string describing the stop condition type and its threshold.\n\n# Examples\n\n```\nuse forge_agent::loop_control::AgentStopCondition;\n\nlet stop = AgentStopCondition::MaxSteps(10);\nassert_eq!(stop.description(), \"max_steps(10)\");\n\nlet stop = AgentStopCondition::MaxTokens(5000);\nassert_eq!(stop.description(), \"max_tokens(5000)\");\n```"
        },
        {
          "name": "::StopWhen",
          "line": 191,
          "signature": "pub trait StopWhen: Send + Sync {\n    /// Determines whether the agent's tool loop should stop.\n    ///\n    /// # Arguments\n    ///\n    /// * `messages` - The current conversation history.\n    /// * `step_count` - The number of tool loop steps completed (1-indexed).\n    ///\n    /// # Returns\n    ///\n    /// `true` if the loop should terminate, `false` to continue.\n    fn should_stop(&self, messages: &[ModelMessage], step_count: u32) -> bool;\n}",
          "documentation": "A trait-based stop condition for controlling the agent's tool loop.\n\n`StopWhen` provides a richer interface than [`AgentStopCondition`] by\nreceiving the full message history and step count, enabling content-aware\nstop decisions.\n\n# ANVIL Spec \u00a79.2\n\nThe agent execution loop supports pluggable stop conditions. `StopWhen`\nis the trait-based interface; `AgentStopCondition` is the simpler enum\nalternative. Both are supported.\n\n# Thread Safety\n\nImplementors must be `Send + Sync` for use in async agent contexts.\n\n# Examples\n\n```\nuse forge_agent::loop_control::StopWhen;\nuse forge_core::message::ModelMessage;\n\nstruct StopAfterFiveSteps;\n\nimpl StopWhen for StopAfterFiveSteps {\n    fn should_stop(&self, _messages: &[ModelMessage], step_count: u32) -> bool {\n        step_count >= 5\n    }\n}\n\nlet stop = StopAfterFiveSteps;\nassert!(!stop.should_stop(&[], 4));\nassert!(stop.should_stop(&[], 5));\n```"
        },
        {
          "name": "::StopWhenTextGenerated",
          "line": 225,
          "signature": "pub struct StopWhenTextGenerated;",
          "documentation": "Stops when the agent produces a text-only response (no tool calls).\n\nThis is the default stop condition \u2014 the loop naturally ends when the\nmodel responds with text instead of tool calls.\n\n# Examples\n\n```\nuse forge_agent::loop_control::{StopWhen, StopWhenTextGenerated};\nuse forge_core::message::{ModelMessage, Role};\n\nlet stop = StopWhenTextGenerated;\nlet messages = vec![\n    ModelMessage::text(Role::User, \"Hello\"),\n    ModelMessage::text(Role::Assistant, \"Hi there!\"),\n];\n// This checks message content \u2014 in practice the tool loop handles\n// this by inspecting tool_calls on the response, not via StopWhen.\nassert!(!stop.should_stop(&messages, 1));\n```"
        },
        {
          "name": "::StopWhenMaxSteps",
          "line": 248,
          "signature": "pub struct StopWhenMaxSteps(pub u32);",
          "documentation": "Stops when the step count reaches or exceeds the configured maximum.\n\n# Examples\n\n```\nuse forge_agent::loop_control::{StopWhen, StopWhenMaxSteps};\nuse forge_core::message::ModelMessage;\n\nlet stop = StopWhenMaxSteps(10);\nassert!(!stop.should_stop(&[], 9));\nassert!(stop.should_stop(&[], 10));\nassert!(stop.should_stop(&[], 11));\n```"
        },
        {
          "name": "::StopWhenToolCalled",
          "line": 272,
          "signature": "pub struct StopWhenToolCalled {\n\n}",
          "documentation": "Stops when a specific tool has been called in the conversation.\n\nInspects the message history for any tool call matching the configured\ntool name.\n\n# Examples\n\n```\nuse forge_agent::loop_control::{StopWhen, StopWhenToolCalled};\nuse forge_core::message::{ModelMessage, Role};\n\nlet stop = StopWhenToolCalled::new(\"submit_answer\");\n// No tool calls in the messages\nlet messages = vec![ModelMessage::text(Role::User, \"Hello\")];\nassert!(!stop.should_stop(&messages, 1));\n```"
        },
        {
          "name": "::StopWhenToolCalled::new",
          "line": 282,
          "signature": "pub fn new(tool_name: impl Into<String>) -> Self;",
          "documentation": "Creates a new stop condition that triggers when the named tool is called.\n\n# Arguments\n\n* `tool_name` - The name of the tool to watch for."
        },
        {
          "name": "::StopWhenCustom",
          "line": 317,
          "signature": "pub struct StopWhenCustom {\n\n}",
          "documentation": "Stops when a custom predicate returns `true`.\n\nThe predicate receives the full message history and step count,\nallowing content-aware stop decisions.\n\n# Examples\n\n```\nuse forge_agent::loop_control::{StopWhen, StopWhenCustom};\nuse forge_core::message::ModelMessage;\n\n// Stop when we have more than 20 messages\nlet stop = StopWhenCustom::new(|messages, _step| messages.len() > 20);\nassert!(!stop.should_stop(&[], 1));\n```"
        },
        {
          "name": "::StopWhenCustom::new",
          "line": 328,
          "signature": "pub fn new<F>(predicate: F) -> Self\n    where\n        F: Fn(&[ModelMessage], u32) -> bool + Send + Sync + 'static,;",
          "documentation": "Creates a new custom stop condition from a closure.\n\n# Arguments\n\n* `predicate` - A closure that receives messages and step count,\n  returning `true` to stop."
        },
        {
          "name": "::PrepareStep",
          "line": 387,
          "signature": "#[async_trait]\npub trait PrepareStep: Send + Sync {\n    /// Modifies the message list before the next LLM call.\n    ///\n    /// # Arguments\n    ///\n    /// * `messages` - The mutable message list that will be sent to the model.\n    ///   Implementors may add, remove, or modify messages.\n    /// * `step` - The current step number (1-indexed). Step 1 is the first call.\n    ///\n    /// # Returns\n    ///\n    /// `Ok(())` on success, or a [`ForgeAgentError`](crate::error::ForgeAgentError)\n    /// if preparation fails (which aborts the tool loop).\n    ///\n    /// # Errors\n    ///\n    /// Returning an error aborts the tool loop and propagates the error to\n    /// the caller.\n    async fn prepare(&self, messages: &mut Vec<ModelMessage>, step: u32) -> ForgeAgentResult<()>;\n}",
          "documentation": "A hook that runs before each LLM call in the tool loop.\n\nImplementors can modify the message list before it is sent to the model.\nThis enables prompt injection, context trimming, memory retrieval, and\nother pre-processing steps.\n\n# ANVIL Spec SS7.1\n\nPre-step hooks are optional extensions to the agent execution loop. They\nexecute synchronously before each inference call.\n\n# Thread Safety\n\nImplementors must be `Send + Sync` for use in async contexts.\n\n# Examples\n\n```\nuse async_trait::async_trait;\nuse forge_agent::loop_control::PrepareStep;\nuse forge_agent::error::ForgeAgentResult;\nuse forge_core::message::{ModelMessage, Role};\n\nstruct InjectTimestamp;\n\n#[async_trait]\nimpl PrepareStep for InjectTimestamp {\n    async fn prepare(&self, messages: &mut Vec<ModelMessage>, step: u32) -> ForgeAgentResult<()> {\n        let note = format!(\"[Step {step}] Processing...\");\n        messages.push(ModelMessage::text(Role::System, note));\n        Ok(())\n    }\n}\n```"
        },
        {
          "name": "::NoOpPrepare",
          "line": 427,
          "signature": "pub struct NoOpPrepare;",
          "documentation": "A no-op [`PrepareStep`] implementation that does nothing.\n\nUsed as the default when no pre-step processing is needed.\n\n# Examples\n\n```\nuse forge_agent::loop_control::NoOpPrepare;\nuse forge_agent::loop_control::PrepareStep;\nuse forge_core::message::ModelMessage;\n\n# tokio::runtime::Runtime::new().unwrap().block_on(async {\nlet noop = NoOpPrepare;\nlet mut messages = vec![];\nlet result = noop.prepare(&mut messages, 1).await;\nassert!(result.is_ok());\nassert!(messages.is_empty());\n# });\n```"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-agent/src/messaging.rs",
      "sha256": "626d88e8fbf1c56d30fc05a883e4e1887b61ce3eb9f9624f263173e6f654e4ad",
      "artifactSha256": "3f9256b9ce7fad73e5d5583f66617a462b0c65d5131def2f18f251eb712321b2",
      "url": "/reference/source/forge-rs/crates/forge-agent/src/messaging.rs.txt",
      "declarations": [
        {
          "name": "::AgentMessage",
          "line": 71,
          "signature": "#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct AgentMessage {\n\n}",
          "documentation": "A typed message exchanged between agents.\n\n`AgentMessage` carries a payload (text content) along with sender and\nrecipient identifiers. Messages are immutable after creation.\n\n# ANVIL Spec SS7.2\n\nInter-agent messages include sender and recipient identity for audit\ntrail purposes. The payload is a free-form text string that the\nreceiving agent interprets.\n\n# Examples\n\n```\nuse forge_agent::messaging::AgentMessage;\n\nlet msg = AgentMessage::text(\"coordinator\", \"analyst\", \"Summarize the data.\");\nassert_eq!(msg.sender(), \"coordinator\");\nassert_eq!(msg.recipient(), \"analyst\");\nassert_eq!(msg.payload(), \"Summarize the data.\");\nassert_eq!(msg.kind(), \"text\");\n```"
        },
        {
          "name": "::AgentMessage::text",
          "line": 107,
          "signature": "pub fn text(\n        sender: impl Into<String>,\n        recipient: impl Into<String>,\n        payload: impl Into<String>,\n    ) -> Self;",
          "documentation": "Creates a new text message between agents.\n\n# Arguments\n\n* `sender` - The sending agent's name or identifier.\n* `recipient` - The recipient agent's name or identifier.\n* `payload` - The text content of the message.\n\n# Returns\n\nA new `AgentMessage` with kind \"text\".\n\n# Examples\n\n```\nuse forge_agent::messaging::AgentMessage;\n\nlet msg = AgentMessage::text(\"a\", \"b\", \"Hello\");\nassert_eq!(msg.kind(), \"text\");\nassert_eq!(msg.payload(), \"Hello\");\n```"
        },
        {
          "name": "::AgentMessage::result",
          "line": 140,
          "signature": "pub fn result(\n        sender: impl Into<String>,\n        recipient: impl Into<String>,\n        payload: impl Into<String>,\n    ) -> Self;",
          "documentation": "Creates a new result message (agent returning output to another).\n\n# Arguments\n\n* `sender` - The sending agent's name or identifier.\n* `recipient` - The recipient agent's name or identifier.\n* `payload` - The result content.\n\n# Returns\n\nA new `AgentMessage` with kind \"result\".\n\n# Examples\n\n```\nuse forge_agent::messaging::AgentMessage;\n\nlet msg = AgentMessage::result(\"worker\", \"orchestrator\", \"Task complete.\");\nassert_eq!(msg.kind(), \"result\");\n```"
        },
        {
          "name": "::AgentMessage::error",
          "line": 173,
          "signature": "pub fn error(\n        sender: impl Into<String>,\n        recipient: impl Into<String>,\n        payload: impl Into<String>,\n    ) -> Self;",
          "documentation": "Creates a new error message.\n\n# Arguments\n\n* `sender` - The sending agent's name or identifier.\n* `recipient` - The recipient agent's name or identifier.\n* `payload` - The error description.\n\n# Returns\n\nA new `AgentMessage` with kind \"error\".\n\n# Examples\n\n```\nuse forge_agent::messaging::AgentMessage;\n\nlet msg = AgentMessage::error(\"worker\", \"orchestrator\", \"Tool execution failed.\");\nassert_eq!(msg.kind(), \"error\");\n```"
        },
        {
          "name": "::AgentMessage::control",
          "line": 207,
          "signature": "pub fn control(\n        sender: impl Into<String>,\n        recipient: impl Into<String>,\n        payload: impl Into<String>,\n    ) -> Self;",
          "documentation": "Creates a new control message (lifecycle signals, coordination).\n\n# Arguments\n\n* `sender` - The sending agent's name or identifier.\n* `recipient` - The recipient agent's name or identifier.\n* `payload` - The control signal content.\n\n# Returns\n\nA new `AgentMessage` with kind \"control\".\n\n# Examples\n\n```\nuse forge_agent::messaging::AgentMessage;\n\nlet msg = AgentMessage::control(\"orchestrator\", \"worker\", \"shutdown\");\nassert_eq!(msg.kind(), \"control\");\nassert_eq!(msg.payload(), \"shutdown\");\n```"
        },
        {
          "name": "::AgentMessage::sender",
          "line": 221,
          "signature": "pub fn sender(&self) -> &str;",
          "documentation": "Returns the sender's name or identifier."
        },
        {
          "name": "::AgentMessage::recipient",
          "line": 226,
          "signature": "pub fn recipient(&self) -> &str;",
          "documentation": "Returns the recipient's name or identifier."
        },
        {
          "name": "::AgentMessage::payload",
          "line": 231,
          "signature": "pub fn payload(&self) -> &str;",
          "documentation": "Returns the message payload."
        },
        {
          "name": "::AgentMessage::kind",
          "line": 236,
          "signature": "pub fn kind(&self) -> &str;",
          "documentation": "Returns the message kind (\"text\", \"result\", \"error\", \"control\")."
        },
        {
          "name": "::AgentChannelSender",
          "line": 264,
          "signature": "#[derive(Debug, Clone)]\npub struct AgentChannelSender {\n\n}",
          "documentation": "The sending half of an agent channel.\n\nThis wraps a `tokio::mpsc::Sender` and provides a typed interface for\nsending [`AgentMessage`] values to the channel.\n\n# Thread Safety\n\n`AgentChannelSender` is `Clone + Send + Sync`, so it can be shared\nacross multiple agents or tasks.\n\n# Examples\n\n```\nuse forge_agent::messaging::{AgentChannel, AgentMessage};\n\n# tokio::runtime::Runtime::new().unwrap().block_on(async {\nlet (tx, mut rx) = AgentChannel::new(8);\nlet msg = AgentMessage::text(\"a\", \"b\", \"hello\");\nlet result = tx.send(msg).await;\nassert!(result.is_ok());\n# });\n```"
        },
        {
          "name": "::AgentChannelSender::send",
          "line": 298,
          "signature": "pub async fn send(&self, message: AgentMessage) -> ForgeAgentResult<()>;",
          "documentation": "Sends a message through the channel.\n\nThis operation waits until there is capacity in the channel. If the\nreceiver has been dropped, the send fails.\n\n# Arguments\n\n* `message` - The message to send.\n\n# Returns\n\n`Ok(())` if the message was sent, or a [`ForgeAgentError::MessageError`]\nif the receiver has been dropped.\n\n# Errors\n\nReturns [`ForgeAgentError::MessageError`] if the receiver has been dropped.\n\n# Examples\n\n```\nuse forge_agent::messaging::{AgentChannel, AgentMessage};\n\n# tokio::runtime::Runtime::new().unwrap().block_on(async {\nlet (tx, _rx) = AgentChannel::new(4);\nlet result = tx.send(AgentMessage::text(\"a\", \"b\", \"hi\")).await;\nassert!(result.is_ok());\n# });\n```"
        },
        {
          "name": "::AgentChannelSender::try_send",
          "line": 333,
          "signature": "pub fn try_send(&self, message: AgentMessage) -> ForgeAgentResult<()>;",
          "documentation": "Attempts to send a message without waiting.\n\nReturns immediately. If the channel is full or the receiver is dropped,\nthe send fails.\n\n# Arguments\n\n* `message` - The message to send.\n\n# Returns\n\n`Ok(())` if the message was sent, or a [`ForgeAgentError::MessageError`]\nif the channel is full or the receiver is dropped.\n\n# Errors\n\nReturns [`ForgeAgentError::MessageError`] if the channel is full or closed.\n\n# Examples\n\n```\nuse forge_agent::messaging::{AgentChannel, AgentMessage};\n\nlet (tx, _rx) = AgentChannel::new(1);\nlet result = tx.try_send(AgentMessage::text(\"a\", \"b\", \"fast\"));\nassert!(result.is_ok());\n```"
        },
        {
          "name": "::AgentChannelReceiver",
          "line": 361,
          "signature": "#[derive(Debug)]\npub struct AgentChannelReceiver {\n\n}",
          "documentation": "The receiving half of an agent channel.\n\nThis wraps a `tokio::mpsc::Receiver` and provides a typed interface\nfor receiving [`AgentMessage`] values from the channel.\n\n# Examples\n\n```\nuse forge_agent::messaging::{AgentChannel, AgentMessage};\n\n# tokio::runtime::Runtime::new().unwrap().block_on(async {\nlet (tx, mut rx) = AgentChannel::new(8);\ntx.send(AgentMessage::text(\"a\", \"b\", \"hello\")).await.unwrap();\n\nlet msg = rx.recv().await;\nassert!(msg.is_some());\n# });\n```"
        },
        {
          "name": "::AgentChannelReceiver::recv",
          "line": 388,
          "signature": "pub async fn recv(&mut self) -> Option<AgentMessage>;",
          "documentation": "Receives the next message from the channel.\n\nWaits until a message is available. Returns `None` if all senders\nhave been dropped (channel is closed).\n\n# Returns\n\n`Some(message)` if a message was received, or `None` if the channel\nis closed.\n\n# Examples\n\n```\nuse forge_agent::messaging::{AgentChannel, AgentMessage};\n\n# tokio::runtime::Runtime::new().unwrap().block_on(async {\nlet (tx, mut rx) = AgentChannel::new(4);\ntx.send(AgentMessage::text(\"a\", \"b\", \"msg\")).await.unwrap();\nlet received = rx.recv().await;\nassert!(received.is_some());\n# });\n```"
        },
        {
          "name": "::AgentChannelReceiver::try_recv",
          "line": 411,
          "signature": "pub fn try_recv(&mut self) -> Option<AgentMessage>;",
          "documentation": "Tries to receive a message without waiting.\n\nReturns immediately. If no message is available, returns `None`.\n\n# Returns\n\n`Some(message)` if a message was available, or `None` if the channel\nis empty.\n\n# Examples\n\n```\nuse forge_agent::messaging::{AgentChannel, AgentMessage};\n\nlet (tx, mut rx) = AgentChannel::new(4);\ntx.try_send(AgentMessage::text(\"a\", \"b\", \"quick\")).unwrap();\nlet result = rx.try_recv();\nassert!(result.is_some());\n```"
        },
        {
          "name": "::AgentChannel",
          "line": 448,
          "signature": "pub struct AgentChannel;",
          "documentation": "Factory for creating agent communication channels.\n\n`AgentChannel` provides a static `new()` method that creates a bounded\n`(sender, receiver)` pair. The channel has backpressure: when the buffer\nis full, senders wait until there is capacity.\n\n# ANVIL Spec SS7.2\n\nAgent channels are the communication backbone for multi-agent workflows.\nThey are bounded to prevent unbounded memory growth, and typed to ensure\nmessage integrity.\n\n# Examples\n\n```\nuse forge_agent::messaging::{AgentChannel, AgentMessage};\n\n# tokio::runtime::Runtime::new().unwrap().block_on(async {\nlet (tx, mut rx) = AgentChannel::new(16);\n\n// Clone the sender for another agent\nlet tx2 = tx.clone();\n\ntx.send(AgentMessage::text(\"agent-a\", \"agent-b\", \"Hello!\")).await.unwrap();\ntx2.send(AgentMessage::text(\"agent-c\", \"agent-b\", \"Hi!\")).await.unwrap();\n\nlet msg1 = rx.recv().await.unwrap();\nlet msg2 = rx.recv().await.unwrap();\nassert_eq!(msg1.sender(), \"agent-a\");\nassert_eq!(msg2.sender(), \"agent-c\");\n# });\n```"
        },
        {
          "name": "::AgentChannel::new",
          "line": 472,
          "signature": "#[allow(clippy::new_ret_no_self)]\npub fn new(capacity: usize) -> (AgentChannelSender, AgentChannelReceiver);",
          "documentation": "Creates a new bounded agent channel.\n\n# Arguments\n\n* `capacity` - The maximum number of messages that can be buffered.\n  Must be at least 1. If 0 is provided, it is clamped to 1.\n\n# Returns\n\nA `(sender, receiver)` pair. The sender can be cloned and shared\nacross multiple agents. The receiver is single-consumer.\n\n# Examples\n\n```\nuse forge_agent::messaging::AgentChannel;\n\nlet (tx, rx) = AgentChannel::new(32);\n// tx can be cloned: let tx2 = tx.clone();\n```"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-agent/src/observer.rs",
      "sha256": "6464c48499058684caf9babfb3984946a35430473c15536e6ddb29a4be261d10",
      "artifactSha256": "5a0133e26a188ab6f61c25a08a119d5dcd99d1dc2eb06d6faa925fd7ad78481b",
      "url": "/reference/source/forge-rs/crates/forge-agent/src/observer.rs.txt",
      "declarations": [
        {
          "name": "::AgentLoopObserver",
          "line": 46,
          "signature": "#[async_trait]\npub trait AgentLoopObserver: Send + Sync {\n    /// Called at the start of each tool loop turn.\n    ///\n    /// # Arguments\n    ///\n    /// * `turn` - The turn number (1-indexed).\n    async fn on_turn_start(&self, _turn: u32) ;\n\n    /// Called at the end of each tool loop turn.\n    ///\n    /// # Arguments\n    ///\n    /// * `turn` - The turn number (1-indexed).\n    /// * `usage` - Cumulative token usage after this turn.\n    async fn on_turn_end(&self, _turn: u32, _usage: Usage) ;\n\n    /// Called when the model produces a text delta (during streaming).\n    ///\n    /// # Arguments\n    ///\n    /// * `text` - The text fragment.\n    async fn on_text_delta(&self, _text: &str) ;\n\n    /// Called when the model starts a tool call.\n    ///\n    /// # Arguments\n    ///\n    /// * `tool_call` - The tool call being initiated.\n    async fn on_tool_call_start(&self, _tool_call: &ToolCall) ;\n\n    /// Called when a tool call completes.\n    ///\n    /// Legacy hook -- prefer [`on_tool_invocation`](Self::on_tool_invocation) for\n    /// per-tool latency, status (succeeded / failed / authorization-denied /\n    /// not-found), and the tool name. This hook is preserved for backward\n    /// compatibility and continues to fire alongside `on_tool_invocation`.\n    ///\n    /// # Arguments\n    ///\n    /// * `tool_call_id` - The tool call ID.\n    /// * `result` - The result content.\n    /// * `is_error` - Whether the tool execution failed.\n    async fn on_tool_call_end(&self, _tool_call_id: &str, _result: &str, _is_error: bool) ;\n\n    /// Called when a tool call completes, with the full invocation record.\n    ///\n    /// Symmetric counterpart to [`on_tool_call_start`](Self::on_tool_call_start)\n    /// -- this hook receives the tool name, wall-clock duration, and the typed\n    /// `ToolInvocationStatus` so observers can build per-tool latency\n    /// histograms, structured audit entries, or richer UI states without\n    /// having to maintain their own start-time bookkeeping.\n    ///\n    /// Default implementation is a no-op so existing observers compile\n    /// unchanged. The streaming tool loop fires both this and\n    /// [`on_tool_call_end`](Self::on_tool_call_end) for every invocation.\n    ///\n    /// # Arguments\n    ///\n    /// * `record` - The complete invocation record.\n    async fn on_tool_invocation(&self, _record: &ToolInvocationRecord) ;\n\n    /// Called when a model inference call completes.\n    ///\n    /// The record carries model/provider ids, token counts, latency, outcome,\n    /// and governed prompt/completion refs. It does not carry raw prompt or\n    /// completion text.\n    ///\n    /// # Arguments\n    ///\n    /// * `record` - The complete model inference record.\n    async fn on_model_inference_completed(&self, _record: &ModelInferenceRecord) ;\n\n    /// Called when a parent agent delegates work to a sub-agent.\n    ///\n    /// The record carries child agent/run identifiers and governed refs for\n    /// instruction or handoff context.\n    ///\n    /// # Arguments\n    ///\n    /// * `record` - The delegation record.\n    async fn on_subagent_delegation_started(&self, _record: &SubAgentDelegationRecord) ;\n\n    /// Called when a stream chunk is received.\n    ///\n    /// # Arguments\n    ///\n    /// * `chunk` - The stream chunk.\n    async fn on_stream_chunk(&self, _chunk: &StreamChunk) ;\n\n    /// Called when the agent loop completes successfully.\n    ///\n    /// # Arguments\n    ///\n    /// * `final_message` - The final assistant message.\n    /// * `total_turns` - Total number of turns executed.\n    /// * `total_usage` - Total token usage across all turns.\n    async fn on_complete(\n        &self,\n        _final_message: &ModelMessage,\n        _total_turns: u32,\n        _total_usage: Usage,\n    ) ;\n\n    /// Called when the agent loop encounters an error.\n    ///\n    /// # Arguments\n    ///\n    /// * `error` - A human-readable error description.\n    /// * `turn` - The turn in which the error occurred.\n    async fn on_error(&self, _error: &str, _turn: u32) ;\n\n    /// Called when the agent loop is stopped by a stop condition.\n    ///\n    /// # Arguments\n    ///\n    /// * `reason` - Why the loop stopped.\n    /// * `turn` - The turn at which the loop stopped.\n    async fn on_stopped(&self, _reason: FinishReason, _turn: u32) ;\n}",
          "documentation": "Observer for agent loop events.\n\nImplementors receive callbacks at key points during the agent's tool loop.\nAll methods have default no-op implementations, so observers only need to\noverride the events they care about.\n\n# Thread Safety\n\nImplementors must be `Send + Sync` for use in async contexts.\n\n# Examples\n\n```\nuse forge_agent::observer::AgentLoopObserver;\nuse async_trait::async_trait;\n\nstruct PrintObserver;\n\n#[async_trait]\nimpl AgentLoopObserver for PrintObserver {\n    async fn on_turn_start(&self, turn: u32) {\n        println!(\"Starting turn {turn}\");\n    }\n}\n```"
        },
        {
          "name": "::NoOpObserver",
          "line": 170,
          "signature": "pub struct NoOpObserver;",
          "documentation": "A no-op observer that discards all events.\n\nUsed as the default when no monitoring is needed."
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-agent/src/streaming_tool_loop.rs",
      "sha256": "df84d3a0a4f00e0e559a1a78e877c1f2d8fe9db08ced25b9be82146285e098bb",
      "artifactSha256": "9f10779b03086e4ca755a72628b499a591b1bc2b1f476a18f88815e1fb0e1f36",
      "url": "/reference/source/forge-rs/crates/forge-agent/src/streaming_tool_loop.rs.txt",
      "declarations": [
        {
          "name": "::StreamingLoopConfig",
          "line": 61,
          "signature": "#[derive(Debug, Clone)]\npub struct StreamingLoopConfig {\n/// Maximum turns before forced termination.\n\npub max_turns: u32,\n/// Context pruning threshold (fraction of max_context_tokens).\n\npub context_threshold: f64,\n/// Context pruning strategy.\n\npub pruning_strategy: PruningStrategy,\n/// Model's maximum context window size.\n\npub max_context_tokens: u64\n}",
          "documentation": "Configuration for the streaming tool loop."
        },
        {
          "name": "::StreamingToolLoopAgent",
          "line": 95,
          "signature": "pub struct StreamingToolLoopAgent {\n\n}",
          "documentation": "An agent that uses streaming inference with real-time observer callbacks.\n\nThis is the recommended agent implementation for any use case that needs\nlive output: dashboards, TUIs, founding pipeline, interactive sessions.\n\n# Observer hot-swap\n\nThe active observer is held behind a [`RwLock`] so callers can rotate\nobservers per turn without rebuilding the agent. Use\n[`set_observer`](Self::set_observer) / [`clear_observer`](Self::clear_observer)\non a long-lived `Arc<StreamingToolLoopAgent>` instead of the consuming\nbuilder [`with_observer`](Self::with_observer)."
        },
        {
          "name": "::StreamingToolLoopAgent::new",
          "line": 111,
          "signature": "pub fn new(\n        config: AgentConfig,\n        loop_config: StreamingLoopConfig,\n        model: Arc<dyn LanguageModel>,\n        tool_registry: ToolRegistry,\n        approval: Arc<dyn ApprovalHandler>,\n    ) -> Self;",
          "documentation": ""
        },
        {
          "name": "::StreamingToolLoopAgent::with_observer",
          "line": 143,
          "signature": "pub fn with_observer(self, observer: Arc<dyn AgentLoopObserver>) -> Self;",
          "documentation": "Builder shim that sets the observer and returns `self`.\n\nMost callers should prefer [`set_observer`](Self::set_observer) on a\nlong-lived agent, which doesn't consume the agent and supports per-turn\nobserver rotation."
        },
        {
          "name": "::StreamingToolLoopAgent::set_observer",
          "line": 154,
          "signature": "pub fn set_observer(&self, observer: Arc<dyn AgentLoopObserver>);",
          "documentation": "Atomically swap the active observer through a shared reference.\n\nUseful when one long-lived `Arc<StreamingToolLoopAgent>` runs many turns\nand each turn needs its own observer (e.g., per-turn tool latency\nhistograms or per-request UI streams). The previous observer is dropped\nonce any in-flight `observer()` snapshot completes."
        },
        {
          "name": "::StreamingToolLoopAgent::clear_observer",
          "line": 166,
          "signature": "pub fn clear_observer(&self);",
          "documentation": "Reset the observer slot to a no-op observer.\n\nEquivalent to `set_observer(Arc::new(NoOpObserver))` but spelled out\nfor clarity at call sites that explicitly want to detach observation."
        },
        {
          "name": "::StreamingToolLoopAgent::observer",
          "line": 176,
          "signature": "pub fn observer(&self) -> Arc<dyn AgentLoopObserver>;",
          "documentation": "Returns a snapshot of the current observer.\n\nThe returned `Arc` is independent of the slot, so the caller may hold\nit across observer swaps without affecting subsequent turns. Used\ninternally by the loop and exposed for callers that want to fire\ncustom callbacks against the active observer."
        },
        {
          "name": "::StreamingToolLoopAgent::enqueue_interjection",
          "line": 191,
          "signature": "pub fn enqueue_interjection(&self, text: impl Into<String>);",
          "documentation": "Queue a live interjection for the next model turn.\n\nThis is intentionally turn-boundary delivery: an interjection sent\nwhile a model call or tool call is in flight is appended to the\nconversation before the next LLM request. That keeps providers and\ntools cancellable via their existing controls while giving long-running\nautonomous loops a safe way to accept new instructions."
        },
        {
          "name": "::StreamingToolLoopAgent::enqueue_interjection_message",
          "line": 204,
          "signature": "pub fn enqueue_interjection_message(&self, message: ModelMessage);",
          "documentation": "Queue a fully-formed message for the next model turn.\n\nMost callers should prefer [`enqueue_interjection`](Self::enqueue_interjection).\nThis lower-level hook exists for adapters that need to preserve richer\nrole/content formatting."
        },
        {
          "name": "::StreamingToolLoopAgent::model",
          "line": 224,
          "signature": "pub fn model(&self) -> &Arc<dyn LanguageModel>;",
          "documentation": "Returns a reference to the underlying language model.\n\nUseful for diagnostics, smoke tests, or building a sibling streaming\nagent that shares the same model instance."
        },
        {
          "name": "::StreamingToolLoopAgent::with_generate_options",
          "line": 229,
          "signature": "pub fn with_generate_options(mut self, options: GenerateOptions) -> Self;",
          "documentation": "Set generation options."
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-agent/src/subagent.rs",
      "sha256": "1073dd6b8f60a127b7ebebdbe424c14dcd76f13f95103aa5352605503d8f90e5",
      "artifactSha256": "844bee930b526e120eedb1b35afa6c0f3b7d4b25a23856b94f014be2949d5c45",
      "url": "/reference/source/forge-rs/crates/forge-agent/src/subagent.rs.txt",
      "declarations": [
        {
          "name": "::SubAgentConfig",
          "line": 81,
          "signature": "#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct SubAgentConfig {\n\n}",
          "documentation": "Configuration for creating a sub-agent from a parent agent.\n\n`SubAgentConfig` specifies which tools from the parent's tool set the\nchild should have access to, along with child-specific overrides for\nsystem prompt and step limits.\n\n# ANVIL Spec SS11.2\n\nSub-agent capabilities must be a subset of the parent's capabilities.\nThe `tool_names` field acts as a filter: only tools whose names appear\nin the parent's `AgentConfig::tools()` are included.\n\n# Examples\n\n```\nuse forge_agent::subagent::SubAgentConfig;\n\nlet config = SubAgentConfig::new(\"data-fetcher\")\n    .with_tool_names(vec![\"http_get\".to_string(), \"parse_json\".to_string()])\n    .with_system_prompt(\"You are a data fetching assistant.\")\n    .with_max_steps(5);\n\nassert_eq!(config.name(), \"data-fetcher\");\nassert_eq!(config.tool_names().len(), 2);\nassert_eq!(config.max_steps(), Some(5));\n```"
        },
        {
          "name": "::SubAgentConfig::new",
          "line": 128,
          "signature": "pub fn new(name: impl Into<String>) -> Self;",
          "documentation": "Creates a new `SubAgentConfig` with the given name.\n\nBy default, the child inherits all parent tools, the parent's system\nprompt, and the parent's max_steps.\n\n# Arguments\n\n* `name` - The child agent's name.\n\n# Returns\n\nA new `SubAgentConfig` with default inheritance settings.\n\n# Examples\n\n```\nuse forge_agent::subagent::SubAgentConfig;\n\nlet config = SubAgentConfig::new(\"worker\");\nassert_eq!(config.name(), \"worker\");\nassert!(config.tool_names().is_empty());\nassert!(config.system_prompt().is_none());\nassert!(config.max_steps().is_none());\n```"
        },
        {
          "name": "::SubAgentConfig::with_tool_names",
          "line": 160,
          "signature": "pub fn with_tool_names(mut self, names: Vec<String>) -> Self;",
          "documentation": "Sets the tool names the child is allowed to use.\n\nThese names are matched against the parent's tool definitions.\nOnly tools whose names appear in both this list AND the parent's\ntools will be available to the child.\n\n# Arguments\n\n* `names` - Tool names to filter by.\n\n# Returns\n\nThe modified `SubAgentConfig` (builder pattern).\n\n# Examples\n\n```\nuse forge_agent::subagent::SubAgentConfig;\n\nlet config = SubAgentConfig::new(\"reader\")\n    .with_tool_names(vec![\"read_file\".to_string()]);\nassert_eq!(config.tool_names(), &[\"read_file\"]);\n```"
        },
        {
          "name": "::SubAgentConfig::with_system_prompt",
          "line": 184,
          "signature": "pub fn with_system_prompt(mut self, prompt: impl Into<String>) -> Self;",
          "documentation": "Sets the system prompt override for the child agent.\n\n# Arguments\n\n* `prompt` - The child's system prompt.\n\n# Returns\n\nThe modified `SubAgentConfig` (builder pattern).\n\n# Examples\n\n```\nuse forge_agent::subagent::SubAgentConfig;\n\nlet config = SubAgentConfig::new(\"helper\")\n    .with_system_prompt(\"You are a specialized helper.\");\nassert_eq!(config.system_prompt(), Some(\"You are a specialized helper.\"));\n```"
        },
        {
          "name": "::SubAgentConfig::with_max_steps",
          "line": 207,
          "signature": "pub fn with_max_steps(mut self, max: u32) -> Self;",
          "documentation": "Sets the max_steps override for the child agent.\n\n# Arguments\n\n* `max` - The maximum number of tool loop steps for the child.\n\n# Returns\n\nThe modified `SubAgentConfig` (builder pattern).\n\n# Examples\n\n```\nuse forge_agent::subagent::SubAgentConfig;\n\nlet config = SubAgentConfig::new(\"worker\").with_max_steps(3);\nassert_eq!(config.max_steps(), Some(3));\n```"
        },
        {
          "name": "::SubAgentConfig::name",
          "line": 213,
          "signature": "pub fn name(&self) -> &str;",
          "documentation": "Returns the child agent's name."
        },
        {
          "name": "::SubAgentConfig::tool_names",
          "line": 220,
          "signature": "pub fn tool_names(&self) -> &[String];",
          "documentation": "Returns the tool names the child is allowed to use.\n\nAn empty slice means the child inherits all parent tools."
        },
        {
          "name": "::SubAgentConfig::system_prompt",
          "line": 225,
          "signature": "pub fn system_prompt(&self) -> Option<&str>;",
          "documentation": "Returns the system prompt override, if set."
        },
        {
          "name": "::SubAgentConfig::max_steps",
          "line": 230,
          "signature": "pub fn max_steps(&self) -> Option<u32>;",
          "documentation": "Returns the max_steps override, if set."
        },
        {
          "name": "::SubAgentDelegationContext",
          "line": 237,
          "signature": "#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\npub struct SubAgentDelegationContext {\n/// Optional stable child agent id. Falls back to the child's configured DID\n\n/// or child name when omitted.\n\npub subagent_id: Option<String>,\n/// Host-assigned run id for the delegated child agent.\n\npub subagent_run_id: String,\n/// Optional summary of why the delegation happened.\n\npub delegation_reason: Option<String>,\n/// Governed artifact ref for delegated instructions.\n\npub instruction_ref: Option<String>,\n/// Capability refs granted to the child.\n\npub capability_refs: Vec<String>,\n/// Governed artifact ref for handoff state.\n\npub handoff_ref: Option<String>\n}",
          "documentation": "Host-supplied context for emitting a sub-agent delegation observer event."
        },
        {
          "name": "::create_subagent",
          "line": 316,
          "signature": "pub fn create_subagent(\n    parent_config: &AgentConfig,\n    sub_config: SubAgentConfig,\n    model: Arc<dyn LanguageModel>,\n    tool_registry: ToolRegistry,\n    approval: Arc<dyn ApprovalHandler>,\n) -> ForgeAgentResult<ToolLoopAgent>;",
          "documentation": "Creates a sub-agent from a parent agent's configuration.\n\nThe sub-agent is a new [`ToolLoopAgent`] with:\n- A narrowed set of tools (filtered by `SubAgentConfig::tool_names`).\n- An optional system prompt override.\n- An optional max_steps override.\n- Its own health profile and lifecycle state (both start fresh).\n\n# ANVIL Spec SS11.2\n\nSub-agent delegation must satisfy capability narrowing: the child's tool\nset is always a subset of (or equal to) the parent's tool set. This\nfunction enforces that constraint.\n\n# Arguments\n\n* `parent_config` - The parent agent's configuration. Used to determine\n  the parent's model and available tools.\n* `sub_config` - The sub-agent configuration specifying the child's name,\n  tool restrictions, and optional overrides.\n* `model` - The language model for the child to use (may be the same as\n  the parent's model or a different one).\n* `tool_registry` - The tool registry for the child agent. Should contain\n  at minimum the tools the child is allowed to use.\n* `approval` - The approval handler for tool execution gating.\n\n# Returns\n\nA [`ForgeAgentResult`] containing the new [`ToolLoopAgent`] on success.\n\n# Errors\n\nReturns [`ForgeAgentError::SubAgentFailed`] if:\n- A requested tool name is not present in the parent's tool set (capability\n  escalation attempt).\n\n# Examples\n\n```no_run\nuse forge_agent::subagent::{SubAgentConfig, create_subagent};\nuse forge_agent::agent::AgentConfig;\nuse forge_core::tool::{ToolDefinition, ToolTier};\nuse forge_core::model::LanguageModel;\nuse forge_tool::registry::ToolRegistry;\nuse forge_tool::approval::AutoApprove;\nuse std::sync::Arc;\n\nfn example(model: Arc<dyn LanguageModel>) {\n    let parent = AgentConfig::new(\"parent\", \"openai:gpt-4o\")\n        .with_tool(ToolDefinition::builder(\"search\").tier(ToolTier::External).build())\n        .with_tool(ToolDefinition::builder(\"write\").tier(ToolTier::External).build());\n\n    let sub = SubAgentConfig::new(\"child\")\n        .with_tool_names(vec![\"search\".to_string()]);\n\n    let registry = ToolRegistry::new();\n    let approval = Arc::new(AutoApprove);\n\n    let child = create_subagent(&parent, sub, model, registry, approval);\n    assert!(child.is_ok());\n}\n```"
        },
        {
          "name": "::create_subagent_with_observer",
          "line": 408,
          "signature": "pub async fn create_subagent_with_observer(\n    parent_config: &AgentConfig,\n    sub_config: SubAgentConfig,\n    model: Arc<dyn LanguageModel>,\n    tool_registry: ToolRegistry,\n    approval: Arc<dyn ApprovalHandler>,\n    observer: &dyn AgentLoopObserver,\n    context: SubAgentDelegationContext,\n) -> ForgeAgentResult<ToolLoopAgent>;",
          "documentation": "Creates a sub-agent and emits an observer callback for the delegation.\n\nThis async helper preserves the existing synchronous [`create_subagent`]\nAPI while giving streaming hosts and orchestration runtimes a semantic\nboundary for Cambium, telemetry, and UI projections."
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-agent/src/tool_loop.rs",
      "sha256": "ef678213f38866feba9a85a5874dcdf51f210b152044fc4e1a88b89a9640e172",
      "artifactSha256": "15e47604417ec6cccf83fe9522c700c16a330da01d2eeef0ecbd7bb120f9c9e5",
      "url": "/reference/source/forge-rs/crates/forge-agent/src/tool_loop.rs.txt",
      "declarations": [
        {
          "name": "::ToolLoopAgent",
          "line": 105,
          "signature": "pub struct ToolLoopAgent {\n\n}",
          "documentation": "The core agent implementation that executes the ANVIL tool loop.\n\n`ToolLoopAgent` drives the agent execution cycle:\n\n```text\nUser prompt\n    |\n    v\n[System prompt + messages] --> LLM\n    |\n    v\nResponse has tool calls?\n    |-- YES --> Execute tools --> Append results --> Loop\n    |-- NO  --> Return final text\n    |\nStop condition reached?\n    |-- YES --> Return with stop condition error\n```\n\n# Components\n\n| Component | Purpose |\n|-----------|---------|\n| `config` | Agent name, model, tools, max_steps, system prompt |\n| `model` | The language model implementation (provider-agnostic) |\n| `tool_registry` | Maps tool names to definitions and executors |\n| `approval` | Approval handler checked before each tool execution |\n| `health` | Runtime health metrics (tool invocations, inference stats) |\n| `lifecycle` | ANVIL lifecycle state machine |\n| `stop_conditions` | Additional stop conditions beyond max_steps |\n| `prepare_step` | Pre-step hook for message modification |\n\n# Thread Safety\n\n`ToolLoopAgent` is `Send + Sync`. The mutable state (health profile and\nlifecycle manager) is protected by a `Mutex`.\n\n# ANVIL Spec SS7.1\n\nThe tool loop algorithm is defined by the ANVIL specification. This\nimplementation is the Forge reference."
        },
        {
          "name": "::ToolLoopAgent::new",
          "line": 169,
          "signature": "pub fn new(\n        config: AgentConfig,\n        model: Arc<dyn LanguageModel>,\n        tool_registry: ToolRegistry,\n        approval: Arc<dyn ApprovalHandler>,\n    ) -> Self;",
          "documentation": "Creates a new `ToolLoopAgent` with the given configuration.\n\nThe agent starts in the `Initializing` lifecycle state. Call [`run()`](Agent::run)\nto execute it, which will automatically manage lifecycle transitions.\n\n# Arguments\n\n* `config` - The agent configuration (name, model, tools, limits).\n* `model` - The language model implementation.\n* `tool_registry` - Registry containing tool definitions and executors.\n* `approval` - The approval handler for tool execution gating.\n\n# Returns\n\nA new `ToolLoopAgent` ready to execute.\n\n# Examples\n\n```no_run\nuse forge_agent::tool_loop::ToolLoopAgent;\nuse forge_agent::agent::AgentConfig;\nuse forge_core::model::LanguageModel;\nuse forge_tool::registry::ToolRegistry;\nuse forge_tool::approval::AutoApprove;\nuse std::sync::Arc;\n\nfn example(model: Arc<dyn LanguageModel>) {\n    let config = AgentConfig::new(\"bot\", \"openai:gpt-4o\");\n    let registry = ToolRegistry::new();\n    let approval = Arc::new(AutoApprove);\n\n    let agent = ToolLoopAgent::new(config, model, registry, approval);\n}\n```"
        },
        {
          "name": "::ToolLoopAgent::with_stop_condition",
          "line": 221,
          "signature": "pub fn with_stop_condition(mut self, condition: AgentStopCondition) -> Self;",
          "documentation": "Adds a stop condition to the agent.\n\nStop conditions are checked after each tool loop step. If any condition\nfires, the loop terminates.\n\n# Arguments\n\n* `condition` - The stop condition to add.\n\n# Returns\n\nThe modified `ToolLoopAgent` (builder pattern).\n\n# Examples\n\n```no_run\nuse forge_agent::tool_loop::ToolLoopAgent;\nuse forge_agent::agent::AgentConfig;\nuse forge_agent::loop_control::AgentStopCondition;\nuse forge_tool::registry::ToolRegistry;\nuse forge_tool::approval::AutoApprove;\nuse std::sync::Arc;\n\nfn example(model: Arc<dyn forge_core::model::LanguageModel>) {\n    let agent = ToolLoopAgent::new(\n        AgentConfig::new(\"bot\", \"openai:gpt-4o\"),\n        model,\n        ToolRegistry::new(),\n        Arc::new(AutoApprove),\n    )\n    .with_stop_condition(AgentStopCondition::MaxTokens(50000));\n}\n```"
        },
        {
          "name": "::ToolLoopAgent::with_prepare_step",
          "line": 237,
          "signature": "pub fn with_prepare_step(mut self, prepare: Arc<dyn PrepareStep>) -> Self;",
          "documentation": "Sets the pre-step hook for message modification.\n\nThe hook runs before each LLM call and can modify the message list.\n\n# Arguments\n\n* `prepare` - The pre-step hook implementation.\n\n# Returns\n\nThe modified `ToolLoopAgent` (builder pattern)."
        },
        {
          "name": "::ToolLoopAgent::with_generate_options",
          "line": 251,
          "signature": "pub fn with_generate_options(mut self, options: GenerateOptions) -> Self;",
          "documentation": "Sets the generation options for LLM calls.\n\n# Arguments\n\n* `options` - The generation options (temperature, max_tokens, etc.).\n\n# Returns\n\nThe modified `ToolLoopAgent` (builder pattern)."
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-agent/src/workflow.rs",
      "sha256": "0a6608e099b46f95a1beebcfce376529dc8e906f639c7cb2333779f2938ab7b4",
      "artifactSha256": "77b2029934a70f7570ea56e2fe306583a2fa202c94503dc1da8ebb2b4581c6fd",
      "url": "/reference/source/forge-rs/crates/forge-agent/src/workflow.rs.txt",
      "declarations": [
        {
          "name": "::WorkflowOutput",
          "line": 57,
          "signature": "#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct WorkflowOutput {\n/// Individual outputs from each agent that executed.\n\npub agent_outputs: Vec<AgentOutput>,\n/// Aggregate token usage across all agents in the workflow.\n\npub total_usage: Usage,\n/// Total number of steps taken across all agents.\n\npub total_steps: u32,\n/// The final text output of the workflow.\n\n///\n\n/// For sequential workflows, this is the last agent's output.\n\n/// For parallel workflows, this is the concatenated outputs.\n\n/// For router workflows, this is the selected agent's output.\n\npub final_text: String\n}",
          "documentation": "The combined output of a workflow execution.\n\nContains the outputs from all agents that participated in the workflow,\nalong with aggregate statistics.\n\n# Examples\n\n```\nuse forge_agent::workflow::WorkflowOutput;\nuse forge_agent::agent::AgentOutput;\nuse forge_core::message::{ModelMessage, Role};\nuse forge_core::output::Usage;\n\nlet output = WorkflowOutput {\n    agent_outputs: vec![],\n    total_usage: Usage::zero(),\n    total_steps: 0,\n    final_text: String::new(),\n};\nassert!(output.agent_outputs.is_empty());\n```"
        },
        {
          "name": "::SequentialWorkflow",
          "line": 102,
          "signature": "pub struct SequentialWorkflow {\n\n}",
          "documentation": "A sequential workflow that runs agents one after another.\n\nEach agent receives the previous agent's output as its input prompt.\nThe first agent receives the original user prompt. The final agent's\noutput becomes the workflow's output.\n\n```text\nUser prompt -> Agent 1 -> output_1 -> Agent 2 -> output_2 -> ... -> Final output\n```\n\n# ANVIL Spec SS7.2\n\nSequential workflows are the simplest orchestration pattern. They model\na pipeline where each stage transforms the previous stage's output.\n\n# Examples\n\n```no_run\nuse forge_agent::workflow::SequentialWorkflow;\nuse forge_agent::agent::Agent;\nuse std::sync::Arc;\n\nasync fn example(agents: Vec<Arc<dyn Agent>>) {\n    let workflow = SequentialWorkflow::new(\"pipeline\", agents);\n    let result = workflow.execute(\"Start\").await;\n}\n```"
        },
        {
          "name": "::SequentialWorkflow::new",
          "line": 133,
          "signature": "pub fn new(name: impl Into<String>, agents: Vec<Arc<dyn Agent>>) -> Self;",
          "documentation": "Creates a new sequential workflow.\n\n# Arguments\n\n* `name` - A human-readable name for the workflow (used in error messages).\n* `agents` - The ordered list of agents. The first agent runs first.\n\n# Returns\n\nA new `SequentialWorkflow`.\n\n# Examples\n\n```no_run\nuse forge_agent::workflow::SequentialWorkflow;\nuse std::sync::Arc;\nuse forge_agent::agent::Agent;\n\nfn example(a1: Arc<dyn Agent>, a2: Arc<dyn Agent>) {\n    let wf = SequentialWorkflow::new(\"my-pipeline\", vec![a1, a2]);\n}\n```"
        },
        {
          "name": "::SequentialWorkflow::execute",
          "line": 174,
          "signature": "pub async fn execute(&self, prompt: &str) -> Result<WorkflowOutput, ForgeAgentError>;",
          "documentation": "Executes the sequential workflow.\n\nRuns each agent in order. The first agent receives the `prompt` as input.\nEach subsequent agent receives the previous agent's `final_text` as input.\n\n# Arguments\n\n* `prompt` - The initial user prompt for the first agent.\n\n# Returns\n\nA [`WorkflowOutput`] containing all agent outputs and aggregate stats.\n\n# Errors\n\nReturns [`ForgeAgentError::WorkflowFailed`] if any agent in the sequence\nfails during execution.\n\n# Examples\n\n```no_run\nuse forge_agent::workflow::SequentialWorkflow;\nuse forge_agent::agent::Agent;\nuse std::sync::Arc;\n\nasync fn example(agents: Vec<Arc<dyn Agent>>) {\n    let wf = SequentialWorkflow::new(\"pipe\", agents);\n    match wf.execute(\"start\").await {\n        Ok(output) => println!(\"Final: {}\", output.final_text),\n        Err(e) => eprintln!(\"Workflow failed: {e}\"),\n    }\n}\n```"
        },
        {
          "name": "::ParallelWorkflow",
          "line": 271,
          "signature": "pub struct ParallelWorkflow {\n\n}",
          "documentation": "A parallel workflow that runs agents concurrently.\n\nAll agents receive the same input prompt and execute simultaneously.\nResults are collected when all agents complete. If any agent fails,\nthe entire workflow fails.\n\n```text\nUser prompt --> Agent 1 --> output_1 --|\n           |--> Agent 2 --> output_2 --|-- Collect all\n           |--> Agent N --> output_N --|\n```\n\n# ANVIL Spec SS7.2\n\nParallel workflows are used for fan-out/fan-in patterns where independent\nsub-tasks can be processed concurrently.\n\n# Examples\n\n```no_run\nuse forge_agent::workflow::ParallelWorkflow;\nuse forge_agent::agent::Agent;\nuse std::sync::Arc;\n\nasync fn example(agents: Vec<Arc<dyn Agent>>) {\n    let workflow = ParallelWorkflow::new(\"fan-out\", agents);\n    let result = workflow.execute(\"Analyze this\").await;\n}\n```"
        },
        {
          "name": "::ParallelWorkflow::new",
          "line": 290,
          "signature": "pub fn new(name: impl Into<String>, agents: Vec<Arc<dyn Agent>>) -> Self;",
          "documentation": "Creates a new parallel workflow.\n\n# Arguments\n\n* `name` - A human-readable name for the workflow.\n* `agents` - The list of agents to run concurrently.\n\n# Returns\n\nA new `ParallelWorkflow`."
        },
        {
          "name": "::ParallelWorkflow::execute",
          "line": 315,
          "signature": "pub async fn execute(&self, prompt: &str) -> Result<WorkflowOutput, ForgeAgentError>;",
          "documentation": "Executes the parallel workflow.\n\nSpawns all agents concurrently with the same input prompt. Waits for\nall agents to complete. The final text is the concatenation of all\nagents' outputs, separated by newlines.\n\n# Arguments\n\n* `prompt` - The input prompt sent to every agent.\n\n# Returns\n\nA [`WorkflowOutput`] containing all agent outputs and aggregate stats.\n\n# Errors\n\nReturns [`ForgeAgentError::WorkflowFailed`] if any agent fails."
        },
        {
          "name": "::RouterWorkflow",
          "line": 408,
          "signature": "pub struct RouterWorkflow {\n\n}",
          "documentation": "A router workflow that uses a classifier to select an agent.\n\nThe router sends the input to a classifier model (via a classifier agent)\nto determine which specialized agent should handle the request. Only the\nselected agent executes.\n\n```text\nUser prompt --> Classifier --> select Agent K --> output_K\n```\n\n# ANVIL Spec SS7.2\n\nRouter workflows enable dynamic dispatch to specialized agents based on\nthe input content, enabling efficient resource utilization.\n\n# Examples\n\n```no_run\nuse forge_agent::workflow::RouterWorkflow;\nuse forge_agent::agent::Agent;\nuse std::sync::Arc;\n\nasync fn example(\n    classifier: Arc<dyn Agent>,\n    agents: Vec<(String, Arc<dyn Agent>)>,\n) {\n    let workflow = RouterWorkflow::new(\"router\", classifier, agents);\n    let result = workflow.execute(\"Analyze this dataset\").await;\n}\n```"
        },
        {
          "name": "::RouterWorkflow::new",
          "line": 432,
          "signature": "pub fn new(\n        name: impl Into<String>,\n        classifier: Arc<dyn Agent>,\n        agents: Vec<(String, Arc<dyn Agent>)>,\n    ) -> Self;",
          "documentation": "Creates a new router workflow.\n\n# Arguments\n\n* `name` - A human-readable name for the workflow.\n* `classifier` - An agent that classifies the input and returns a route name.\n* `agents` - Named agents. The classifier's output is matched against these names.\n\n# Returns\n\nA new `RouterWorkflow`."
        },
        {
          "name": "::RouterWorkflow::execute",
          "line": 464,
          "signature": "pub async fn execute(&self, prompt: &str) -> Result<WorkflowOutput, ForgeAgentError>;",
          "documentation": "Executes the router workflow.\n\n1. Runs the classifier agent with the prompt.\n2. Matches the classifier's output text against agent names.\n3. Runs the matched agent with the original prompt.\n\n# Arguments\n\n* `prompt` - The input prompt to classify and route.\n\n# Returns\n\nA [`WorkflowOutput`] containing the classifier and selected agent outputs.\n\n# Errors\n\n- [`ForgeAgentError::WorkflowFailed`] if the classifier fails.\n- [`ForgeAgentError::WorkflowFailed`] if no agent matches the classifier's output.\n- [`ForgeAgentError::WorkflowFailed`] if the selected agent fails."
        }
      ]
    }
  ]
}
