{
  "name": "forge-generate",
  "language": "rust",
  "version": "0.2.0",
  "description": "Text, stream, and structured output generation for the Forge SDK",
  "manifest": "forge-rs/crates/forge-generate/Cargo.toml",
  "manifestSha256": "bd1d2fdc4d0e5fc00553e7b809098dfabe722bd3dca4a985367c8d0562326226",
  "status": "source-reference",
  "registryPublicationVerified": false,
  "route": "/libraries/rust/forge-generate",
  "features": {},
  "files": [
    {
      "path": "forge-rs/crates/forge-generate/src/error.rs",
      "sha256": "8e7abb146991d947e6df860feb7b8a11d14db181b016ccf85e7515c7c723bb97",
      "artifactSha256": "ad0957819cd43d2b1c51046c2f3f2b6e825dc01eb5b149aee6caf82a4ce7e86c",
      "url": "/reference/source/forge-rs/crates/forge-generate/src/error.rs.txt",
      "declarations": [
        {
          "name": "::ForgeGenerateError",
          "line": 33,
          "signature": "#[derive(Debug, Error)]\npub enum ForgeGenerateError {\n    /// The language model returned an error during inference.\n    ///\n    /// This wraps errors from the underlying `LanguageModel::generate()` or\n    /// `LanguageModel::stream()` calls, including provider-side failures,\n    /// rate limits, and network errors.\n    #[error(\"model '{model}' returned an error during generation: {reason}\")]\n    ModelError {\n        /// The model identifier (e.g., \"gpt-4o\").\n        model: String,\n        /// The error message from the provider.\n        reason: String,\n    },\n\n    /// The model's output failed schema validation.\n    ///\n    /// Occurs during structured output generation ([`generate_object()`] /\n    /// [`stream_object()`]) when the model produces JSON that does not\n    /// conform to the provided schema.\n    ///\n    /// [`generate_object()`]: crate::generate_object\n    /// [`stream_object()`]: crate::stream_object\n    #[error(\"schema violation at path '{path}': {reason} (model={model})\")]\n    SchemaViolation {\n        /// The model identifier.\n        model: String,\n        /// JSON pointer path to the failing field.\n        path: String,\n        /// Human-readable description of the schema expectation.\n        reason: String,\n    },\n\n    /// The maximum step limit was reached during multi-step generation.\n    ///\n    /// Occurs when [`generate_steps()`] exhausts its stop condition without\n    /// the model producing a terminal response.\n    ///\n    /// [`generate_steps()`]: crate::generate_steps\n    #[error(\"step limit reached after {steps_completed} steps (limit={limit}, total_tokens={total_tokens})\")]\n    StepLimitReached {\n        /// The number of steps completed before the limit was hit.\n        steps_completed: u32,\n        /// The configured step limit.\n        limit: u32,\n        /// Total tokens consumed across all steps.\n        total_tokens: u64,\n    },\n\n    /// A streaming response was interrupted before completion.\n    ///\n    /// Occurs when `LanguageModel::stream()` returns chunks that do not\n    /// include a terminal `Done` chunk, indicating the stream was cut short.\n    #[error(\"stream interrupted for model '{model}' after {chunks_received} chunks: {reason}\")]\n    StreamInterrupted {\n        /// The model identifier.\n        model: String,\n        /// The number of chunks received before the interruption.\n        chunks_received: usize,\n        /// Explanation of what went wrong.\n        reason: String,\n    },\n\n    /// The model returned no response content.\n    ///\n    /// Occurs when the model's response message contains no text parts and\n    /// no tool calls, which is an unexpected provider behavior.\n    #[error(\"model '{model}' returned no response content for {messages_count} input messages\")]\n    NoResponse {\n        /// The model identifier.\n        model: String,\n        /// The number of input messages that were sent.\n        messages_count: usize,\n    },\n\n    /// JSON deserialization of the model output failed.\n    ///\n    /// Occurs during structured output generation when the model's text\n    /// output cannot be parsed as valid JSON or cannot be deserialized\n    /// into the target type.\n    #[error(\"failed to deserialize model output as {target_type}: {reason} (model={model})\")]\n    DeserializationFailed {\n        /// The model identifier.\n        model: String,\n        /// The name of the target type being deserialized to.\n        target_type: String,\n        /// The deserialization error message.\n        reason: String,\n    },\n\n    /// A `forge-core` error occurred during generation.\n    #[error(\"core error: {0}\")]\n    Core(#[from] forge_core::error::ForgeError),\n}",
          "documentation": "Error type for generation operations.\n\nCovers model call failures, schema violations, streaming interruptions,\nstep limit exhaustion, and missing responses.\n\n# Examples\n\n```\nuse forge_generate::ForgeGenerateError;\n\nlet err = ForgeGenerateError::NoResponse {\n    model: \"openai:gpt-4o\".to_string(),\n    messages_count: 5,\n};\nlet msg = err.to_string();\nassert!(msg.contains(\"openai:gpt-4o\"));\nassert!(msg.contains(\"5\"));\n```"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-generate/src/lib.rs",
      "sha256": "3a98512850ebd57e25f815df526a87a285ce3edd41f7b82019fba310411b1b49",
      "artifactSha256": "63762cdf6b3ed9d7be44422ea97389c2d30dd513b320ad26d4421f7fdd364a07",
      "url": "/reference/source/forge-rs/crates/forge-generate/src/lib.rs.txt",
      "declarations": [
        {
          "name": "error",
          "line": 45,
          "signature": "pub mod error;",
          "documentation": "# forge-generate\n\nText generation, streaming, and structured output generation for the Forge SDK.\n\nThis crate provides the primary inference functions that agent code uses to\ninteract with language models. It builds on `forge-core` types and the\n`LanguageModel` trait to deliver:\n\n- **Text generation** \u2014 [`generate_text()`] for complete, buffered responses.\n- **Streaming** \u2014 [`stream_text()`] for incremental, chunk-by-chunk responses.\n- **Structured output** \u2014 [`generate_object()`] and [`stream_object()`] for\n  schema-validated, deserialized responses.\n- **Multi-step generation** \u2014 [`generate_steps()`] for iterating through\n  multiple inference calls until a stop condition is met.\n\n# ANVIL Spec Reference\n\nThis crate implements ANVIL Spec \u00a76.1 \u2014 Cognitive Interface, which defines the\ninference operations that all ANVIL-compliant runtimes must support:\n\n- `infer()` maps to [`generate_text()`]\n- `infer_stream()` maps to [`stream_text()`]\n- Structured output maps to [`generate_object()`]\n- Multi-step loops map to [`generate_steps()`]\n\n# Examples\n\n```no_run\nuse forge_core::config::GenerateOptions;\nuse forge_core::message::{ModelMessage, Role};\nuse forge_core::model::LanguageModel;\n\nasync fn example(model: &dyn LanguageModel) {\n    let messages = vec![\n        ModelMessage::text(Role::System, \"You are a helpful assistant.\"),\n        ModelMessage::text(Role::User, \"What is 2+2?\"),\n    ];\n    let options = GenerateOptions::default();\n\n    let result = forge_generate::generate_text(model, &messages, &[], &options).await;\n}\n```"
        },
        {
          "name": "object",
          "line": 46,
          "signature": "pub mod object;",
          "documentation": ""
        },
        {
          "name": "step",
          "line": 47,
          "signature": "pub mod step;",
          "documentation": ""
        },
        {
          "name": "stream",
          "line": 48,
          "signature": "pub mod stream;",
          "documentation": ""
        },
        {
          "name": "text",
          "line": 49,
          "signature": "pub mod text;",
          "documentation": ""
        },
        {
          "name": "pub use error::ForgeGenerateError;",
          "line": 51,
          "signature": "pub use error::ForgeGenerateError;",
          "documentation": ""
        },
        {
          "name": "pub use object::{generate_object, stream_object, ObjectResult};",
          "line": 52,
          "signature": "pub use object::{generate_object, stream_object, ObjectResult};",
          "documentation": ""
        },
        {
          "name": "pub use step::{generate_steps, StepResult, StopCondition, StopReason};",
          "line": 53,
          "signature": "pub use step::{generate_steps, StepResult, StopCondition, StopReason};",
          "documentation": ""
        },
        {
          "name": "pub use stream::{stream_text, stream_text_chunks, TextStreamResult};",
          "line": 54,
          "signature": "pub use stream::{stream_text, stream_text_chunks, TextStreamResult};",
          "documentation": ""
        },
        {
          "name": "pub use text::{generate_text, GenerateTextResult};",
          "line": 55,
          "signature": "pub use text::{generate_text, GenerateTextResult};",
          "documentation": ""
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-generate/src/object.rs",
      "sha256": "7de11089d17a005eee22201555ff89478cdb395aefa10a648c073dcdde18f390",
      "artifactSha256": "dfe5a88584cd3b7ecb556216c2196a0113319aecf8267ceea34f63ada85a9f0f",
      "url": "/reference/source/forge-rs/crates/forge-generate/src/object.rs.txt",
      "declarations": [
        {
          "name": "::ObjectResult",
          "line": 84,
          "signature": "#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct ObjectResult<T> {\n/// The deserialized object.\n\npub object: T,\n/// The raw JSON string from the model output.\n\npub raw_json: String,\n/// Token usage statistics.\n\npub usage: Usage,\n/// Why generation stopped.\n\npub finish_reason: FinishReason\n}",
          "documentation": "The result of a [`generate_object()`] or [`stream_object()`] call.\n\nContains the deserialized object, the raw JSON string from the model,\nand token usage statistics.\n\n# Type Parameters\n\n* `T` - The target type to deserialize the model's JSON output into.\n\n# Examples\n\n```\nuse forge_core::output::Usage;\nuse forge_generate::ObjectResult;\n\nlet result: ObjectResult<Vec<String>> = ObjectResult {\n    object: vec![\"hello\".to_string()],\n    raw_json: r#\"[\"hello\"]\"#.to_string(),\n    usage: Usage { prompt_tokens: 5, completion_tokens: 3, total_tokens: 8 },\n    finish_reason: forge_core::output::FinishReason::Stop,\n};\nassert_eq!(result.object.len(), 1);\n```"
        },
        {
          "name": "::generate_object",
          "line": 157,
          "signature": "pub async fn generate_object<T: DeserializeOwned>(\n    model: &dyn LanguageModel,\n    messages: &[ModelMessage],\n    schema: &JsonSchema,\n    options: &GenerateOptions,\n) -> Result<ObjectResult<T>, ForgeGenerateError>;",
          "documentation": "Generates a structured object from a language model.\n\nSends the conversation history to the model with a JSON schema constraint,\nvalidates the response against the schema, and deserializes it into type `T`.\n\nThe schema is passed to the model via `GenerateOptions::output_schema`. If the\ncaller provides options that already have an `output_schema` set, this function\nuses the `schema` parameter instead (overriding the options schema).\n\n# ANVIL Spec \u00a76.1\n\nStructured output generation uses the cognitive interface `infer()` with a\nschema constraint.\n\n# Arguments\n\n* `model` - The language model to use for generation.\n* `messages` - The conversation history.\n* `schema` - The JSON schema that the model's output must conform to.\n* `options` - Generation options (temperature, max_tokens, etc.).\n\n# Returns\n\nAn [`ObjectResult<T>`] containing the deserialized object, raw JSON, usage,\nand finish reason.\n\n# Errors\n\n* [`ForgeGenerateError::ModelError`] \u2014 if the model call fails.\n* [`ForgeGenerateError::NoResponse`] \u2014 if the model returns empty content.\n* [`ForgeGenerateError::SchemaViolation`] \u2014 if the output fails schema validation.\n* [`ForgeGenerateError::DeserializationFailed`] \u2014 if JSON deserialization fails.\n\n# Examples\n\n```no_run\nuse forge_core::config::GenerateOptions;\nuse forge_core::message::{ModelMessage, Role};\nuse forge_core::model::LanguageModel;\nuse forge_core::schema::JsonSchema;\nuse forge_generate::generate_object;\nuse serde::Deserialize;\n\n#[derive(Deserialize)]\nstruct Answer {\n    value: i32,\n    explanation: String,\n}\n\nasync fn example(model: &dyn LanguageModel) {\n    let messages = vec![ModelMessage::text(Role::User, \"What is 2+2?\")];\n    let schema = JsonSchema::object()\n        .property(\"value\", JsonSchema::integer())\n        .property(\"explanation\", JsonSchema::string())\n        .required(\"value\")\n        .required(\"explanation\");\n\n    let result = generate_object::<Answer>(\n        model, &messages, &schema, &GenerateOptions::default(),\n    ).await;\n}\n```"
        },
        {
          "name": "::stream_object",
          "line": 293,
          "signature": "pub async fn stream_object<T: DeserializeOwned>(\n    model: &dyn LanguageModel,\n    messages: &[ModelMessage],\n    schema: &JsonSchema,\n    options: &GenerateOptions,\n) -> Result<ObjectResult<T>, ForgeGenerateError>;",
          "documentation": "Streams a structured object response from a language model.\n\nSimilar to [`generate_object()`], but uses the streaming API to receive the\nresponse incrementally. Once the full stream is collected, the assembled text\nis validated against the schema and deserialized into type `T`.\n\n# ANVIL Spec \u00a76.1\n\nStreaming structured output combines `infer_stream()` with schema validation.\n\n# Arguments\n\n* `model` - The language model to use for streaming generation.\n* `messages` - The conversation history.\n* `schema` - The JSON schema that the model's output must conform to.\n* `options` - Generation options (temperature, max_tokens, etc.).\n\n# Returns\n\nAn [`ObjectResult<T>`] containing the deserialized object, raw JSON, usage,\nand finish reason.\n\n# Errors\n\n* [`ForgeGenerateError::ModelError`] \u2014 if the model stream call fails.\n* [`ForgeGenerateError::StreamInterrupted`] \u2014 if the stream ends prematurely.\n* [`ForgeGenerateError::NoResponse`] \u2014 if the assembled text is empty.\n* [`ForgeGenerateError::SchemaViolation`] \u2014 if the output fails schema validation.\n* [`ForgeGenerateError::DeserializationFailed`] \u2014 if JSON deserialization fails.\n\n# Examples\n\n```no_run\nuse forge_core::config::GenerateOptions;\nuse forge_core::message::{ModelMessage, Role};\nuse forge_core::model::LanguageModel;\nuse forge_core::schema::JsonSchema;\nuse forge_generate::stream_object;\nuse serde::Deserialize;\n\n#[derive(Deserialize)]\nstruct Summary {\n    title: String,\n    points: Vec<String>,\n}\n\nasync fn example(model: &dyn LanguageModel) {\n    let messages = vec![ModelMessage::text(Role::User, \"Summarize this document.\")];\n    let schema = JsonSchema::object()\n        .property(\"title\", JsonSchema::string())\n        .property(\"points\", JsonSchema::array().items_schema(JsonSchema::string()))\n        .required(\"title\")\n        .required(\"points\");\n\n    let result = stream_object::<Summary>(\n        model, &messages, &schema, &GenerateOptions::default(),\n    ).await;\n}\n```"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-generate/src/step.rs",
      "sha256": "d15bc5689f67f7cc67c65f340c8f5b094c158ddd4f6ef2bafa0bbb62ea843d67",
      "artifactSha256": "704be9e6d43a0e4d06514674dc7dc11475154514946a1010683112aa394cba48",
      "url": "/reference/source/forge-rs/crates/forge-generate/src/step.rs.txt",
      "declarations": [
        {
          "name": "::StopCondition",
          "line": 70,
          "signature": "pub enum StopCondition {\n    /// Stop after a maximum number of generation steps.\n    MaxSteps(u32),\n\n    /// Stop when the cumulative token usage exceeds this threshold.\n    MaxTokens(u64),\n\n    /// Stop when the model's text output contains this substring.\n    TextMatch(String),\n\n    /// Stop based on a custom predicate applied to each step's result.\n    ///\n    /// The function receives the latest `GenerateResult` and returns `true`\n    /// if generation should stop.\n    Custom(Box<dyn Fn(&GenerateResult) -> bool + Send + Sync>),\n}",
          "documentation": "A condition that determines when multi-step generation stops.\n\n# ANVIL Spec \u00a76.1\n\nThe cognitive interface tool loop continues until a terminal condition:\nthe model stops requesting tools, a step limit is reached, or a token\nbudget is exhausted.\n\n# Variants\n\n* [`MaxSteps`](StopCondition::MaxSteps) \u2014 Stop after a fixed number of steps.\n* [`MaxTokens`](StopCondition::MaxTokens) \u2014 Stop when cumulative tokens exceed a budget.\n* [`TextMatch`](StopCondition::TextMatch) \u2014 Stop when the model's output contains a string.\n* [`Custom`](StopCondition::Custom) \u2014 Stop based on a user-defined predicate.\n\n# Examples\n\n```\nuse forge_generate::StopCondition;\n\nlet by_steps = StopCondition::MaxSteps(10);\nlet by_tokens = StopCondition::MaxTokens(4096);\nlet by_text = StopCondition::TextMatch(\"FINAL ANSWER\".to_string());\n```"
        },
        {
          "name": "::StopReason",
          "line": 113,
          "signature": "#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]\npub enum StopReason {\n    /// The model produced a terminal response (no more tool calls).\n    ModelStopped,\n\n    /// The maximum step limit was reached.\n    StepLimitReached {\n        /// The number of steps completed.\n        steps: u32,\n        /// The configured step limit.\n        limit: u32,\n    },\n\n    /// The cumulative token budget was exceeded.\n    TokenLimitReached {\n        /// Total tokens consumed.\n        total_tokens: u64,\n        /// The configured token limit.\n        limit: u64,\n    },\n\n    /// The model's output matched the target text.\n    TextMatchFound {\n        /// The text pattern that was matched.\n        pattern: String,\n    },\n\n    /// A custom stop condition was triggered.\n    CustomCondition,\n}",
          "documentation": "The reason why multi-step generation stopped.\n\nIncluded in [`StepResult`] to let the caller determine whether\ngeneration completed naturally or was cut short by a limit.\n\n# Examples\n\n```\nuse forge_generate::StopReason;\n\nlet reason = StopReason::ModelStopped;\nlet msg = format!(\"{reason}\");\nassert!(msg.contains(\"stopped\"));\n```"
        },
        {
          "name": "::StepResult",
          "line": 181,
          "signature": "#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct StepResult {\n/// The ordered sequence of generation results, one per step.\n\npub steps: Vec<GenerateResult>,\n/// Cumulative token usage across all steps.\n\npub total_usage: Usage,\n/// Why multi-step generation stopped.\n\npub stop_reason: StopReason\n}",
          "documentation": "The result of a [`generate_steps()`] call.\n\nContains the sequence of generation results from each step, cumulative\ntoken usage, and the reason generation stopped.\n\n# Examples\n\n```\nuse forge_core::output::Usage;\nuse forge_generate::step::{StepResult, StopReason};\n\nlet result = StepResult {\n    steps: vec![],\n    total_usage: Usage::zero(),\n    stop_reason: StopReason::ModelStopped,\n};\nassert!(result.steps.is_empty());\n```"
        },
        {
          "name": "::StepResult::final_text",
          "line": 198,
          "signature": "pub fn final_text(&self) -> String;",
          "documentation": "Returns the text from the final step, or an empty string if no steps completed.\n\n# Returns\n\nThe text content of the last generation result."
        },
        {
          "name": "::StepResult::step_count",
          "line": 203,
          "signature": "pub fn step_count(&self) -> usize;",
          "documentation": "Returns the number of completed steps."
        },
        {
          "name": "::StepResult::completed_naturally",
          "line": 208,
          "signature": "pub fn completed_naturally(&self) -> bool;",
          "documentation": "Returns `true` if the model stopped naturally (no limits hit)."
        },
        {
          "name": "::generate_steps",
          "line": 261,
          "signature": "pub async fn generate_steps(\n    model: &dyn LanguageModel,\n    initial_messages: Vec<ModelMessage>,\n    tools: &[ToolDefinition],\n    options: &GenerateOptions,\n    stop: StopCondition,\n) -> Result<StepResult, ForgeGenerateError>;",
          "documentation": "Runs multi-step generation until a stop condition is met.\n\nEach step calls `LanguageModel::generate()`, appends the model's response\nto the conversation, and checks the stop condition. Generation continues\nuntil the stop condition fires or the model produces a response without\ntool calls (natural completion).\n\n# ANVIL Spec \u00a76.1\n\nImplements the tool loop pattern from the cognitive interface specification.\n\n# Arguments\n\n* `model` - The language model to use.\n* `initial_messages` - The starting conversation history. This is consumed and\n  extended with each step's response.\n* `tools` - Available tool definitions.\n* `options` - Generation options applied to each step.\n* `stop` - The stop condition that terminates generation.\n\n# Returns\n\nA [`StepResult`] containing all step results, cumulative usage, and stop reason.\n\n# Errors\n\n* [`ForgeGenerateError::ModelError`] \u2014 if any step's model call fails.\n* [`ForgeGenerateError::StepLimitReached`] \u2014 if the maximum step limit is reached\n  (only when using `StopCondition::MaxSteps`).\n\n# Examples\n\n```no_run\nuse forge_core::config::GenerateOptions;\nuse forge_core::message::{ModelMessage, Role};\nuse forge_core::model::LanguageModel;\nuse forge_generate::step::{generate_steps, StopCondition};\n\nasync fn example(model: &dyn LanguageModel) {\n    let messages = vec![\n        ModelMessage::text(Role::User, \"What is 2+2?\"),\n    ];\n    let result = generate_steps(\n        model, messages, &[], &GenerateOptions::default(),\n        StopCondition::MaxSteps(3),\n    ).await;\n}\n```"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-generate/src/stream.rs",
      "sha256": "41e588929ce3c918bdb009dfc7c9b89b452d1dbb93a1e8ff5ee501e52f8a7c11",
      "artifactSha256": "da7cfa4b333bfb83c6d0cb01fb49f137cb8907d33281a7ffb6420747bfcb014b",
      "url": "/reference/source/forge-rs/crates/forge-generate/src/stream.rs.txt",
      "declarations": [
        {
          "name": "::TextStreamResult",
          "line": 77,
          "signature": "#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct TextStreamResult {\n\n}",
          "documentation": "The result of a [`stream_text()`] call.\n\nHolds all streamed chunks received from the model and provides accessors\nfor assembling the full text, inspecting individual chunks, and retrieving\nusage statistics from the terminal `Done` chunk.\n\n# ANVIL Spec \u00a76.1\n\nStreaming results must include the full set of chunks, final usage, and\nfinish reason.\n\n# Examples\n\n```\nuse forge_core::output::{StreamChunk, FinishReason, Usage};\nuse forge_generate::TextStreamResult;\n\nlet chunks = vec![\n    StreamChunk::text_delta(\"Hello\"),\n    StreamChunk::text_delta(\", world!\"),\n    StreamChunk::done(FinishReason::Stop, Usage { prompt_tokens: 5, completion_tokens: 3, total_tokens: 8 }),\n];\nlet result = TextStreamResult::new(chunks);\nassert_eq!(result.full_text(), \"Hello, world!\");\nassert_eq!(result.chunk_count(), 3);\n```"
        },
        {
          "name": "::TextStreamResult::new",
          "line": 88,
          "signature": "pub fn new(chunks: Vec<StreamChunk>) -> Self;",
          "documentation": "Creates a new `TextStreamResult` from received chunks.\n\n# Arguments\n\n* `chunks` - The complete set of stream chunks received from the model."
        },
        {
          "name": "::TextStreamResult::full_text",
          "line": 109,
          "signature": "pub fn full_text(&self) -> String;",
          "documentation": "Assembles and returns the full text from all text delta chunks.\n\nConcatenates the text content of every `TextDelta` chunk in order.\nNon-text chunks (tool call deltas, done markers) are skipped.\n\n# Examples\n\n```\nuse forge_core::output::{StreamChunk, FinishReason, Usage};\nuse forge_generate::TextStreamResult;\n\nlet result = TextStreamResult::new(vec![\n    StreamChunk::text_delta(\"Hello\"),\n    StreamChunk::text_delta(\" there\"),\n]);\nassert_eq!(result.full_text(), \"Hello there\");\n```"
        },
        {
          "name": "::TextStreamResult::chunks",
          "line": 124,
          "signature": "pub fn chunks(&self) -> &[StreamChunk];",
          "documentation": "Returns a reference to the received chunks.\n\n# Returns\n\nA slice of all [`StreamChunk`] values in the order they were received."
        },
        {
          "name": "::TextStreamResult::chunk_count",
          "line": 129,
          "signature": "pub fn chunk_count(&self) -> usize;",
          "documentation": "Returns the total number of received chunks."
        },
        {
          "name": "::TextStreamResult::usage",
          "line": 141,
          "signature": "pub fn usage(&self) -> Usage;",
          "documentation": "Returns the usage statistics from the terminal `Done` chunk.\n\nIf no `Done` chunk is present (e.g., the stream was interrupted),\nreturns [`Usage::zero()`].\n\n# Returns\n\nA [`Usage`] struct with prompt, completion, and total token counts."
        },
        {
          "name": "::TextStreamResult::finish_reason",
          "line": 157,
          "signature": "pub fn finish_reason(&self) -> Option<FinishReason>;",
          "documentation": "Returns the finish reason from the terminal `Done` chunk.\n\nIf no `Done` chunk is present, returns `None`.\n\n# Returns\n\nThe [`FinishReason`] from the terminal chunk, if present."
        },
        {
          "name": "::TextStreamResult::is_complete",
          "line": 167,
          "signature": "pub fn is_complete(&self) -> bool;",
          "documentation": "Returns `true` if the stream completed (a `Done` chunk was received)."
        },
        {
          "name": "::stream_text",
          "line": 232,
          "signature": "pub async fn stream_text(\n    model: &dyn LanguageModel,\n    messages: &[ModelMessage],\n    tools: &[ToolDefinition],\n    options: &GenerateOptions,\n) -> Result<TextStreamResult, ForgeGenerateError>;",
          "documentation": "Streams a text response from a language model.\n\nSends the conversation history and available tools to the model, receives\nthe streamed response as chunks, and wraps the result in a [`TextStreamResult`].\n\n# Buffering\n\nThis call drives the underlying [`stream_text_chunks()`] to completion\nand collects every `Ok` item into a `Vec<StreamChunk>` before returning.\nMid-stream errors are silently dropped \u2014 to observe them, use\n[`stream_text_chunks()`] directly.\n\nFor true per-token UX, prefer [`stream_text_chunks()`].\n\n# ANVIL Spec \u00a76.1\n\nImplements the `infer_stream()` operation defined by the ANVIL cognitive interface.\n\n# Arguments\n\n* `model` - The language model to use for streaming generation.\n* `messages` - The conversation history (system, user, assistant, tool messages).\n* `tools` - Available tool definitions the model may call. Pass an empty slice\n  if no tools are available.\n* `options` - Generation options (temperature, max_tokens, etc.).\n\n# Returns\n\nA [`TextStreamResult`] holding all received chunks, with accessors for the\nassembled text, individual chunks, usage, and finish reason.\n\n# Errors\n\n* [`ForgeGenerateError::ModelError`] \u2014 if the underlying model stream call fails.\n* [`ForgeGenerateError::StreamInterrupted`] \u2014 if the stream completes without\n  a terminal `Done` chunk.\n\n# Examples\n\n```no_run\nuse forge_core::config::GenerateOptions;\nuse forge_core::message::{ModelMessage, Role};\nuse forge_core::model::LanguageModel;\nuse forge_generate::stream_text;\n\nasync fn example(model: &dyn LanguageModel) {\n    let messages = vec![\n        ModelMessage::text(Role::User, \"Tell me a joke.\"),\n    ];\n    let result = stream_text(model, &messages, &[], &GenerateOptions::default()).await;\n    if let Ok(r) = result {\n        for chunk in r.chunks() {\n            if let Some(text) = chunk.as_text() {\n                print!(\"{text}\");\n            }\n        }\n        println!();\n    }\n}\n```"
        },
        {
          "name": "::stream_text_chunks",
          "line": 331,
          "signature": "pub async fn stream_text_chunks(\n    model: &dyn LanguageModel,\n    messages: &[ModelMessage],\n    tools: &[ToolDefinition],\n    options: &GenerateOptions,\n) -> Result<ChunkStream<'static>, ForgeGenerateError>;",
          "documentation": "Streams a text response and returns the underlying [`ChunkStream`] directly.\n\n**Per-token streaming.** Unlike [`stream_text`], this function does not\ncollect the response into a `Vec`. Each item resolves as soon as the\nupstream provider yields the corresponding chunk on the wire.\n\nUse this when you want to render text as it arrives \u2014 TUIs, live\ndashboards, the harness ecosystem. Use [`stream_text`] when you only\nneed the final assembled text and want a simple `TextStreamResult`.\n\n# Errors\n\n- Outer `Result` returns `Err` for connect-time failures (auth, malformed\n  request, non-2xx status).\n- Per-item `Err` for mid-stream failures (frame read, SSE decode, JSON\n  parse). Caller decides whether to break or recover.\n\n(RFC 0001 / F-6 / F-7.)\n\n# Examples\n\n```no_run\nuse forge_core::config::GenerateOptions;\nuse forge_core::message::{ModelMessage, Role};\nuse forge_core::model::LanguageModel;\nuse forge_generate::stream_text_chunks;\nuse futures_util::StreamExt;\n\nasync fn example(model: &dyn LanguageModel) {\n    let messages = vec![ModelMessage::text(Role::User, \"Tell me a joke.\")];\n    if let Ok(mut stream) = stream_text_chunks(model, &messages, &[], &GenerateOptions::default()).await {\n        while let Some(item) = stream.next().await {\n            if let Ok(chunk) = item {\n                if let Some(text) = chunk.as_text() {\n                    print!(\"{text}\");\n                }\n            }\n        }\n        println!();\n    }\n}\n```"
        }
      ]
    },
    {
      "path": "forge-rs/crates/forge-generate/src/text.rs",
      "sha256": "0599fd394cf3140864002d8369ff409a85e365acf957c8e7b3186b6d8d2e8d28",
      "artifactSha256": "f6f6db2893c660e08837464a94e89e443310e0f79c8c8f5ef399fbd7b6a1896d",
      "url": "/reference/source/forge-rs/crates/forge-generate/src/text.rs.txt",
      "declarations": [
        {
          "name": "::GenerateTextResult",
          "line": 64,
          "signature": "#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct GenerateTextResult {\n\n}",
          "documentation": "The result of a [`generate_text()`] call.\n\nWraps the raw [`GenerateResult`] from the model with convenience accessors\nfor common fields (text content, usage statistics, finish reason).\n\n# ANVIL Spec \u00a76.1\n\nThe cognitive interface `infer()` result must include the generated content,\ntoken usage, and finish reason.\n\n# Examples\n\n```\nuse forge_core::message::{ModelMessage, Role};\nuse forge_core::output::{FinishReason, GenerateResult, Usage};\nuse forge_generate::GenerateTextResult;\n\nlet inner = GenerateResult {\n    message: ModelMessage::text(Role::Assistant, \"Paris is the capital.\"),\n    finish_reason: FinishReason::Stop,\n    usage: Usage { prompt_tokens: 12, completion_tokens: 6, total_tokens: 18 },\n};\nlet result = GenerateTextResult::new(inner);\nassert_eq!(result.text(), \"Paris is the capital.\");\nassert!(result.finish_reason().is_complete());\n```"
        },
        {
          "name": "::GenerateTextResult::new",
          "line": 75,
          "signature": "pub fn new(inner: GenerateResult) -> Self;",
          "documentation": "Creates a new `GenerateTextResult` wrapping a `GenerateResult`.\n\n# Arguments\n\n* `inner` - The raw result from `LanguageModel::generate()`."
        },
        {
          "name": "::GenerateTextResult::text",
          "line": 98,
          "signature": "pub fn text(&self) -> String;",
          "documentation": "Returns the generated text content.\n\nConcatenates all text parts from the response message. Returns an\nempty string if the response contains no text parts (e.g., only tool calls).\n\n# Examples\n\n```\nuse forge_core::message::{ModelMessage, Role};\nuse forge_core::output::{FinishReason, GenerateResult, Usage};\nuse forge_generate::GenerateTextResult;\n\nlet result = GenerateTextResult::new(GenerateResult {\n    message: ModelMessage::text(Role::Assistant, \"Hello!\"),\n    finish_reason: FinishReason::Stop,\n    usage: Usage::zero(),\n});\nassert_eq!(result.text(), \"Hello!\");\n```"
        },
        {
          "name": "::GenerateTextResult::usage",
          "line": 107,
          "signature": "pub fn usage(&self) -> &Usage;",
          "documentation": "Returns the token usage statistics.\n\n# Returns\n\nA [`Usage`] struct with prompt, completion, and total token counts."
        },
        {
          "name": "::GenerateTextResult::finish_reason",
          "line": 117,
          "signature": "pub fn finish_reason(&self) -> FinishReason;",
          "documentation": "Returns why generation stopped.\n\n# Returns\n\nA [`FinishReason`] indicating whether the model stopped naturally,\nhit a token limit, requested tool calls, etc."
        },
        {
          "name": "::GenerateTextResult::message",
          "line": 124,
          "signature": "pub fn message(&self) -> &ModelMessage;",
          "documentation": "Returns the full response message from the model.\n\nUse this when you need access to multi-part content (e.g., text + tool calls)."
        },
        {
          "name": "::GenerateTextResult::has_tool_calls",
          "line": 129,
          "signature": "pub fn has_tool_calls(&self) -> bool;",
          "documentation": "Returns `true` if the response contains tool call requests."
        },
        {
          "name": "::GenerateTextResult::into_inner",
          "line": 134,
          "signature": "pub fn into_inner(self) -> GenerateResult;",
          "documentation": "Consumes this result and returns the underlying [`GenerateResult`]."
        },
        {
          "name": "::generate_text",
          "line": 187,
          "signature": "pub async fn generate_text(\n    model: &dyn LanguageModel,\n    messages: &[ModelMessage],\n    tools: &[ToolDefinition],\n    options: &GenerateOptions,\n) -> Result<GenerateTextResult, ForgeGenerateError>;",
          "documentation": "Generates a complete text response from a language model.\n\nThis is the primary entry point for buffered (non-streaming) inference. It\nsends the conversation history and available tools to the model, waits for\nthe complete response, and returns it wrapped in a [`GenerateTextResult`].\n\n# ANVIL Spec \u00a76.1\n\nImplements the `infer()` operation defined by the ANVIL cognitive interface.\n\n# Arguments\n\n* `model` - The language model to use for generation.\n* `messages` - The conversation history (system, user, assistant, tool messages).\n* `tools` - Available tool definitions the model may call. Pass an empty slice\n  if no tools are available.\n* `options` - Generation options (temperature, max_tokens, etc.).\n\n# Returns\n\nA [`GenerateTextResult`] containing the model's response, usage statistics,\nand finish reason.\n\n# Errors\n\n* [`ForgeGenerateError::ModelError`] \u2014 if the underlying model call fails.\n* [`ForgeGenerateError::NoResponse`] \u2014 if the model returns empty content.\n\n# Examples\n\n```no_run\nuse forge_core::config::GenerateOptions;\nuse forge_core::message::{ModelMessage, Role};\nuse forge_core::model::LanguageModel;\nuse forge_generate::generate_text;\n\nasync fn example(model: &dyn LanguageModel) {\n    let messages = vec![\n        ModelMessage::text(Role::System, \"You are a helpful assistant.\"),\n        ModelMessage::text(Role::User, \"What is 2+2?\"),\n    ];\n    let result = generate_text(model, &messages, &[], &GenerateOptions::default()).await;\n    match result {\n        Ok(r) => println!(\"Response: {}\", r.text()),\n        Err(e) => eprintln!(\"Generation failed: {e}\"),\n    }\n}\n```"
        }
      ]
    }
  ]
}
