openapi: 3.1.0
info:
  title: AgentContainer API
  version: 0.2.0
  description: |
    Public API for configuring containers, configuring agents on top of them,
    and dispatching tasks.
servers:
  - url: http://localhost:3000
    description: Local development
tags:
  - name: Account
    description: Account identity and platform billing state.
  - name: Containers
    description: Reusable execution environments.
  - name: Agents
    description: Reusable workers built on top of containers.
  - name: Files
    description: Uploads and file relationships.
  - name: Tasks
    description: Task dispatch and task inspection.
paths:
  /api/v1/account:
    get:
      tags: [Account]
      operationId: getAccount
      summary: Get account
      description: Returns the account resolved from the bearer API key, including current platform credit balance.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Account details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Account"
        "401":
          $ref: "#/components/responses/Unauthorized"
  /api/v1/containers:
    get:
      tags: [Containers]
      operationId: listContainers
      summary: List containers
      description: Lists your custom containers and platform-provided standard containers.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Containers successfully listed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListContainersResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
    post:
      tags: [Containers]
      operationId: createContainer
      summary: Create container
      description: Creates a reusable execution environment definition.
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateContainerRequest"
      responses:
        "201":
          description: Container created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Container"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "422":
          $ref: "#/components/responses/InvalidRequest"
  /api/v1/containers/{containerId}:
    parameters:
      - $ref: "#/components/parameters/ContainerId"
    get:
      tags: [Containers]
      operationId: getContainer
      summary: Get container
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Container details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Container"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
    patch:
      tags: [Containers]
      operationId: updateContainer
      summary: Update container
      description: Updates a container. Execution changes create a new container version.
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateContainerRequest"
      responses:
        "200":
          description: Container updated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Container"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "422":
          $ref: "#/components/responses/InvalidRequest"
    delete:
      tags: [Containers]
      operationId: archiveContainer
      summary: Archive container
      description: Soft-archives a custom container.
      security:
        - bearerAuth: []
      responses:
        "204":
          description: Container archived
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
  /api/v1/containers/{containerId}/fork:
    parameters:
      - $ref: "#/components/parameters/ContainerId"
    post:
      tags: [Containers]
      operationId: forkContainer
      summary: Fork container
      description: Forks a standard container into your own custom container.
      security:
        - bearerAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ForkResourceRequest"
      responses:
        "201":
          description: Container forked
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Container"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
  /api/v1/containers/{containerId}/versions:
    parameters:
      - $ref: "#/components/parameters/ContainerId"
    get:
      tags: [Containers]
      operationId: listContainerVersions
      summary: List container versions
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Container versions successfully listed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListContainerVersionsResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
  /api/v1/containers/{containerId}/versions/{versionId}:
    parameters:
      - $ref: "#/components/parameters/ContainerId"
      - $ref: "#/components/parameters/VersionId"
    get:
      tags: [Containers]
      operationId: getContainerVersion
      summary: Get container version
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Container version details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ContainerVersion"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /api/v1/agents:
    get:
      tags: [Agents]
      operationId: listAgents
      summary: List agents
      description: Lists your custom agents and platform-provided standard agents.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Agents successfully listed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListAgentsResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
    post:
      tags: [Agents]
      operationId: createAgent
      summary: Create agent
      description: Creates a reusable worker definition referencing a container.
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateAgentRequest"
      responses:
        "201":
          description: Agent created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agent"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "422":
          $ref: "#/components/responses/InvalidRequest"
  /api/v1/agents/{agentId}:
    parameters:
      - $ref: "#/components/parameters/AgentId"
    get:
      tags: [Agents]
      operationId: getAgent
      summary: Get agent
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Agent details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agent"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
    patch:
      tags: [Agents]
      operationId: updateAgent
      summary: Update agent
      description: Updates an agent. Execution changes create a new agent version.
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateAgentRequest"
      responses:
        "200":
          description: Agent updated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agent"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "422":
          $ref: "#/components/responses/InvalidRequest"
    delete:
      tags: [Agents]
      operationId: archiveAgent
      summary: Archive agent
      description: Soft-archives a custom agent.
      security:
        - bearerAuth: []
      responses:
        "204":
          description: Agent archived
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
  /api/v1/agents/{agentId}/fork:
    parameters:
      - $ref: "#/components/parameters/AgentId"
    post:
      tags: [Agents]
      operationId: forkAgent
      summary: Fork agent
      description: Forks a standard agent into your own custom agent.
      security:
        - bearerAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ForkResourceRequest"
      responses:
        "201":
          description: Agent forked
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agent"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
  /api/v1/agents/{agentId}/versions:
    parameters:
      - $ref: "#/components/parameters/AgentId"
    get:
      tags: [Agents]
      operationId: listAgentVersions
      summary: List agent versions
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Agent versions successfully listed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListAgentVersionsResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
  /api/v1/agents/{agentId}/versions/{versionId}:
    parameters:
      - $ref: "#/components/parameters/AgentId"
      - $ref: "#/components/parameters/VersionId"
    get:
      tags: [Agents]
      operationId: getAgentVersion
      summary: Get agent version
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Agent version details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentVersion"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /api/v1/uploads/prepare:
    post:
      tags: [Files]
      operationId: prepareUpload
      summary: Prepare file upload
      description: Creates a scoped upload session and returns a Convex upload URL.
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PrepareUploadRequest"
      responses:
        "201":
          description: Upload prepared
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PreparedUpload"
        "401":
          $ref: "#/components/responses/Unauthorized"
  /api/v1/uploads/complete:
    post:
      tags: [Files]
      operationId: completeUpload
      summary: Complete file upload
      description: Finalizes a previously prepared upload after the file bytes have been sent to Convex storage.
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CompleteUploadRequest"
      responses:
        "201":
          description: File uploaded
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/File"
        "401":
          $ref: "#/components/responses/Unauthorized"
  /api/v1/agents/{agentId}/reference-files:
    parameters:
      - $ref: "#/components/parameters/AgentId"
    post:
      tags: [Files, Agents]
      operationId: attachAgentReferenceFiles
      summary: Attach reference files to agent
      description: Attaches previously uploaded files to an agent, creating a new agent version.
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AttachReferenceFilesRequest"
      responses:
        "200":
          description: Reference files attached
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agent"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "422":
          $ref: "#/components/responses/InvalidRequest"
    get:
      tags: [Files, Agents]
      operationId: listAgentReferenceFiles
      summary: List reference files for current agent version
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Reference files listed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListFilesResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /api/v1/agents/{agentId}/tasks:
    parameters:
      - $ref: "#/components/parameters/AgentId"
    post:
      tags: [Tasks]
      operationId: createTask
      summary: Dispatch task
      description: Dispatches a task to an agent. If `versionId` is omitted, the current agent version is used.
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateTaskRequest"
      responses:
        "201":
          description: Task created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Task"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "422":
          $ref: "#/components/responses/InvalidRequest"
    get:
      tags: [Tasks]
      operationId: listAgentTasks
      summary: List tasks for agent
      security:
        - bearerAuth: []
      parameters:
        - in: query
          name: status
          required: false
          schema:
            type: string
            enum: [pending, running, finished, failed, cancelled]
      responses:
        "200":
          description: Tasks listed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListTasksResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
  /api/v1/tasks/{taskId}:
    parameters:
      - $ref: "#/components/parameters/TaskId"
    get:
      tags: [Tasks]
      operationId: getTask
      summary: Get task
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Task details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Task"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
  /api/v1/tasks/{taskId}/cancel:
    parameters:
      - $ref: "#/components/parameters/TaskId"
    post:
      tags: [Tasks]
      operationId: cancelTask
      summary: Cancel task
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Task cancellation requested
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Task"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
  /api/v1/tasks/{taskId}/files:
    parameters:
      - $ref: "#/components/parameters/TaskId"
    get:
      tags: [Tasks, Files]
      operationId: listTaskFiles
      summary: List task files
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Task files listed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListFilesResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
  /api/v1/tasks/{taskId}/files/{fileId}:
    parameters:
      - $ref: "#/components/parameters/TaskId"
      - $ref: "#/components/parameters/FileId"
    get:
      tags: [Tasks, Files]
      operationId: downloadTaskFile
      summary: Download task file
      security:
        - bearerAuth: []
      responses:
        "200":
          description: File bytes
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /api/v1/openapi.yaml:
    get:
      operationId: getOpenApiSpec
      summary: Raw OpenAPI spec
      description: Returns the raw YAML OpenAPI specification for this API.
      responses:
        "200":
          description: Raw OpenAPI YAML
          content:
            application/yaml:
              schema:
                type: string

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
  parameters:
    ContainerId:
      in: path
      name: containerId
      required: true
      schema:
        type: string
    AgentId:
      in: path
      name: agentId
      required: true
      schema:
        type: string
    TaskId:
      in: path
      name: taskId
      required: true
      schema:
        type: string
    FileId:
      in: path
      name: fileId
      required: true
      schema:
        type: string
    VersionId:
      in: path
      name: versionId
      required: true
      schema:
        type: string
  responses:
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    InvalidRequest:
      description: Request failed validation
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
  schemas:
    Account:
      type: object
      additionalProperties: false
      required:
        - id
        - name
        - email
        - creditBalance
        - createdAt
      properties:
        id:
          type: string
          description: Internal account identifier resolved from the API key.
        name:
          type:
            - string
            - "null"
        email:
          type:
            - string
            - "null"
          format: email
        creditBalance:
          type: number
          description: Current prepaid platform credit balance in USD.
        createdAt:
          type: string
          format: date-time
    CreateContainerRequest:
      type: object
      additionalProperties: false
      required:
        - name
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 200
        description:
          type: string
          maxLength: 2000
        containerPreset:
          type: string
          maxLength: 200
        containerImage:
          type: string
          maxLength: 1000
        containerContractVersion:
          type: string
          maxLength: 100
    UpdateContainerRequest:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 200
        description:
          type: string
          maxLength: 2000
        containerPreset:
          type: string
          maxLength: 200
        containerImage:
          type: string
          maxLength: 1000
        containerContractVersion:
          type: string
          maxLength: 100
    CreateAgentRequest:
      type: object
      additionalProperties: false
      required:
        - name
        - basePrompt
        - defaults
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 200
        description:
          type: string
          maxLength: 2000
        containerId:
          type: string
        containerVersionId:
          type: string
        basePrompt:
          type: string
          maxLength: 20000
        defaults:
          $ref: "#/components/schemas/AgentDefaults"
    UpdateAgentRequest:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 200
        description:
          type: string
          maxLength: 2000
        containerId:
          type: string
        containerVersionId:
          type: string
        basePrompt:
          type: string
          maxLength: 20000
        defaults:
          $ref: "#/components/schemas/AgentDefaults"
    AgentDefaults:
      type: object
      additionalProperties: false
      required:
        - model
        - internetAccess
        - maxRuntimeSeconds
        - outputPolicy
      properties:
        provider:
          type: string
          enum: [anthropic, openrouter, openai]
          description: LLM provider. Falls back to user account default if not set.
        providerApiKey:
          type: string
          maxLength: 500
          writeOnly: true
          description: API key for the specified provider. Write-only; never returned in responses.
        model:
          type: string
          minLength: 1
          maxLength: 200
        internetAccess:
          type: boolean
        maxRuntimeSeconds:
          type: integer
          minimum: 60
          maximum: 14400
        outputPolicy:
          $ref: "#/components/schemas/OutputPolicy"
        runtimeRegion:
          type: string
          enum: [any, eu]
    OutputDescriptor:
      type: object
      additionalProperties: false
      required:
        - name
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 200
        description:
          type: string
          minLength: 1
          maxLength: 1000
    OutputPolicy:
      oneOf:
        - type: object
          additionalProperties: false
          required:
            - mode
          properties:
            mode:
              type: string
              enum: [any]
        - type: object
          additionalProperties: false
          required:
            - mode
          properties:
            mode:
              type: string
              enum: [none]
        - type: object
          additionalProperties: false
          required:
            - mode
          properties:
            mode:
              type: string
              enum: [at_least_one]
        - type: object
          additionalProperties: false
          required:
            - mode
            - files
          properties:
            mode:
              type: string
              enum: [named]
            files:
              type: array
              minItems: 1
              items:
                $ref: "#/components/schemas/OutputDescriptor"
    CreateTaskRequest:
      type: object
      additionalProperties: false
      required:
        - description
      properties:
        versionId:
          type: string
        description:
          type: string
          minLength: 1
          maxLength: 20000
        inputFileIds:
          type: array
          items:
            type: string
        metadata:
          type: object
          additionalProperties:
            type: string
            maxLength: 500
          propertyNames:
            minLength: 1
            maxLength: 100
        overrides:
          $ref: "#/components/schemas/TaskOverrides"
    TaskOverrides:
      type: object
      additionalProperties: false
      properties:
        provider:
          type: string
          enum: [anthropic, openrouter, openai]
          description: LLM provider override for this task.
        providerApiKey:
          type: string
          maxLength: 500
          writeOnly: true
          description: API key for the specified provider. Write-only; never returned in responses.
        model:
          type: string
          minLength: 1
          maxLength: 200
        internetAccess:
          type: boolean
        maxRuntimeSeconds:
          type: integer
          minimum: 60
          maximum: 14400
        outputPolicy:
          $ref: "#/components/schemas/OutputPolicy"
        runtimeRegion:
          type: string
          enum: [any, eu]
    AttachReferenceFilesRequest:
      type: object
      additionalProperties: false
      required:
        - fileIds
      properties:
        fileIds:
          type: array
          minItems: 1
          items:
            type: string
    ForkResourceRequest:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 200
        description:
          type: string
          maxLength: 2000
    Container:
      type: object
      additionalProperties: false
      required:
        - id
        - name
        - description
        - isStandard
        - archivedAt
        - currentVersion
        - createdAt
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type:
            - string
            - "null"
        isStandard:
          type: boolean
        archivedAt:
          type:
            - string
            - "null"
          format: date-time
        currentVersion:
          $ref: "#/components/schemas/ContainerVersion"
        createdAt:
          type: string
          format: date-time
    ContainerVersion:
      type: object
      additionalProperties: false
      required:
        - id
        - number
        - containerPreset
        - containerImage
        - containerContractVersion
        - createdAt
      properties:
        id:
          type: string
        number:
          type: integer
        containerPreset:
          type:
            - string
            - "null"
        containerImage:
          type:
            - string
            - "null"
        containerContractVersion:
          type:
            - string
            - "null"
        createdAt:
          type: string
          format: date-time
    Agent:
      type: object
      additionalProperties: false
      required:
        - id
        - name
        - description
        - isStandard
        - archivedAt
        - currentVersion
        - createdAt
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type:
            - string
            - "null"
        isStandard:
          type: boolean
        archivedAt:
          type:
            - string
            - "null"
          format: date-time
        currentVersion:
          $ref: "#/components/schemas/AgentVersion"
        createdAt:
          type: string
          format: date-time
    AgentVersion:
      type: object
      additionalProperties: false
      required:
        - id
        - number
        - containerVersionId
        - basePrompt
        - defaults
        - createdAt
      properties:
        id:
          type: string
        number:
          type: integer
        containerVersionId:
          type: string
        basePrompt:
          type: string
        defaults:
          $ref: "#/components/schemas/AgentVersionDefaults"
        createdAt:
          type: string
          format: date-time
    AgentVersionDefaults:
      type: object
      additionalProperties: false
      required:
        - provider
        - hasProviderApiKey
        - model
        - internetAccess
        - maxRuntimeSeconds
        - outputPolicy
        - runtimeRegion
      properties:
        provider:
          type:
            - string
            - "null"
          enum: [anthropic, openrouter, openai, null]
          description: Configured LLM provider, or null if using account default.
        hasProviderApiKey:
          type: boolean
          description: Whether a provider API key is set on this version.
        model:
          type: string
        internetAccess:
          type: boolean
        maxRuntimeSeconds:
          type: integer
        outputPolicy:
          $ref: "#/components/schemas/OutputPolicy"
        runtimeRegion:
          type: string
          enum: [any, eu]
    TaskResponseOverrides:
      type: object
      additionalProperties: false
      properties:
        provider:
          type: string
          enum: [anthropic, openrouter, openai]
        hasProviderApiKey:
          type: boolean
        model:
          type: string
        internetAccess:
          type: boolean
        maxRuntimeSeconds:
          type: integer
        outputPolicy:
          $ref: "#/components/schemas/OutputPolicy"
        runtimeRegion:
          type: string
          enum: [any, eu]
    Task:
      type: object
      additionalProperties: false
      required:
        - id
        - agentId
        - agentVersionId
        - containerVersionId
        - status
        - description
        - runtimeRegion
        - overrides
        - metadata
        - createdAt
        - startedAt
        - completedAt
        - result
        - error
        - costUsd
        - containerMinutes
        - tokenUsage
      properties:
        id:
          type: string
        agentId:
          type: string
        agentVersionId:
          type: string
        containerVersionId:
          type: string
        status:
          type: string
          enum: [pending, running, finished, failed, cancelled]
        description:
          type: string
        runtimeRegion:
          type: string
          enum: [any, eu]
        overrides:
          $ref: "#/components/schemas/TaskResponseOverrides"
        metadata:
          type: object
          additionalProperties:
            type: string
        createdAt:
          type: string
          format: date-time
        startedAt:
          type:
            - string
            - "null"
          format: date-time
        completedAt:
          type:
            - string
            - "null"
          format: date-time
        result:
          type:
            - string
            - "null"
        error:
          type:
            - string
            - "null"
        costUsd:
          type:
            - number
            - "null"
        containerMinutes:
          type:
            - number
            - "null"
        tokenUsage:
          type:
            - object
            - "null"
          additionalProperties: true
    File:
      type: object
      additionalProperties: false
      required:
        - id
        - filename
        - contentType
        - sizeBytes
        - createdAt
      properties:
        id:
          type: string
        filename:
          type: string
        contentType:
          type:
            - string
            - "null"
        sizeBytes:
          type:
            - integer
            - "null"
        createdAt:
          type: string
          format: date-time
    PrepareUploadRequest:
      type: object
      additionalProperties: false
      required:
        - filename
      properties:
        filename:
          type: string
        contentType:
          type: string
        sizeBytes:
          type: integer
    CompleteUploadRequest:
      type: object
      additionalProperties: false
      required:
        - uploadId
        - storageId
      properties:
        uploadId:
          type: string
        storageId:
          type: string
    PreparedUpload:
      type: object
      additionalProperties: false
      required:
        - uploadId
        - uploadUrl
        - expiresAt
      properties:
        uploadId:
          type: string
        uploadUrl:
          type: string
          format: uri
        expiresAt:
          type:
            - string
            - "null"
          format: date-time
    ListContainersResponse:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Container"
    ListContainerVersionsResponse:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/ContainerVersion"
    ListAgentsResponse:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Agent"
    ListAgentVersionsResponse:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/AgentVersion"
    ListTasksResponse:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Task"
    ListFilesResponse:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/File"
    ErrorResponse:
      type: object
      additionalProperties: false
      required: [error]
      properties:
        error:
          type: object
          additionalProperties: true
          required: [code, message]
          properties:
            code:
              type: string
            message:
              type: string
