{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://github.com/andrewhuot/headless-chat-sdk/schemas/messages.schema.json",
  "title": "ChatMessage and ChatMessagePart",
  "description": "Generated from packages/gecx-chat/src/messages/types.ts. Each part variant extends BasePart with a stable id.",
  "definitions": {
    "BasePart": {
      "type": "object",
      "required": ["id", "type"],
      "properties": { "id": { "type": "string" } }
    },
    "BotToBotRouteDecision": {
      "type": "object",
      "required": ["from", "to", "latencyMs"],
      "properties": {
        "from": { "type": "string" },
        "to": { "type": "string" },
        "latencyMs": { "type": "number", "minimum": 0 },
        "reason": { "type": "string" },
        "ruleIndex": { "type": ["integer", "null"] },
        "intentLabel": { "type": "string" },
        "intentConfidence": { "type": "number", "minimum": 0, "maximum": 1 }
      }
    },
    "TextPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "text"],
          "properties": { "type": { "const": "text" }, "text": { "type": "string" } }
        }
      ]
    },
    "TextDeltaPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "delta"],
          "properties": { "type": { "const": "text-delta" }, "delta": { "type": "string" } }
        }
      ]
    },
    "MarkdownPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "markdown"],
          "properties": { "type": { "const": "markdown" }, "markdown": { "type": "string" } }
        }
      ]
    },
    "CitationPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "title", "url"],
          "properties": {
            "type": { "const": "citation" },
            "title": { "type": "string" },
            "url": { "type": "string", "format": "uri" },
            "snippet": { "type": "string" }
          }
        }
      ]
    },
    "SuggestionChipPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "chips"],
          "properties": {
            "type": { "const": "suggestion-chips" },
            "chips": {
              "type": "array",
              "items": {
                "type": "object",
                "required": ["label"],
                "properties": { "label": { "type": "string" }, "value": { "type": "string" } }
              }
            },
            "payloadVersion": { "type": "integer", "minimum": 1 }
          }
        }
      ]
    },
    "ProductCarouselPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "products"],
          "properties": {
            "type": { "const": "product-carousel" },
            "products": {
              "type": "array",
              "items": {
                "type": "object",
                "required": ["id", "title"],
                "properties": {
                  "id": { "type": "string" },
                  "title": { "type": "string" },
                  "description": { "type": "string" },
                  "imageUrl": { "type": "string", "format": "uri" },
                  "price": { "type": "string" },
                  "currency": { "type": "string" },
                  "url": { "type": "string", "format": "uri" },
                  "metadata": { "type": "object", "additionalProperties": true }
                }
              }
            },
            "payloadVersion": { "type": "integer", "minimum": 1 }
          }
        }
      ]
    },
    "OrderSummaryPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "orderId", "items", "subtotal", "total"],
          "properties": {
            "type": { "const": "order-summary" },
            "orderId": { "type": "string" },
            "items": {
              "type": "array",
              "items": {
                "type": "object",
                "required": ["name", "quantity", "price"],
                "properties": {
                  "name": { "type": "string" },
                  "quantity": { "type": "integer", "minimum": 1 },
                  "price": { "type": "string" }
                }
              }
            },
            "subtotal": { "type": "string" },
            "tax": { "type": "string" },
            "shipping": { "type": "string" },
            "total": { "type": "string" },
            "currency": { "type": "string" },
            "status": { "type": "string" },
            "payloadVersion": { "type": "integer", "minimum": 1 }
          }
        }
      ]
    },
    "CustomPayloadPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "payloadType", "data"],
          "properties": {
            "type": { "const": "custom" },
            "payloadType": { "type": "string" },
            "data": { "type": "object" },
            "payloadVersion": { "type": "integer", "minimum": 1 }
          }
        }
      ]
    },
    "ToolCallPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "toolCallId", "toolName", "input", "status"],
          "properties": {
            "type": { "const": "tool-call" },
            "toolCallId": { "type": "string" },
            "toolName": { "type": "string" },
            "input": { "type": "object" },
            "status": {
              "type": "string",
              "enum": ["requested", "awaiting_approval", "pending_supervisor", "async_pending", "approved", "denied", "executing", "completed", "failed", "timed_out", "duplicate"]
            },
            "output": { "type": "object" },
            "error": { "type": "string" },
            "idempotencyKey": { "type": "string" },
            "duplicateDisposition": { "type": "string", "enum": ["replayed", "rejected", "conflict"] },
            "approvalPolicy": { "type": "string", "enum": ["auto", "user_confirm", "supervisor_approve", "denied", "async_pending"] }
          }
        }
      ]
    },
    "ToolResultPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "toolCallId", "toolName", "output"],
          "properties": {
            "type": { "const": "tool-result" },
            "toolCallId": { "type": "string" },
            "toolName": { "type": "string" },
            "output": { "type": "object" },
            "error": { "type": "string" }
          }
        }
      ]
    },
    "FilePart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "fileName", "mimeType", "sizeBytes"],
          "properties": {
            "type": { "const": "file" },
            "attachmentId": { "type": "string" },
            "fileName": { "type": "string" },
            "mimeType": { "type": "string" },
            "sizeBytes": { "type": "integer", "minimum": 0 },
            "url": { "type": "string", "format": "uri" },
            "uploadStatus": { "type": "string", "enum": ["pending", "uploading", "completed", "failed"] },
            "uploadProgress": { "type": "number", "minimum": 0, "maximum": 100 },
            "lifecycleStatus": {
              "type": "string",
              "enum": ["selected", "validating", "rejected", "queued", "uploading", "uploaded", "scan_pending", "scan_failed", "ready_to_send", "sent", "failed", "removed"]
            },
            "preview": {
              "type": "object",
              "required": ["kind", "fileName", "mimeType", "sizeBytes"],
              "additionalProperties": false,
              "properties": {
                "kind": { "type": "string", "enum": ["image", "text", "pdf", "binary"] },
                "fileName": { "type": "string" },
                "mimeType": { "type": "string" },
                "sizeBytes": { "type": "integer", "minimum": 0 }
              }
            },
            "scanStatus": { "type": "string", "enum": ["not_required", "pending", "passed", "failed"] },
            "metadata": { "type": "object" }
          }
        }
      ]
    },
    "AgentTransferPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "status"],
          "properties": {
            "type": { "const": "agent-transfer" },
            "status": { "type": "string", "enum": ["none", "requested", "queued", "connecting", "ringing", "connected", "on_hold", "ended", "failed", "cancelled", "completed"] },
            "transferType": { "type": "string", "enum": ["bot_to_human", "human_to_human", "supervisor_consult", "blind", "warm", "bot_to_bot"] },
            "targetAgent": { "type": "string" },
            "reason": { "type": "string" },
            "queuePosition": { "type": "integer", "minimum": 0 },
            "estimatedWaitTime": { "type": "string" },
            "estimatedWaitMs": { "type": "integer", "minimum": 0 },
            "failureReason": { "type": "string" },
            "warmContext": {
              "type": "object",
              "properties": {
                "summary": { "type": "string" },
                "intentTags": { "type": "array", "items": { "type": "string" } },
                "sentiment": { "type": "string", "enum": ["positive", "neutral", "negative", "mixed"] },
                "customAttributes": { "type": "object", "additionalProperties": { "type": ["string", "number", "boolean"] } }
              }
            },
            "voice": {
              "type": "object",
              "required": ["sipUri"],
              "properties": {
                "sipUri": { "type": "string" },
                "callerId": { "type": "string" },
                "codec": { "type": "string" },
                "dtmfSupported": { "type": "boolean" }
              }
            },
            "bundleId": { "type": "string" },
            "routeDecision": { "$ref": "#/definitions/BotToBotRouteDecision" },
            "graphPath": { "type": "array", "items": { "type": "string" } }
          }
        }
      ]
    },
    "DiagnosticPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "category", "message", "timestamp"],
          "properties": {
            "type": { "const": "diagnostic" },
            "category": { "type": "string" },
            "message": { "type": "string" },
            "details": { "type": "object" },
            "timestamp": { "type": "string", "format": "date-time" }
          }
        }
      ]
    },
    "EndSessionPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "reason"],
          "properties": {
            "type": { "const": "end-session" },
            "reason": { "type": "string", "enum": ["completed", "timeout", "error", "user_ended", "agent_ended", "handoff_completed"] },
            "message": { "type": "string" }
          }
        }
      ]
    },
    "ErrorPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "code", "message"],
          "properties": {
            "type": { "const": "error" },
            "code": { "type": "string" },
            "message": { "type": "string" },
            "userMessage": { "type": "string" },
            "developerHint": { "type": "string" },
            "docsUrl": { "type": "string", "format": "uri" },
            "retryable": { "type": "boolean" }
          }
        }
      ]
    },
    "A2UISurfacePart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "surfaceId", "protocolVersion", "catalogId", "components", "dataModel", "status"],
          "properties": {
            "type": { "const": "a2ui-surface" },
            "surfaceId": { "type": "string" },
            "protocolVersion": { "const": "v0.9" },
            "catalogId": { "type": "string" },
            "theme": { "type": "object" },
            "components": {
              "type": "array",
              "items": {
                "type": "object",
                "required": ["id", "component"],
                "properties": {
                  "id": { "type": "string" },
                  "component": { "type": "string" }
                },
                "additionalProperties": true
              }
            },
            "dataModel": { "type": "object" },
            "status": { "type": "string", "enum": ["streaming", "ready", "deleted", "error"] },
            "error": {
              "type": "object",
              "required": ["code", "message"],
              "properties": {
                "code": { "type": "string" },
                "message": { "type": "string" }
              }
            },
            "metadata": {
              "type": "object",
              "properties": {
                "frameCount": { "type": "integer", "minimum": 0 },
                "lastFrameAt": { "type": "string", "format": "date-time" },
                "source": { "const": "rich-payload" }
              }
            }
          }
        }
      ]
    },
    "AudioInputPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "mimeType", "status"],
          "properties": {
            "type": { "const": "audio-input" },
            "mimeType": { "type": "string" },
            "durationMs": { "type": "number", "minimum": 0 },
            "sampleRate": { "type": "integer", "minimum": 1 },
            "channels": { "type": "integer", "minimum": 1 },
            "url": { "type": "string" },
            "retained": { "type": "boolean" },
            "status": { "type": "string", "enum": ["capturing", "completed", "cancelled", "failed"] }
          }
        }
      ]
    },
    "AudioOutputPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "mimeType", "status"],
          "properties": {
            "type": { "const": "audio-output" },
            "mimeType": { "type": "string" },
            "durationMs": { "type": "number", "minimum": 0 },
            "sampleRate": { "type": "integer", "minimum": 1 },
            "url": { "type": "string" },
            "retained": { "type": "boolean" },
            "status": { "type": "string", "enum": ["streaming", "completed", "interrupted"] },
            "playedUpToMs": { "type": "number", "minimum": 0 }
          }
        }
      ]
    },
    "TranscriptPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "role", "text", "interim"],
          "properties": {
            "type": { "const": "transcript" },
            "role": { "type": "string", "enum": ["user", "assistant"] },
            "text": { "type": "string" },
            "interim": { "type": "boolean" },
            "confidence": { "type": "number", "minimum": 0, "maximum": 1 },
            "language": { "type": "string" },
            "audioRefId": { "type": "string" }
          }
        }
      ]
    },
    "AudioCuePart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "cue"],
          "properties": {
            "type": { "const": "audio-cue" },
            "cue": {
              "type": "string",
              "enum": [
                "end-of-turn",
                "barge-in",
                "silence-threshold-hit",
                "speech-started",
                "session-ready",
                "session-ended"
              ]
            },
            "responseId": { "type": "string" },
            "metadata": { "type": "object" }
          }
        }
      ]
    },
    "VisionPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "kind", "mimeType"],
          "properties": {
            "type": { "const": "vision" },
            "kind": { "type": "string", "enum": ["input", "output"] },
            "mimeType": { "type": "string" },
            "url": { "type": "string" },
            "width": { "type": "integer", "minimum": 1 },
            "height": { "type": "integer", "minimum": 1 },
            "altText": { "type": "string" },
            "caption": { "type": "string" },
            "sizeBytes": { "type": "integer", "minimum": 0 }
          }
        }
      ]
    },
    "MemoryApprovalPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "candidates", "status"],
          "properties": {
            "type": { "const": "memory-approval" },
            "status": { "type": "string", "enum": ["pending", "resolved"] },
            "candidates": {
              "type": "array",
              "items": {
                "type": "object",
                "required": ["id", "text"],
                "properties": {
                  "id": { "type": "string" },
                  "text": { "type": "string" },
                  "key": { "type": "string" },
                  "rationale": { "type": "string" },
                  "confidence": { "type": "number", "minimum": 0, "maximum": 1 },
                  "tags": { "type": "array", "items": { "type": "string" } }
                }
              }
            }
          }
        }
      ]
    },
    "MemoryRecallResultPart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": ["type", "entries"],
          "properties": {
            "type": { "const": "memory-recall-result" },
            "query": { "type": "string" },
            "entries": {
              "type": "array",
              "items": {
                "type": "object",
                "required": ["id", "text", "createdAt"],
                "properties": {
                  "id": { "type": "string" },
                  "text": { "type": "string" },
                  "key": { "type": "string" },
                  "createdAt": { "type": "integer", "minimum": 0 },
                  "tags": { "type": "array", "items": { "type": "string" } }
                }
              }
            }
          }
        }
      ]
    },
    "SignalCategory": {
      "type": "string",
      "enum": ["frustration", "anger", "confusion", "urgency", "satisfaction", "delight", "neutral"]
    },
    "SignalSource": {
      "type": "string",
      "enum": ["model", "local", "server", "rule"]
    },
    "SignalScope": {
      "type": "string",
      "enum": ["message", "turn", "session"]
    },
    "SignalPolarity": {
      "type": "string",
      "enum": ["positive", "neutral", "negative", "mixed"]
    },
    "SignalBase": {
      "type": "object",
      "required": ["id", "score", "confidence", "source", "adapter"],
      "properties": {
        "id": { "type": "string" },
        "score": { "type": "number", "minimum": 0, "maximum": 1 },
        "confidence": { "type": "number", "minimum": 0, "maximum": 1 },
        "source": { "$ref": "#/definitions/SignalSource" },
        "adapter": { "type": "string" },
        "scope": { "$ref": "#/definitions/SignalScope" },
        "attributedMessageId": { "type": "string" },
        "latencyMs": { "type": "number", "minimum": 0 }
      }
    },
    "SentimentSignalPart": {
      "allOf": [
        { "$ref": "#/definitions/SignalBase" },
        {
          "type": "object",
          "required": ["type", "category"],
          "properties": {
            "type": { "const": "sentiment-signal" },
            "category": { "$ref": "#/definitions/SignalCategory" },
            "polarity": { "$ref": "#/definitions/SignalPolarity" }
          }
        }
      ]
    },
    "IntentSignalPart": {
      "allOf": [
        { "$ref": "#/definitions/SignalBase" },
        {
          "type": "object",
          "required": ["type", "intent"],
          "properties": {
            "type": { "const": "intent-signal" },
            "intent": { "type": "string" },
            "alternates": {
              "type": "array",
              "items": {
                "type": "object",
                "required": ["intent", "score"],
                "properties": {
                  "intent": { "type": "string" },
                  "score": { "type": "number", "minimum": 0, "maximum": 1 }
                }
              }
            }
          }
        }
      ]
    },
    "ComputerUseSurfacePart": {
      "allOf": [
        { "$ref": "#/definitions/BasePart" },
        {
          "type": "object",
          "required": [
            "type",
            "computerUseSessionId",
            "toolCallId",
            "goal",
            "allowlist",
            "streamUrl",
            "controlUrl",
            "status",
            "maxDurationMs",
            "maxActionsPerSession"
          ],
          "properties": {
            "type": { "const": "computer-use-surface" },
            "computerUseSessionId": { "type": "string", "minLength": 1 },
            "toolCallId": { "type": "string", "minLength": 1 },
            "goal": { "type": "string", "minLength": 1 },
            "allowlist": { "type": "array", "items": { "type": "string" } },
            "streamUrl": { "type": "string" },
            "controlUrl": { "type": "string" },
            "status": {
              "type": "string",
              "enum": ["awaiting_consent", "streaming", "completed", "aborted", "failed"]
            },
            "maxDurationMs": { "type": "integer", "minimum": 1000 },
            "maxActionsPerSession": { "type": "integer", "minimum": 1 },
            "startedAt": { "type": "string" },
            "endedAt": { "type": "string" },
            "error": {
              "type": "object",
              "required": ["code", "message"],
              "properties": {
                "code": { "type": "string" },
                "message": { "type": "string" }
              }
            }
          }
        }
      ]
    },
    "ChatMessagePart": {
      "oneOf": [
        { "$ref": "#/definitions/TextPart" },
        { "$ref": "#/definitions/TextDeltaPart" },
        { "$ref": "#/definitions/MarkdownPart" },
        { "$ref": "#/definitions/CitationPart" },
        { "$ref": "#/definitions/SuggestionChipPart" },
        { "$ref": "#/definitions/ProductCarouselPart" },
        { "$ref": "#/definitions/OrderSummaryPart" },
        { "$ref": "#/definitions/CustomPayloadPart" },
        { "$ref": "#/definitions/ToolCallPart" },
        { "$ref": "#/definitions/ToolResultPart" },
        { "$ref": "#/definitions/FilePart" },
        { "$ref": "#/definitions/AgentTransferPart" },
        { "$ref": "#/definitions/DiagnosticPart" },
        { "$ref": "#/definitions/EndSessionPart" },
        { "$ref": "#/definitions/ErrorPart" },
        { "$ref": "#/definitions/AudioInputPart" },
        { "$ref": "#/definitions/AudioOutputPart" },
        { "$ref": "#/definitions/TranscriptPart" },
        { "$ref": "#/definitions/AudioCuePart" },
        { "$ref": "#/definitions/VisionPart" },
        { "$ref": "#/definitions/MemoryApprovalPart" },
        { "$ref": "#/definitions/MemoryRecallResultPart" },
        { "$ref": "#/definitions/SentimentSignalPart" },
        { "$ref": "#/definitions/IntentSignalPart" },
        { "$ref": "#/definitions/A2UISurfacePart" },
        { "$ref": "#/definitions/ComputerUseSurfacePart" }
      ]
    },
    "ChatMessage": {
      "type": "object",
      "required": ["id", "role", "status", "createdAt", "sessionId", "turnIndex", "parts"],
      "properties": {
        "id": { "type": "string" },
        "role": { "type": "string", "enum": ["user", "agent"] },
        "status": {
          "type": "string",
          "enum": ["pending", "streaming", "completed", "error", "replaced"]
        },
        "createdAt": { "type": "string", "format": "date-time" },
        "sessionId": { "type": "string" },
        "turnIndex": { "type": "integer", "minimum": 0 },
        "responseId": { "type": "string" },
        "parts": { "type": "array", "items": { "$ref": "#/definitions/ChatMessagePart" } },
        "metadata": { "type": "object" },
        "editOf": {
          "type": "string",
          "description": "ID of the message this edit replaces. Set by ChatSession.editLastMessage()."
        }
      }
    }
  },
  "$ref": "#/definitions/ChatMessage"
}
