Files
agent-call/docs/contracts/executor.openapi.yaml
T

304 lines
10 KiB
YAML

# yaml-language-server: $schema=https://json-schema.org/draft/2020-12/schema
openapi: 3.1.0
info:
title: agent-call Executor Control API
version: 1.0.0
description: >-
Internal control, query, replay, and recording hand-off API. Call execution
enters through RabbitMQ, not HTTP.
servers:
- url: https://executor.internal
security:
- bearerAuth: []
paths:
/internal/v1/outbound/tasks/{task_id}/controls:
post:
operationId: controlTask
summary: Persist a pause, resume, or stop barrier
parameters:
- $ref: '#/components/parameters/TenantId'
- $ref: '#/components/parameters/RequestId'
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/TaskId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ControlRequest'
responses:
'202':
description: Reliably persisted, not yet necessarily applied
headers:
Location:
schema: {type: string}
content:
application/json:
schema: {$ref: '#/components/schemas/ControlAccepted'}
'409': {$ref: '#/components/responses/Conflict'}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {$ref: '#/components/responses/Forbidden'}
'404': {$ref: '#/components/responses/NotFound'}
/internal/v1/outbound/commands/{command_id}:
get:
operationId: getCommand
parameters:
- $ref: '#/components/parameters/TenantId'
- $ref: '#/components/parameters/RequestId'
- $ref: '#/components/parameters/CommandId'
responses:
'200':
description: Command snapshot
content:
application/json:
schema: {$ref: '#/components/schemas/Command'}
'401': {$ref: '#/components/responses/Unauthorized'}
'404': {$ref: '#/components/responses/NotFound'}
/internal/v1/outbound/calls/{call_id}:
get:
operationId: getCall
parameters:
- $ref: '#/components/parameters/TenantId'
- $ref: '#/components/parameters/RequestId'
- $ref: '#/components/parameters/CallId'
responses:
'200':
description: Call snapshot
content:
application/json:
schema: {$ref: '#/components/schemas/Call'}
'401': {$ref: '#/components/responses/Unauthorized'}
'404': {$ref: '#/components/responses/NotFound'}
/internal/v1/outbound/calls/{call_id}/replays:
post:
operationId: replayCall
parameters:
- $ref: '#/components/parameters/TenantId'
- $ref: '#/components/parameters/RequestId'
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/CallId'
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/ReplayRequest'}
responses:
'202':
description: Replay persisted for bounded broker delivery
headers:
Location: {schema: {type: string}}
content:
application/json:
schema: {$ref: '#/components/schemas/ReplayAccepted'}
'401': {$ref: '#/components/responses/Unauthorized'}
'404': {$ref: '#/components/responses/NotFound'}
'410': {$ref: '#/components/responses/ReplayExpired'}
/internal/v1/outbound/commands/{source_command_id}/replays:
post:
operationId: replayCommand
parameters:
- $ref: '#/components/parameters/TenantId'
- $ref: '#/components/parameters/RequestId'
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/SourceCommandId'
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/ReplayRequest'}
responses:
'202':
description: Replay persisted for bounded broker delivery
headers:
Location: {schema: {type: string}}
content:
application/json:
schema: {$ref: '#/components/schemas/ReplayAccepted'}
'401': {$ref: '#/components/responses/Unauthorized'}
'404': {$ref: '#/components/responses/NotFound'}
'410': {$ref: '#/components/responses/ReplayExpired'}
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
parameters:
TenantId:
name: X-Tenant-ID
in: header
required: true
schema: {type: string}
RequestId:
name: X-Request-ID
in: header
required: true
schema: {type: string}
IdempotencyKey:
name: Idempotency-Key
in: header
required: true
schema: {type: string}
TaskId:
name: task_id
in: path
required: true
schema: {$ref: '#/components/schemas/Id'}
CommandId:
name: command_id
in: path
required: true
schema: {$ref: '#/components/schemas/Id'}
SourceCommandId:
name: source_command_id
in: path
required: true
schema: {$ref: '#/components/schemas/Id'}
CallId:
name: call_id
in: path
required: true
schema: {$ref: '#/components/schemas/Id'}
schemas:
Id:
type: string
minLength: 1
maxLength: 128
pattern: '^[^\\s/\\\\]+$'
ControlRequest:
type: object
additionalProperties: false
required: [command_id, action, expected_task_revision, reason]
properties:
command_id: {$ref: '#/components/schemas/Id'}
action: {type: string, enum: [pause, resume, stop]}
expected_task_revision: {type: integer, minimum: 1}
active_call_policy: {type: string, enum: [drain, hangup]}
reason: {type: string, minLength: 1, maxLength: 512}
ControlAccepted:
type: object
required:
- command_id
- tenant_id
- tenant_key
- task_id
- status
- requested_task_revision
- accepted_at
properties:
command_id: {$ref: '#/components/schemas/Id'}
tenant_id: {type: string}
tenant_key: {type: string}
task_id: {$ref: '#/components/schemas/Id'}
status: {const: accepted}
requested_task_revision: {type: integer}
accepted_at: {type: string, format: date-time}
ReplayRequest:
type: object
additionalProperties: false
required: [command_id, reason]
properties:
command_id: {$ref: '#/components/schemas/Id'}
reason: {type: string, minLength: 1, maxLength: 512}
ReplayAccepted:
type: object
required: [command_id, status, snapshot_cutoff]
properties:
command_id: {$ref: '#/components/schemas/Id'}
status: {const: accepted}
snapshot_cutoff: {type: string, format: date-time}
Command:
type: object
required:
- command_id
- command_type
- tenant_id
- tenant_key
- status
- aggregate_version
properties:
command_id: {$ref: '#/components/schemas/Id'}
command_type: {type: string}
tenant_id: {type: string}
tenant_key: {type: string}
task_id: {type: [string, 'null']}
execution_id: {type: [string, 'null']}
call_id: {type: [string, 'null']}
status: {type: string}
reason_code: {type: [string, 'null']}
wait_reason_code: {type: [string, 'null']}
accepted_at: {type: [string, 'null'], format: date-time}
waiting_since: {type: [string, 'null'], format: date-time}
admission_deadline: {type: [string, 'null'], format: date-time}
requested_task_revision: {type: [integer, 'null']}
applied_task_revision: {type: [integer, 'null']}
task_state: {type: [string, 'null']}
updated_at: {type: string, format: date-time}
aggregate_version: {type: integer, minimum: 1}
Call:
type: object
required:
- call_id
- execution_id
- call_state
- call_version
- attempts
- transcript
- recordings
- delivery
- snapshot_at
properties:
call_id: {type: string}
execution_id: {type: string}
task_id: {type: string}
task_item_id: {type: string}
call_state: {type: string}
call_version: {type: integer}
reason_code: {type: [string, 'null']}
outcome: {type: [string, 'null']}
started_at: {type: [string, 'null'], format: date-time}
ended_at: {type: [string, 'null'], format: date-time}
duration_ms: {type: [integer, 'null']}
attempts: {type: array, items: {type: object}}
transcript: {type: object}
recordings: {type: array, items: {type: object}}
delivery: {type: object}
snapshot_at: {type: string, format: date-time}
responses:
Unauthorized:
description: Unauthorized
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
Forbidden:
description: Forbidden
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
NotFound:
description: Not found without cross-tenant enumeration
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
Conflict:
description: Idempotency or revision conflict
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
ReplayExpired:
description: Retention window expired
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
Problem:
type: object
additionalProperties: false
required: [type, title, status, code, detail, request_id, retryable]
properties:
type: {type: string, format: uri-reference}
title: {type: string}
status: {type: integer}
code: {type: string}
detail: {type: string}
request_id: {type: string}
retryable: {type: boolean}