> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryorbitai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Outputs

> Result structures and formats from task execution, agents, and orbits in OrbitAI workflows.

## Overview

Outputs are the results generated by agents executing tasks within orbits. OrbitAI provides a comprehensive output system that supports multiple formats, type-safe structured data, and rich metadata about execution.

<CardGroup cols={3}>
  <Card title="Multiple Formats" icon="file-code">
    Text, JSON, Markdown, CSV, XML, and structured
  </Card>

  <Card title="Type Safety" icon="shield-check">
    Strongly-typed structured outputs with Codable
  </Card>

  <Card title="Rich Metadata" icon="tags">
    Usage metrics, tool usage, timestamps
  </Card>

  <Card title="Fallback Parsing" icon="life-ring">
    Automatic error recovery for malformed outputs
  </Card>

  <Card title="Validation" icon="check-double">
    Schema validation for structured data
  </Card>

  <Card title="Traceability" icon="route">
    Track which agent produced which output
  </Card>
</CardGroup>

### What are Outputs?

**Outputs** are the structured results from task execution that contain:

* The actual generated content (raw or structured)
* Metadata about execution (agent, task, timestamps)
* Usage metrics (tokens, API calls)
* Tool execution information
* Validation results

<Info>
  Outputs provide complete traceability and observability into what agents produced and how they accomplished their tasks.
</Info>

### Key Characteristics

<AccordionGroup>
  <Accordion title="Multi-Format Support" icon="layer-group">
    Outputs can be in various formats to suit different use cases:

    ```swift theme={null}
    // Plain text
    let textOutput = TaskOutput(rawOutput: "Analysis complete")

    // Structured JSON
    let jsonOutput = TaskOutput(
        rawOutput: #"{"status": "success", "count": 42}"#,
        structuredOutput: parsedJSON
    )

    // Type-safe structure
    let typedOutput = StructuredTaskOutput(
        data: AnalysisResult(findings: [...]),
        rawOutput: jsonString
    )
    ```
  </Accordion>

  <Accordion title="Metadata Enrichment" icon="info-circle">
    Every output includes comprehensive metadata:

    ```swift theme={null}
    public struct TaskOutput {
        let rawOutput: String              // The actual content
        let usageMetrics: UsageMetrics    // Token usage
        let toolsUsed: [ToolUsage]        // Tool execution data
        let agentId: OrbitAIID            // Which agent produced this
        let taskId: OrbitAIID             // For which task
        let timestamp: Date               // When it was generated
    }
    ```
  </Accordion>

  <Accordion title="Type Safety" icon="shield-check">
    Use Swift's type system for compile-time safety:

    ```swift theme={null}
    struct Report: Codable, Sendable {
        let title: String
        let summary: String
        let findings: [Finding]
    }

    // Type-safe access
    let report: Report = try output.decode(as: Report.self)
    // Compiler ensures correct types
    ```
  </Accordion>

  <Accordion title="Error Recovery" icon="wrench">
    Automatic fallback strategies for parsing failures:

    ```swift theme={null}
    // Attempts multiple parsing strategies
    let data = try output.decodeWithFallback(as: Report.self)

    // Fallback order:
    // 1. Direct decode
    // 2. Unwrap common wrappers
    // 3. Normalize field names
    // 4. Partial extraction with defaults
    // 5. Clean markdown artifacts
    ```
  </Accordion>
</AccordionGroup>

## Output Types

### TaskOutput

The result from a single task execution.

<Tabs>
  <Tab title="Structure">
    ```swift theme={null}
    public struct TaskOutput: Codable, Sendable {
        // Core content
        public let rawOutput: String
        public let structuredOutput: StructuredOutput?

        // Execution metadata
        public let usageMetrics: UsageMetrics
        public let toolsUsed: [ToolUsage]

        // Traceability
        public let agentId: OrbitAIID
        public let taskId: OrbitAIID
        public let timestamp: Date

        // Validation (if applicable)
        public let validationResult: TaskValidationResult?
    }
    ```

    | Property           | Type                    | Description                |
    | ------------------ | ----------------------- | -------------------------- |
    | `rawOutput`        | `String`                | Raw text output from agent |
    | `structuredOutput` | `StructuredOutput?`     | Parsed structured data     |
    | `usageMetrics`     | `UsageMetrics`          | Token and API usage stats  |
    | `toolsUsed`        | `[ToolUsage]`           | Tools executed during task |
    | `agentId`          | `OrbitAIID`             | Agent that produced output |
    | `taskId`           | `OrbitAIID`             | Task that was executed     |
    | `timestamp`        | `Date`                  | When output was generated  |
    | `validationResult` | `TaskValidationResult?` | Manager validation result  |
  </Tab>

  <Tab title="Creating">
    ```swift theme={null}
    // TaskOutput is typically created by the system
    // But you can create manually if needed

    let output = TaskOutput(
        rawOutput: "Analysis complete. Found 42 anomalies.",
        structuredOutput: nil,
        usageMetrics: UsageMetrics(
            promptTokens: 150,
            completionTokens: 50,
            totalTokens: 200,
            successfulRequests: 1,
            totalRequests: 1
        ),
        toolsUsed: [
            ToolUsage(
                toolName: "data_analyzer",
                executionTime: 2.5,
                success: true,
                inputSize: 1024,
                outputSize: 512
            )
        ],
        agentId: analyst.id,
        taskId: task.id,
        timestamp: Date()
    )
    ```
  </Tab>

  <Tab title="Accessing">
    ```swift theme={null}
    // Basic access
    print("Output: \(output.rawOutput)")
    print("Agent: \(output.agentId)")
    print("Tokens used: \(output.usageMetrics.totalTokens)")

    // Check tools used
    for toolUsage in output.toolsUsed {
        print("Tool: \(toolUsage.toolName)")
        print("  Time: \(toolUsage.executionTime)s")
        print("  Success: \(toolUsage.success)")
    }

    // Access structured output
    if let structured = output.structuredOutput {
        print("Structured data available")
    }
    ```
  </Tab>

  <Tab title="Type-Safe Decoding">
    ```swift theme={null}
    // Define expected structure
    struct AnalysisResult: Codable, Sendable {
        let summary: String
        let anomalies: Int
        let severity: String
        let recommendations: [String]
    }

    // Decode with type safety
    do {
        let result = try output.decode(as: AnalysisResult.self)

        print("Summary: \(result.summary)")
        print("Anomalies: \(result.anomalies)")
        print("Severity: \(result.severity)")

        for rec in result.recommendations {
            print("- \(rec)")
        }
    } catch {
        print("Failed to decode: \(error)")
        // Fall back to raw output
        print("Raw: \(output.rawOutput)")
    }
    ```
  </Tab>
</Tabs>

### OrbitOutput

The aggregated result from an entire orbit execution.

<Tabs>
  <Tab title="Structure">
    ```swift theme={null}
    public struct OrbitOutput: Codable, Sendable {
        // Task results
        public let taskOutputs: [TaskOutput]

        // Aggregated metrics
        public let usageMetrics: UsageMetrics

        // Execution timing
        public let executionTime: TimeInterval

        // Orbit metadata
        public let orbitId: OrbitAIID
        public let orbitName: String
        public let completedAt: Date

        // Process information
        public let processType: Process?
    }
    ```

    | Property        | Type           | Description                  |
    | --------------- | -------------- | ---------------------------- |
    | `taskOutputs`   | `[TaskOutput]` | All task results in order    |
    | `usageMetrics`  | `UsageMetrics` | Total usage across all tasks |
    | `executionTime` | `TimeInterval` | Total execution duration     |
    | `orbitId`       | `OrbitAIID`    | Orbit identifier             |
    | `orbitName`     | `String`       | Human-readable orbit name    |
    | `completedAt`   | `Date`         | Completion timestamp         |
    | `processType`   | `Process?`     | Sequential/Hierarchical/etc  |
  </Tab>

  <Tab title="Accessing">
    ```swift theme={null}
    let result = try await orbit.start()

    // Access all outputs
    print("Total tasks: \(result.taskOutputs.count)")

    for (index, output) in result.taskOutputs.enumerated() {
        print("\n=== Task \(index) ===")
        print("Output: \(output.rawOutput)")
        print("Agent: \(output.agentId)")
        print("Tokens: \(output.usageMetrics.totalTokens)")
    }

    // Aggregated metrics
    print("\n=== Total Metrics ===")
    print("Tokens: \(result.usageMetrics.totalTokens)")
    print("  Prompt: \(result.usageMetrics.promptTokens)")
    print("  Completion: \(result.usageMetrics.completionTokens)")
    print("API calls: \(result.usageMetrics.totalRequests)")
    print("Success rate: \(result.usageMetrics.successfulRequests)/\(result.usageMetrics.totalRequests)")

    // Timing
    print("\nExecution time: \(result.executionTime)s")
    print("Completed: \(result.completedAt)")
    ```
  </Tab>

  <Tab title="Filtering Results">
    ```swift theme={null}
    let result = try await orbit.start()

    // Get outputs from specific agent
    let analystOutputs = result.taskOutputs.filter {
        $0.agentId == analystAgent.id
    }

    // Get outputs that used specific tool
    let searchOutputs = result.taskOutputs.filter {
        $0.toolsUsed.contains { $0.toolName == "web_search" }
    }

    // Find longest execution
    let longest = result.taskOutputs.max {
        ($0.usageMetrics.totalTokens) < ($1.usageMetrics.totalTokens)
    }

    // Calculate average execution time per task
    let avgTime = result.executionTime / Double(result.taskOutputs.count)
    print("Average time per task: \(avgTime)s")
    ```
  </Tab>

  <Tab title="Exporting">
    ```swift theme={null}
    let result = try await orbit.start()

    // Export to JSON
    let encoder = JSONEncoder()
    encoder.outputFormatting = .prettyPrinted
    encoder.dateEncodingStrategy = .iso8601

    let jsonData = try encoder.encode(result)
    try jsonData.write(to: URL(fileURLWithPath: "./orbit-result.json"))

    // Export summary
    let summary = """
    Orbit: \(result.orbitName)
    Completed: \(result.completedAt)
    Tasks: \(result.taskOutputs.count)
    Tokens: \(result.usageMetrics.totalTokens)
    Time: \(result.executionTime)s
    """
    try summary.write(to: URL(fileURLWithPath: "./summary.txt"))

    // Export individual task outputs
    for (index, output) in result.taskOutputs.enumerated() {
        let filename = "./task_\(index)_output.txt"
        try output.rawOutput.write(
            toFile: filename,
            atomically: true,
            encoding: .utf8
        )
    }
    ```
  </Tab>
</Tabs>

### StructuredOutput

Parsed structured data with optional schema validation.

<Tabs>
  <Tab title="Structure">
    ```swift theme={null}
    public struct StructuredOutput: Codable, Sendable {
        // Parsed data
        public let data: Metadata

        // Schema (if validated)
        public let schema: JSONSchema?

        // Validation result
        public let isValid: Bool
        public let validationErrors: [String]?

        // Original raw output
        public let rawJSON: String
    }
    ```

    | Property           | Type          | Description               |
    | ------------------ | ------------- | ------------------------- |
    | `data`             | `Metadata`    | Parsed structured data    |
    | `schema`           | `JSONSchema?` | Validation schema used    |
    | `isValid`          | `Bool`        | Schema validation passed  |
    | `validationErrors` | `[String]?`   | Validation error messages |
    | `rawJSON`          | `String`      | Original JSON string      |
  </Tab>

  <Tab title="Creating">
    ```swift theme={null}
    // Define schema
    let schema = JSONSchema(
        type: .object,
        properties: [
            "title": JSONSchema(type: .string),
            "count": JSONSchema(type: .integer),
            "confidence": JSONSchema(type: .number)
        ],
        required: ["title", "count"]
    )

    // Parse and validate
    let jsonString = #"{"title": "Analysis", "count": 42, "confidence": 0.95}"#

    do {
        let structured = try StructuredOutput.parse(
            jsonString: jsonString,
            schema: schema
        )

        print("Valid: \(structured.isValid)")
        print("Title: \(structured.data["title"]?.stringValue ?? "")")
        print("Count: \(structured.data["count"]?.intValue ?? 0)")
    } catch {
        print("Parsing failed: \(error)")
    }
    ```
  </Tab>

  <Tab title="Validation">
    ```swift theme={null}
    let structured = try StructuredOutput.parse(
        jsonString: jsonString,
        schema: schema
    )

    if structured.isValid {
        print("✅ Valid output")
        // Process data
    } else {
        print("❌ Invalid output")
        if let errors = structured.validationErrors {
            for error in errors {
                print("  - \(error)")
            }
        }
    }

    // Access data regardless of validation
    let data = structured.data
    ```
  </Tab>
</Tabs>

## Output Formats

OrbitAI supports multiple output formats to suit different use cases.

<Tabs>
  <Tab title="Text">
    **Format**: Plain text output

    ```swift theme={null}
    let task = ORTask(
        description: "Summarize the article",
        expectedOutput: "Brief summary in plain text",
        outputFormat: .text  // Default
    )

    let result = try await orbit.start()
    let output = result.taskOutputs.first!

    // Access as string
    print(output.rawOutput)
    // "The article discusses AI trends in healthcare..."
    ```

    **Use Cases**:

    * Human-readable reports
    * Summaries
    * Descriptions
    * General text generation
  </Tab>

  <Tab title="JSON">
    **Format**: Generic JSON output

    ```swift theme={null}
    let task = ORTask(
        description: "Generate product data in JSON format",
        expectedOutput: "JSON object with product details",
        outputFormat: .json
    )

    let result = try await orbit.start()
    let output = result.taskOutputs.first!

    // Parse JSON
    if let jsonData = output.rawOutput.data(using: .utf8),
       let json = try? JSONSerialization.jsonObject(with: jsonData) as? [String: Any] {
        print("Product name: \(json["name"] ?? "")")
        print("Price: \(json["price"] ?? 0)")
    }

    // Or use structured output
    if let structured = output.structuredOutput {
        print("Name: \(structured.data["name"]?.stringValue ?? "")")
    }
    ```

    **Use Cases**:

    * API responses
    * Data interchange
    * Configuration files
    * Flexible structures
  </Tab>

  <Tab title="Markdown">
    **Format**: Markdown formatted text

    ```swift theme={null}
    let task = ORTask(
        description: "Write documentation",
        expectedOutput: "Documentation in Markdown format",
        outputFormat: .markdown
    )

    let result = try await orbit.start()
    let output = result.taskOutputs.first!

    // Output is markdown-formatted
    print(output.rawOutput)
    // # Documentation
    // ## Section 1
    // Content here...

    // Save as .md file
    try output.rawOutput.write(
        to: URL(fileURLWithPath: "./docs.md"),
        atomically: true,
        encoding: .utf8
    )
    ```

    **Use Cases**:

    * Documentation
    * Blog posts
    * README files
    * Technical writing
  </Tab>

  <Tab title="CSV">
    **Format**: Comma-separated values

    ```swift theme={null}
    let task = ORTask(
        description: "Generate sales report",
        expectedOutput: "CSV with sales data",
        outputFormat: .csv
    )

    let result = try await orbit.start()
    let output = result.taskOutputs.first!

    // Output is CSV format
    print(output.rawOutput)
    // Date,Product,Quantity,Revenue
    // 2024-01-01,Widget A,100,1000.00
    // 2024-01-02,Widget B,150,1500.00

    // Save as CSV
    try output.rawOutput.write(
        to: URL(fileURLWithPath: "./sales.csv"),
        atomically: true,
        encoding: .utf8
    )

    // Parse CSV
    let rows = output.rawOutput.components(separatedBy: "\n")
    for row in rows {
        let columns = row.components(separatedBy: ",")
        print(columns)
    }
    ```

    **Use Cases**:

    * Data exports
    * Spreadsheet imports
    * Tabular data
    * Reports
  </Tab>

  <Tab title="XML">
    **Format**: XML structured output

    ```swift theme={null}
    let task = ORTask(
        description: "Generate configuration",
        expectedOutput: "Configuration in XML format",
        outputFormat: .xml
    )

    let result = try await orbit.start()
    let output = result.taskOutputs.first!

    // Output is XML format
    print(output.rawOutput)
    // <?xml version="1.0"?>
    // <config>
    //   <setting name="timeout">30</setting>
    //   <setting name="retries">3</setting>
    // </config>

    // Parse XML
    let xmlData = output.rawOutput.data(using: .utf8)!
    let parser = XMLParser(data: xmlData)
    // ... XML parsing logic
    ```

    **Use Cases**:

    * Legacy system integration
    * Configuration files
    * SOAP APIs
    * Structured documents
  </Tab>

  <Tab title="Structured">
    **Format**: Type-safe structured output with schema

    ```swift theme={null}
    // Define schema
    let schema = JSONSchema(
        type: .object,
        properties: [
            "name": JSONSchema(type: .string),
            "age": JSONSchema(type: .integer),
            "email": JSONSchema(type: .string)
        ],
        required: ["name", "email"]
    )

    let task = ORTask(
        description: "Generate user profile",
        expectedOutput: "User profile data",
        outputFormat: .structured(schema)
    )

    let result = try await orbit.start()
    let output = result.taskOutputs.first!

    // Access validated structured output
    if let structured = output.structuredOutput {
        if structured.isValid {
            let name = structured.data["name"]?.stringValue
            let age = structured.data["age"]?.intValue
            let email = structured.data["email"]?.stringValue

            print("User: \(name ?? "Unknown")")
            print("Age: \(age ?? 0)")
            print("Email: \(email ?? "N/A")")
        }
    }
    ```

    **Use Cases**:

    * Type-safe data
    * Validated outputs
    * API contracts
    * Database inserts
  </Tab>
</Tabs>

## Structured Outputs

Comprehensive guide to creating and using type-safe structured outputs.

### Creating Structured Outputs

<Steps>
  <Step title="Define Data Structure">
    Create a Codable struct representing your desired output:

    ```swift theme={null}
    struct AnalysisReport: Codable, Sendable {
        let title: String
        let executiveSummary: String
        let findings: [Finding]
        let recommendations: [Recommendation]
        let metadata: Metadata

        struct Finding: Codable, Sendable {
            let category: String
            let description: String
            let severity: Severity
            let evidence: [String]
        }

        struct Recommendation: Codable, Sendable {
            let title: String
            let description: String
            let priority: Priority
            let estimatedImpact: String
        }

        struct Metadata: Codable, Sendable {
            let analysisDate: Date
            let analyst: String
            let confidence: Double
            let version: String
        }

        enum Severity: String, Codable {
            case critical, high, medium, low
        }

        enum Priority: String, Codable {
            case urgent, high, medium, low
        }
    }
    ```

    <Tip>
      Use nested types to organize complex data structures logically.
    </Tip>
  </Step>

  <Step title="Create Task with Structured Output">
    Use the `withStructuredOutput` factory method:

    ```swift theme={null}
    let task = ORTask.withStructuredOutput(
        description: """
        Analyze the Q4 2024 business performance data and generate
        a comprehensive report with findings and recommendations.

        Focus on:
        - Revenue trends
        - Cost analysis
        - Market position
        - Growth opportunities
        """,
        expectedType: AnalysisReport.self,
        agent: analystAgent.id,
        context: [dataTask.id]
    )
    ```

    The system automatically:

    * Generates appropriate JSON schema from the type
    * Instructs the LLM to return structured JSON
    * Validates the output against the schema
    * Provides type-safe decoding
  </Step>

  <Step title="Execute and Access">
    Execute the orbit and decode the structured output:

    ```swift theme={null}
    let orbit = try await Orbit.create(
        name: "Business Analysis",
        agents: [analystAgent],
        tasks: [task]
    )

    let result = try await orbit.start()

    // Type-safe decoding
    if let output = result.taskOutputs.first {
        do {
            let report = try output.decode(as: AnalysisReport.self)

            // Access with full type safety
            print("Title: \(report.title)")
            print("Summary: \(report.executiveSummary)")

            print("\nFindings (\(report.findings.count)):")
            for finding in report.findings {
                print("- [\(finding.severity)] \(finding.category)")
                print("  \(finding.description)")
            }

            print("\nRecommendations:")
            for rec in report.recommendations {
                print("- [\(rec.priority)] \(rec.title)")
            }

            print("\nConfidence: \(report.metadata.confidence)")
        } catch {
            print("Decoding failed: \(error)")
            // Fall back to raw output
            print("Raw output: \(output.rawOutput)")
        }
    }
    ```
  </Step>

  <Step title="Handle Decoding Errors">
    Implement fallback strategies:

    ```swift theme={null}
    // Try with automatic fallback
    let report = try output.decodeWithFallback(as: AnalysisReport.self)

    // Or handle explicitly
    do {
        let report = try output.decode(as: AnalysisReport.self)
        processReport(report)
    } catch DecodingError.keyNotFound(let key, _) {
        print("Missing key: \(key.stringValue)")
        // Try partial decode or use defaults
    } catch DecodingError.typeMismatch(let type, let context) {
        print("Type mismatch for \(type) at \(context.codingPath)")
        // Try type coercion
    } catch {
        print("Unexpected error: \(error)")
        // Fall back to raw output processing
    }
    ```
  </Step>
</Steps>

### Assigning Structured Outputs

<Tabs>
  <Tab title="Method 1: Factory">
    ```swift theme={null}
    // Using factory method (recommended)
    let task = ORTask.withStructuredOutput(
        description: "Generate user profile data",
        expectedType: UserProfile.self,
        agent: agent.id
    )
    ```

    **Benefits**:

    * Automatic schema generation
    * Type-safe at compile time
    * Clean, readable API
  </Tab>

  <Tab title="Method 2: Schema">
    ```swift theme={null}
    // Using explicit schema
    let schema = JSONSchema(
        type: .object,
        properties: [
            "name": JSONSchema(type: .string),
            "age": JSONSchema(type: .integer),
            "email": JSONSchema(
                type: .string,
                description: "Valid email address"
            ),
            "tags": JSONSchema(
                type: .array,
                items: .init(value: JSONSchema(type: .string))
            )
        ],
        required: ["name", "email"]
    )

    let task = ORTask(
        description: "Generate user profile",
        expectedOutput: "User profile in JSON",
        outputFormat: .structured(schema)
    )
    ```

    **Benefits**:

    * Full control over schema
    * Custom descriptions
    * Validation rules
  </Tab>

  <Tab title="Method 3: TypedJSON">
    ```swift theme={null}
    // Using typedJSON format
    struct Product: Codable, Sendable {
        let id: String
        let name: String
        let price: Double
        let inStock: Bool
    }

    let task = ORTask(
        description: "Generate product data",
        expectedOutput: "Product details",
        outputFormat: .typedJSON("Product")
    )

    // Later decode
    let product: Product = try output.decode(as: Product.self)
    ```

    **Benefits**:

    * Named type reference
    * Flexible decoding
    * Runtime type resolution
  </Tab>
</Tabs>

### Using Structured Outputs

<AccordionGroup>
  <Accordion title="Database Integration" icon="database">
    ```swift theme={null}
    struct Customer: Codable, Sendable {
        let id: UUID
        let name: String
        let email: String
        let phone: String
        let address: Address

        struct Address: Codable, Sendable {
            let street: String
            let city: String
            let state: String
            let zip: String
        }
    }

    // Generate customer data
    let task = ORTask.withStructuredOutput(
        description: "Generate customer record from form data",
        expectedType: Customer.self,
        agent: dataAgent.id
    )

    let result = try await orbit.start()
    let customer = try result.taskOutputs.first!.decode(as: Customer.self)

    // Insert into database
    try await database.insert(customer)
    ```
  </Accordion>

  <Accordion title="API Responses" icon="globe">
    ```swift theme={null}
    struct APIResponse: Codable, Sendable {
        let status: String
        let data: ResponseData
        let metadata: ResponseMetadata

        struct ResponseData: Codable, Sendable {
            let items: [Item]
            let total: Int
            let page: Int
        }

        struct ResponseMetadata: Codable, Sendable {
            let requestId: String
            let timestamp: Date
            let version: String
        }
    }

    // Generate API response
    let task = ORTask.withStructuredOutput(
        description: "Format query results as API response",
        expectedType: APIResponse.self,
        agent: apiAgent.id
    )

    let result = try await orbit.start()
    let response = try result.taskOutputs.first!.decode(as: APIResponse.self)

    // Return as HTTP response
    let encoder = JSONEncoder()
    encoder.dateEncodingStrategy = .iso8601
    let jsonData = try encoder.encode(response)
    return Response(body: jsonData, contentType: .json)
    ```
  </Accordion>

  <Accordion title="UI Rendering" icon="display">
    ```swift theme={null}
    struct DashboardData: Codable, Sendable {
        let title: String
        let widgets: [Widget]
        let refreshInterval: Int

        struct Widget: Codable, Sendable {
            let id: String
            let type: WidgetType
            let title: String
            let data: Metadata
            let position: Position

            enum WidgetType: String, Codable {
                case chart, table, metric, text
            }

            struct Position: Codable, Sendable {
                let x: Int
                let y: Int
                let width: Int
                let height: Int
            }
        }
    }

    // Generate dashboard configuration
    let task = ORTask.withStructuredOutput(
        description: "Create dashboard layout for sales metrics",
        expectedType: DashboardData.self,
        agent: uiAgent.id
    )

    let result = try await orbit.start()
    let dashboard = try result.taskOutputs.first!.decode(as: DashboardData.self)

    // Render UI
    await renderDashboard(dashboard)
    ```
  </Accordion>

  <Accordion title="Workflow Chaining" icon="link">
    ```swift theme={null}
    // Task 1: Generate structured data
    struct Analysis: Codable, Sendable {
        let insights: [String]
        let metrics: [String: Double]
    }

    let analysisTask = ORTask.withStructuredOutput(
        description: "Analyze data and generate insights",
        expectedType: Analysis.self,
        agent: analystAgent.id
    )

    // Task 2: Use structured output from Task 1
    struct Report: Codable, Sendable {
        let summary: String
        let details: [Detail]
    }

    let reportTask = ORTask.withStructuredOutput(
        description: """
        Create report based on analysis: {task_0_output}
        """,
        expectedType: Report.self,
        agent: reportAgent.id,
        context: [analysisTask.id]
    )

    // Execute workflow
    let result = try await orbit.start()

    // Access both structured outputs
    let analysis = try result.taskOutputs[0].decode(as: Analysis.self)
    let report = try result.taskOutputs[1].decode(as: Report.self)

    print("Insights: \(analysis.insights.count)")
    print("Report sections: \(report.details.count)")
    ```
  </Accordion>
</AccordionGroup>

### Fallback Parsing

OrbitAI includes sophisticated fallback strategies for handling malformed outputs:

<Steps>
  <Step title="Direct Decoding">
    First attempt: Standard JSONDecoder

    ```swift theme={null}
    let decoder = JSONDecoder()
    return try decoder.decode(T.self, from: jsonData)
    ```
  </Step>

  <Step title="Wrapper Unwrapping">
    Handle common wrapper patterns:

    ```swift theme={null}
    // LLM might wrap in: {"data": {...}}
    let wrapperKeys = ["data", "result", "response", "content"]

    for key in wrapperKeys {
        if let wrapped = json[key] as? [String: Any] {
            // Try decoding wrapped content
        }
    }
    ```
  </Step>

  <Step title="Field Normalization">
    Map alternative field names:

    ```swift theme={null}
    // Handle snake_case vs camelCase
    decoder.keyDecodingStrategy = .convertFromSnakeCase

    // Custom key mapping
    let normalized = normalizeFieldNames(json, for: T.self)
    ```
  </Step>

  <Step title="Partial Extraction">
    Extract available fields with defaults:

    ```swift theme={null}
    // If some fields missing, use defaults
    struct PartialUser: Codable {
        let name: String
        let email: String
        let age: Int = 0  // Default
        let phone: String? = nil  // Optional
    }
    ```
  </Step>

  <Step title="Markdown Cleaning">
    Remove markdown formatting artifacts:

    ````swift theme={null}
    let cleaned = jsonString
        .replacingOccurrences(of: "```json", with: "")
        .replacingOccurrences(of: "```", with: "")
        .trimmingCharacters(in: .whitespacesAndNewlines)

    // Try parsing cleaned version
    ````
  </Step>
</Steps>

## Error Handling

### Common Output Errors

<CardGroup cols={2}>
  <Card title="Missing Output" icon="circle-exclamation">
    **Error**: Task completes but produces no output

    ```swift theme={null}
    do {
        let result = try await orbit.start()
        guard let output = result.taskOutputs.first else {
            throw OrbitAIError.taskExecutionFailed(
                "No output generated"
            )
        }
    } catch {
        print("Error: \(error)")
    }
    ```

    **Causes**:

    * Task failed silently
    * Agent produced empty response
    * Output filtering removed content
  </Card>

  <Card title="Malformed JSON" icon="code">
    **Error**: Cannot parse JSON output

    ```swift theme={null}
    do {
        let data = try output.decode(as: Report.self)
    } catch DecodingError.dataCorrupted {
        print("Invalid JSON format")
        // Use fallback parsing
        let data = try output.decodeWithFallback(as: Report.self)
    }
    ```

    **Causes**:

    * LLM generated invalid JSON
    * Extra text before/after JSON
    * Unclosed brackets/quotes
  </Card>

  <Card title="Schema Mismatch" icon="table">
    **Error**: Output doesn't match expected structure

    ```swift theme={null}
    do {
        let data = try output.decode(as: Report.self)
    } catch DecodingError.keyNotFound(let key, _) {
        print("Missing field: \(key.stringValue)")
    } catch DecodingError.typeMismatch(let type, _) {
        print("Wrong type for field: \(type)")
    }
    ```

    **Causes**:

    * LLM misunderstood schema
    * Field name variations
    * Type differences
  </Card>

  <Card title="Empty Content" icon="file-slash">
    **Error**: Output exists but content is empty

    ```swift theme={null}
    let output = result.taskOutputs.first!

    if output.rawOutput.isEmpty {
        print("Warning: Empty output")
        // Check if task failed
        if let task = orbit.tasks.first {
            print("Task status: \(task.status)")
        }
    }
    ```

    **Causes**:

    * Task execution issue
    * Agent configuration problem
    * LLM returned empty response
  </Card>
</CardGroup>

### Error Recovery Strategies

<Tabs>
  <Tab title="Graceful Fallback">
    ```swift theme={null}
    func getReportData(output: TaskOutput) -> ReportData {
        // Try structured decode
        if let structured = try? output.decode(as: ReportData.self) {
            return structured
        }

        // Try fallback parsing
        if let fallback = try? output.decodeWithFallback(as: ReportData.self) {
            return fallback
        }

        // Parse raw output manually
        if let parsed = parseRawOutput(output.rawOutput) {
            return parsed
        }

        // Return minimal valid data
        return ReportData(
            title: "Error: Unable to parse report",
            summary: output.rawOutput,
            findings: [],
            recommendations: []
        )
    }
    ```
  </Tab>

  <Tab title="Retry with Clarification">
    ```swift theme={null}
    func executeWithRetry(
        task: ORTask,
        expectedType: Report.Type,
        maxRetries: Int = 2
    ) async throws -> Report {
        var lastError: Error?

        for attempt in 1...maxRetries {
            let result = try await orbit.start()
            let output = result.taskOutputs.first!

            do {
                return try output.decode(as: Report.self)
            } catch {
                lastError = error

                if attempt < maxRetries {
                    // Create clarification task
                    let clarificationTask = ORTask(
                        description: """
                        Previous output had parsing errors: \(error)

                        Please generate the report again with valid JSON.
                        Ensure all required fields are present.
                        """,
                        expectedOutput: "Valid JSON report",
                        outputFormat: .structured(reportSchema)
                    )

                    // Retry with clarification
                    // ... recreate orbit with clarification task
                }
            }
        }

        throw lastError ?? OrbitAIError.taskExecutionFailed("Max retries exceeded")
    }
    ```
  </Tab>

  <Tab title="Partial Success">
    ```swift theme={null}
    // Handle partial outputs
    struct PartialReport: Codable, Sendable {
        let title: String?
        let summary: String?
        let findings: [Finding]?
        let recommendations: [Recommendation]?

        // Convert to complete report with defaults
        func toComplete() -> Report {
            return Report(
                title: title ?? "Untitled Report",
                summary: summary ?? "No summary available",
                findings: findings ?? [],
                recommendations: recommendations ?? []
            )
        }
    }

    // Try parsing as partial
    if let partial = try? output.decode(as: PartialReport.self) {
        let complete = partial.toComplete()
        print("Warning: Partial data, filled with defaults")
        return complete
    }
    ```
  </Tab>

  <Tab title="Validation & Repair">
    ````swift theme={null}
    func validateAndRepair(_ output: TaskOutput) -> TaskOutput {
        // Try to decode
        guard let data = try? output.decode(as: Report.self) else {
            // Attempt repair
            let repairedJSON = repairJSON(output.rawOutput)

            // Create new output with repaired JSON
            return TaskOutput(
                rawOutput: repairedJSON,
                structuredOutput: nil,
                usageMetrics: output.usageMetrics,
                toolsUsed: output.toolsUsed,
                agentId: output.agentId,
                taskId: output.taskId,
                timestamp: output.timestamp
            )
        }

        return output
    }

    func repairJSON(_ json: String) -> String {
        var repaired = json

        // Remove markdown code blocks
        repaired = repaired
            .replacingOccurrences(of: "```json", with: "")
            .replacingOccurrences(of: "```", with: "")

        // Fix common issues
        repaired = repaired
            .replacingOccurrences(of: "\\n", with: " ")
            .replacingOccurrences(of: "'", with: "\"")

        // Balance brackets
        repaired = balanceBrackets(repaired)

        return repaired
    }
    ````
  </Tab>
</Tabs>

## Best Practices

### Output Design

<CardGroup cols={2}>
  <Card title="Clear Structure" icon="sitemap">
    **Do**: Define clear, well-organized structures

    ```swift theme={null}
    // Good: Logical organization
    struct Report: Codable {
        let metadata: Metadata
        let content: Content
        let appendices: [Appendix]

        struct Metadata: Codable {
            let title: String
            let author: String
            let date: Date
        }
    }

    // Bad: Flat, disorganized
    struct Report: Codable {
        let title: String
        let thing1: String
        let data: [String]
        let misc: String
    }
    ```
  </Card>

  <Card title="Appropriate Types" icon="shapes">
    **Do**: Use specific types

    ```swift theme={null}
    // Good
    struct Product: Codable {
        let id: UUID
        let price: Decimal
        let inStock: Bool
        let category: Category

        enum Category: String, Codable {
            case electronics, clothing, books
        }
    }

    // Bad
    struct Product: Codable {
        let id: String  // Should be UUID
        let price: String  // Should be number
        let inStock: String  // Should be Bool
        let category: String  // Should be enum
    }
    ```
  </Card>

  <Card title="Optional vs Required" icon="asterisk">
    **Do**: Make intentional choices

    ```swift theme={null}
    struct User: Codable {
        // Required fields
        let id: UUID
        let email: String
        let name: String

        // Optional fields
        let phone: String?
        let bio: String?
        let avatar: URL?

        // With defaults
        let role: String = "user"
        let active: Bool = true
    }
    ```
  </Card>

  <Card title="Documentation" icon="book">
    **Do**: Document expected structures

    ```swift theme={null}
    /// Represents an analysis report with findings
    /// and recommendations.
    struct AnalysisReport: Codable {
        /// Report title (max 100 chars)
        let title: String

        /// Executive summary (200-500 words)
        let summary: String

        /// Detailed findings (3-10 items)
        let findings: [Finding]

        /// Actionable recommendations (min 2)
        let recommendations: [Recommendation]
    }
    ```
  </Card>
</CardGroup>

### Performance

<Steps>
  <Step title="Minimize Output Size">
    ```swift theme={null}
    // Good: Concise outputs
    struct Summary: Codable {
        let keyPoints: [String]  // Top 5 only
        let metrics: [String: Double]  // Essential metrics
    }

    // Avoid: Unnecessarily large outputs
    struct VerboseSummary: Codable {
        let entireDocument: String  // Don't include full text
        let everyMetric: [String: Any]  // Don't include everything
    }
    ```
  </Step>

  <Step title="Use Streaming for Large Outputs">
    ```swift theme={null}
    // For large content generation
    let stream = try await manager.generateStreamingCompletion(
        request: request
    )

    var fullOutput = ""
    for try await chunk in stream {
        fullOutput += chunk.content ?? ""
        // Process incrementally
        await updateUI(chunk.content)
    }
    ```
  </Step>

  <Step title="Cache Common Outputs">
    ```swift theme={null}
    actor OutputCache {
        private var cache: [String: TaskOutput] = [:]

        func get(_ key: String) -> TaskOutput? {
            return cache[key]
        }

        func set(_ key: String, output: TaskOutput) {
            cache[key] = output
        }
    }

    // Use for repeated queries
    let cacheKey = "\(task.description)-\(inputs.hashValue)"
    if let cached = await cache.get(cacheKey) {
        return cached
    }
    ```
  </Step>
</Steps>

### Type Safety

<AccordionGroup>
  <Accordion title="Leverage Enums" icon="list">
    ```swift theme={null}
    struct Analysis: Codable {
        let status: Status
        let priority: Priority
        let category: Category

        enum Status: String, Codable {
            case pending, inProgress, completed, failed
        }

        enum Priority: String, Codable {
            case low, medium, high, critical
        }

        enum Category: String, Codable {
            case bug, feature, improvement, documentation
        }
    }

    // Type-safe access
    if analysis.priority == .critical {
        // Handle critical priority
    }
    ```
  </Accordion>

  <Accordion title="Use Nested Types" icon="layer-group">
    ```swift theme={null}
    struct Order: Codable {
        let id: UUID
        let customer: Customer
        let items: [Item]
        let payment: Payment
        let shipping: Shipping

        struct Customer: Codable {
            let id: UUID
            let name: String
            let email: String
        }

        struct Item: Codable {
            let productId: UUID
            let quantity: Int
            let price: Decimal
        }

        struct Payment: Codable {
            let method: PaymentMethod
            let amount: Decimal
            let status: PaymentStatus

            enum PaymentMethod: String, Codable {
                case card, paypal, bankTransfer
            }

            enum PaymentStatus: String, Codable {
                case pending, completed, failed
            }
        }

        struct Shipping: Codable {
            let address: Address
            let method: ShippingMethod
            let tracking: String?

            struct Address: Codable {
                let street: String
                let city: String
                let state: String
                let zip: String
                let country: String
            }

            enum ShippingMethod: String, Codable {
                case standard, express, overnight
            }
        }
    }
    ```
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Output Not Generated" icon="circle-question">
    **Symptoms**: Task completes but no output

    **Debug Steps**:

    ```swift theme={null}
    // Check task status
    let tasks = await orbit.getTasks()
    for task in tasks {
        print("Task: \(task.description)")
        print("Status: \(task.status)")
        if let result = task.result {
            switch result {
            case .success(let output):
                print("Output: \(output.rawOutput)")
            case .failure(let error):
                print("Error: \(error)")
            }
        }
    }

    // Check agent configuration
    let agents = await orbit.getAgents()
    for agent in agents {
        print("Agent: \(agent.role)")
        print("Tools: \(await agent.getToolNames())")
    }
    ```

    **Solutions**:

    * Verify agent has proper configuration
    * Check task description is clear
    * Enable verbose logging
    * Verify LLM provider is working
  </Accordion>

  <Accordion title="JSON Parsing Fails" icon="code">
    **Symptoms**: DecodingError when parsing output

    **Debug Steps**:

    ````swift theme={null}
    // Print raw output
    print("Raw output:")
    print(output.rawOutput)

    // Try parsing manually
    if let jsonData = output.rawOutput.data(using: .utf8) {
        do {
            let json = try JSONSerialization.jsonObject(with: jsonData)
            print("Valid JSON:")
            print(json)
        } catch {
            print("Invalid JSON: \(error)")

            // Check for common issues
            if output.rawOutput.contains("```") {
                print("Contains markdown code blocks")
            }
            if !output.rawOutput.hasPrefix("{") && !output.rawOutput.hasPrefix("[") {
                print("Extra text before JSON")
            }
        }
    }
    ````

    **Solutions**:

    ````swift theme={null}
    // Use fallback parsing
    let data = try output.decodeWithFallback(as: Report.self)

    // Or clean manually
    let cleaned = output.rawOutput
        .replacingOccurrences(of: "```json", with: "")
        .replacingOccurrences(of: "```", with: "")
        .trimmingCharacters(in: .whitespacesAndNewlines)

    // Extract JSON from text
    if let range = cleaned.range(of: #"\{[\s\S]*\}"#, options: .regularExpression) {
        let jsonOnly = String(cleaned[range])
        // Parse jsonOnly
    }
    ````
  </Accordion>

  <Accordion title="Schema Validation Fails" icon="clipboard-check">
    **Symptoms**: Valid JSON but doesn't match schema

    **Debug**:

    ```swift theme={null}
    if let structured = output.structuredOutput {
        print("Valid: \(structured.isValid)")

        if !structured.isValid {
            print("Validation errors:")
            for error in structured.validationErrors ?? [] {
                print("  - \(error)")
            }
        }

        // Inspect actual structure
        print("Actual data:")
        printStructure(structured.data)
    }

    func printStructure(_ metadata: Metadata, indent: Int = 0) {
        let spacing = String(repeating: "  ", count: indent)

        switch metadata {
        case .dictionary(let dict):
            for (key, value) in dict {
                print("\(spacing)\(key): \(type(of: value))")
                printStructure(value, indent: indent + 1)
            }
        case .array(let items):
            print("\(spacing)Array(\(items.count) items)")
        default:
            print("\(spacing)\(metadata)")
        }
    }
    ```

    **Solutions**:

    * Adjust schema to match actual output
    * Provide clearer instructions to LLM
    * Use examples in task description
    * Lower validation strictness
  </Accordion>

  <Accordion title="Type Mismatches" icon="not-equal">
    **Symptoms**: DecodingError.typeMismatch

    **Common Causes**:

    ```swift theme={null}
    // Expected Int, got String
    struct Data: Codable {
        let count: Int
    }
    // LLM output: {"count": "42"}

    // Expected Array, got single value
    struct Data: Codable {
        let tags: [String]
    }
    // LLM output: {"tags": "tag1"}
    ```

    **Solutions**:

    ```swift theme={null}
    // Use flexible types
    struct FlexibleData: Codable {
        let count: FlexibleInt
        let tags: FlexibleArray<String>
    }

    // Custom decoding
    struct Data: Codable {
        let count: Int

        init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)

            // Try Int first, then String
            if let intValue = try? container.decode(Int.self, forKey: .count) {
                count = intValue
            } else if let stringValue = try? container.decode(String.self, forKey: .count),
                      let intValue = Int(stringValue) {
                count = intValue
            } else {
                count = 0  // Default
            }
        }
    }
    ```
  </Accordion>

  <Accordion title="Incomplete Outputs" icon="file-slash">
    **Symptoms**: Output missing expected fields

    **Debug**:

    ```swift theme={null}
    do {
        let report = try output.decode(as: Report.self)
    } catch DecodingError.keyNotFound(let key, let context) {
        print("Missing key: \(key.stringValue)")
        print("Context: \(context.codingPath)")
        print("Debug description: \(context.debugDescription)")

        // Check what's actually present
        if let json = try? JSONSerialization.jsonObject(
            with: output.rawOutput.data(using: .utf8)!
        ) as? [String: Any] {
            print("Available keys: \(json.keys)")
        }
    }
    ```

    **Solutions**:

    ```swift theme={null}
    // Make fields optional
    struct Report: Codable {
        let title: String
        let summary: String
        let findings: [Finding]?  // Optional
        let recommendations: [Recommendation]?  // Optional
    }

    // Or provide defaults
    struct Report: Codable {
        let title: String
        let summary: String
        let findings: [Finding] = []
        let recommendations: [Recommendation] = []
    }

    // Or decode partially
    let partial = try output.decode(as: PartialReport.self)
    let complete = partial.fillDefaults()
    ```
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Inputs" icon="arrow-right-to-bracket" href="/Inputs">
    Learn about orbit inputs
  </Card>

  <Card title="Tasks" icon="list-check" href="/tasks">
    Configure task output formats
  </Card>

  <Card title="Agents" icon="robot" href="/agents">
    Understand agent output generation
  </Card>

  <Card title="Orbits" icon="satellite" href="/orbits">
    Access orbit-level outputs
  </Card>
</CardGroup>

<Note>
  For additional support, consult the [GitHub Discussions](https://github.com/tryorbitai/orbit-ai-swift/discussions) or check the [Issue Tracker](https://github.com/tryorbitai/orbit-ai-swift/issues).
</Note>
