openapi: 3.1.0
info:
  title: Hengam Document Analysis Bridge
  description: Claims analysis jobs, records public progress updates, and stores final results. Drawing content is returned as Action-compatible visual packet PDFs.
  version: 2.9.0
servers:
  - url: https://gpt.138-124-60-41.sslip.io
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
  schemas:
    ClaimRequest:
      type: object
      additionalProperties: false
      required: [command]
      properties:
        command:
          type: string
          enum: [claim_next]
          description: Send claim_next to retrieve the next queued or stalled job.
    ProgressUpdate:
      type: object
      additionalProperties: false
      required: [phase, message]
      properties:
        phase:
          type: string
          maxLength: 80
          description: Short operational phase name, such as files_received, reviewing, comparing, drafting, or submitting.
        message:
          type: string
          maxLength: 1200
          description: Public progress message. Send the same message shown to the user; never send hidden reasoning or chain of thought.
        progress_percent:
          type: number
          minimum: 0
          maximum: 99
          description: Optional approximate completion percentage before the final result.
        current_item:
          type: string
          maxLength: 240
          description: Optional document, source page, packet, or section currently being processed.
    JobResult:
      type: object
      additionalProperties: false
      required: [status, answer]
      properties:
        status:
          type: string
          enum: [completed, failed]
        answer:
          type: string
          description: Complete final analysis or a concise failure description.
security:
  - bearerAuth: []
paths:
  /api/action/jobs/claim:
    post:
      operationId: claimNextFileJob
      summary: Claim the next analysis job
      description: Claims the oldest queued job or a stalled job. Active processing jobs with a valid heartbeat lease are not claimed again.
      x-openai-isConsequential: false
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClaimRequest'
      responses:
        '200':
          description: A claimed job or an empty queue
          content:
            application/json:
              schema:
                type: object
                required: [found]
                properties:
                  found: { type: boolean }
                  message: { type: string }
                  job_id: { type: string }
                  job_type: { type: string }
                  source_job_id: { type: string }
                  filenames:
                    type: array
                    items: { type: string }
                  mime_types:
                    type: array
                    items: { type: string }
                  file_roles:
                    type: array
                    items: { type: string }
                  file_count: { type: integer }
                  metadata_json:
                    type: string
                    description: JSON mapping files and visual packet pages to documents, revision roles, source pages, full-page views, and tiles.
                  lease_expires_at:
                    type: string
                    format: date-time
                  heartbeat_interval_seconds:
                    type: integer
                    description: Suggested maximum interval between public progress updates.
                  reclaimed: { type: boolean }
                  claim_attempt: { type: integer }
                  openaiFileResponse:
                    type: array
                    description: Up to 10 temporary URLs for Action-compatible files. Drawings are returned as visual packet PDFs.
                    items:
                      type: string
                      format: uri
  /api/action/jobs/{job_id}/heartbeat:
    post:
      operationId: reportJobProgress
      summary: Report progress and renew the job lease
      description: Stores a user-visible progress update and renews the processing lease. Use at each major phase and before or after lengthy tool work.
      x-openai-isConsequential: false
      parameters:
        - name: job_id
          in: path
          required: true
          description: Exact job ID returned by claimNextFileJob.
          schema: { type: string }
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProgressUpdate'
      responses:
        '200':
          description: Progress stored and lease renewed
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok: { type: boolean }
                  job_id: { type: string }
                  status: { type: string }
                  heartbeat_at: { type: string, format: date-time }
                  lease_expires_at: { type: string, format: date-time }
                  heartbeat_count: { type: integer }
  /api/action/jobs/{job_id}/result:
    post:
      operationId: submitFileJobResult
      summary: Save the final analysis
      description: Stores the completed analysis or final failure message and archives the job.
      x-openai-isConsequential: false
      parameters:
        - name: job_id
          in: path
          required: true
          description: Exact job ID returned by claimNextFileJob.
          schema: { type: string }
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JobResult'
      responses:
        '200':
          description: Result stored successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok: { type: boolean }
                  job_id: { type: string }
                  status: { type: string }
