Spaces:
Running
Running
| import { | |
| AGENT_BACKGROUNDS, | |
| AGENT_IMAGE_BACKENDS, | |
| AGENT_JOB_STATES, | |
| AGENT_MODERATIONS, | |
| AGENT_MODELS, | |
| AGENT_OUTPUT_FORMATS, | |
| AGENT_PAGE_SSE_AGENT_USAGE, | |
| AGENT_QUALITIES, | |
| AGENT_RESPONSE_MODES, | |
| AGENT_STREAM_MODES, | |
| AGENT_STREAMING_STRATEGIES, | |
| AGENT_UPSTREAM_SSE_EDIT_REQUEST_FIELDS, | |
| AGENT_UPSTREAM_SSE_GENERATE_REQUEST_FIELDS, | |
| AGENT_UPSTREAM_SSE_ACTIVATION_STRATEGIES, | |
| type AgentAuthScheme, | |
| type AgentRoutingStrength, | |
| type AgentRoutingTransport, | |
| buildAgentCapabilities, | |
| readAgentPublicBaseUrl | |
| } from './agent-api-contracts'; | |
| import { AGENT_ENDPOINTS } from './agent-api-paths.mjs'; | |
| import { CHANNEL_REQUEST_MODES } from './channel-request-mode'; | |
| import { MAX_PROMPT_LENGTH } from './image-request-utils'; | |
| type AgentOpenApiSecurityRequirement = { BearerAuth: [] } | { AppPasswordHash: [] }; | |
| function buildAgentOpenApiSecurity(schemes: readonly AgentAuthScheme[]): AgentOpenApiSecurityRequirement[] { | |
| return schemes.map((scheme) => (scheme === 'bearer' ? { BearerAuth: [] } : { AppPasswordHash: [] })); | |
| } | |
| function buildAgentOpenApiSecuritySchemes(schemes: readonly AgentAuthScheme[]) { | |
| const securitySchemes: Record<string, { type: string; scheme?: string; in?: string; name?: string }> = {}; | |
| if (schemes.includes('bearer')) { | |
| securitySchemes.BearerAuth = { | |
| type: 'http', | |
| scheme: 'bearer' | |
| }; | |
| } | |
| if (schemes.includes('x-app-password-hash')) { | |
| securitySchemes.AppPasswordHash = { | |
| type: 'apiKey', | |
| in: 'header', | |
| name: 'X-App-Password-Hash' | |
| }; | |
| } | |
| return securitySchemes; | |
| } | |
| export function buildAgentOpenApiDocument(env: Record<string, string | undefined>) { | |
| const capabilities = buildAgentCapabilities(env); | |
| const maxGenerateImageCount = capabilities.limits.generate_images.max; | |
| const maxEditImageCount = capabilities.limits.edit_images.max; | |
| const maxSourceImageCount = capabilities.limits.upload_images.max; | |
| const supportedBackgrounds = capabilities.upstream_profile.activeConstraints.gptImage2.allowTransparentBackground | |
| ? AGENT_BACKGROUNDS | |
| : AGENT_BACKGROUNDS.filter((value) => value !== 'transparent'); | |
| const jsonContent = (schemaRef: string) => ({ | |
| content: { | |
| 'application/json': { | |
| schema: { $ref: schemaRef } | |
| } | |
| } | |
| }); | |
| const agentSecurity = buildAgentOpenApiSecurity(capabilities.auth.schemes); | |
| const securitySchemes = buildAgentOpenApiSecuritySchemes(capabilities.auth.schemes); | |
| const commonAgentErrors = { | |
| '401': jsonContent('#/components/schemas/AgentError'), | |
| '403': jsonContent('#/components/schemas/AgentError'), | |
| '415': jsonContent('#/components/schemas/AgentError'), | |
| '429': jsonContent('#/components/schemas/AgentError'), | |
| '502': jsonContent('#/components/schemas/AgentError') | |
| }; | |
| return { | |
| openapi: '3.1.0', | |
| info: { | |
| title: 'Visual Journal Agent API', | |
| version: capabilities.api_version | |
| }, | |
| servers: [{ url: readAgentPublicBaseUrl(env) }], | |
| paths: { | |
| [AGENT_ENDPOINTS.capabilities]: { | |
| get: { | |
| summary: '获取机器可读的 Agent API 能力信息', | |
| responses: { | |
| '200': jsonContent('#/components/schemas/AgentCapabilities') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.openapi]: { | |
| get: { | |
| summary: '获取 Agent API 的 OpenAPI 文档', | |
| responses: { | |
| '200': { description: 'OpenAPI 文档' } | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.generate]: { | |
| post: { | |
| summary: '为 Agent 生成图片', | |
| security: agentSecurity, | |
| parameters: [{ $ref: '#/components/parameters/IdempotencyKey' }], | |
| requestBody: { | |
| required: true, | |
| ...jsonContent('#/components/schemas/GenerateRequest') | |
| }, | |
| responses: { | |
| '200': jsonContent('#/components/schemas/AgentImageResponse'), | |
| '400': jsonContent('#/components/schemas/AgentError'), | |
| '409': { | |
| ...jsonContent('#/components/schemas/AgentError'), | |
| headers: { | |
| 'Retry-After': { schema: { type: 'integer', minimum: 1 } } | |
| } | |
| }, | |
| ...commonAgentErrors, | |
| '422': jsonContent('#/components/schemas/AgentError'), | |
| '500': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.edit]: { | |
| post: { | |
| summary: '为 Agent 编辑图片', | |
| security: agentSecurity, | |
| parameters: [{ $ref: '#/components/parameters/IdempotencyKey' }], | |
| requestBody: { | |
| required: true, | |
| content: { | |
| 'multipart/form-data': { | |
| schema: { $ref: '#/components/schemas/EditRequest' } | |
| } | |
| } | |
| }, | |
| responses: { | |
| '200': jsonContent('#/components/schemas/AgentImageResponse'), | |
| '400': jsonContent('#/components/schemas/AgentError'), | |
| '409': { | |
| ...jsonContent('#/components/schemas/AgentError'), | |
| headers: { | |
| 'Retry-After': { schema: { type: 'integer', minimum: 1 } } | |
| } | |
| }, | |
| ...commonAgentErrors, | |
| '422': jsonContent('#/components/schemas/AgentError'), | |
| '500': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.create_image_request]: { | |
| post: { | |
| summary: '提交服务端编排的 Agent 图片生成意图', | |
| security: agentSecurity, | |
| parameters: [{ $ref: '#/components/parameters/IdempotencyKey' }], | |
| requestBody: { | |
| required: true, | |
| ...jsonContent('#/components/schemas/GenerateRequest') | |
| }, | |
| responses: { | |
| '200': jsonContent('#/components/schemas/AgentJobStatusResponse'), | |
| '202': { | |
| ...jsonContent('#/components/schemas/AgentJobStatusResponse'), | |
| headers: { | |
| 'Retry-After': { schema: { type: 'integer', minimum: 1 } } | |
| } | |
| }, | |
| '400': jsonContent('#/components/schemas/AgentError'), | |
| '409': jsonContent('#/components/schemas/AgentError'), | |
| ...commonAgentErrors, | |
| '422': jsonContent('#/components/schemas/AgentError'), | |
| '500': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.create_generate_job]: { | |
| post: { | |
| summary: '创建 Agent 图片生成 job', | |
| security: agentSecurity, | |
| parameters: [{ $ref: '#/components/parameters/IdempotencyKey' }], | |
| requestBody: { | |
| required: true, | |
| ...jsonContent('#/components/schemas/GenerateRequest') | |
| }, | |
| responses: { | |
| '200': jsonContent('#/components/schemas/AgentJobStatusResponse'), | |
| '202': { | |
| ...jsonContent('#/components/schemas/AgentJobStatusResponse'), | |
| headers: { | |
| 'Retry-After': { schema: { type: 'integer', minimum: 1 } } | |
| } | |
| }, | |
| '400': jsonContent('#/components/schemas/AgentError'), | |
| '409': jsonContent('#/components/schemas/AgentError'), | |
| ...commonAgentErrors, | |
| '422': jsonContent('#/components/schemas/AgentError'), | |
| '500': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.job]: { | |
| get: { | |
| summary: '获取 Agent job 状态', | |
| security: agentSecurity, | |
| parameters: [{ $ref: '#/components/parameters/JobId' }], | |
| responses: { | |
| '200': jsonContent('#/components/schemas/AgentJobStatusResponse'), | |
| '401': jsonContent('#/components/schemas/AgentError'), | |
| '404': jsonContent('#/components/schemas/AgentError'), | |
| '410': jsonContent('#/components/schemas/AgentError'), | |
| '500': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.job_result]: { | |
| get: { | |
| summary: '获取 Agent job 结果', | |
| security: agentSecurity, | |
| parameters: [{ $ref: '#/components/parameters/JobId' }], | |
| responses: { | |
| '200': jsonContent('#/components/schemas/AgentImageResponse'), | |
| '401': jsonContent('#/components/schemas/AgentError'), | |
| '403': jsonContent('#/components/schemas/AgentError'), | |
| '404': jsonContent('#/components/schemas/AgentError'), | |
| '409': { | |
| ...jsonContent('#/components/schemas/AgentError'), | |
| headers: { | |
| 'Retry-After': { schema: { type: 'integer', minimum: 1 } } | |
| } | |
| }, | |
| '410': jsonContent('#/components/schemas/AgentError'), | |
| '422': jsonContent('#/components/schemas/AgentError'), | |
| '429': jsonContent('#/components/schemas/AgentError'), | |
| '502': jsonContent('#/components/schemas/AgentError'), | |
| '500': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.artifact_metadata]: { | |
| get: { | |
| summary: '获取产物元数据', | |
| security: agentSecurity, | |
| parameters: [{ $ref: '#/components/parameters/ArtifactId' }], | |
| responses: { | |
| '200': jsonContent('#/components/schemas/ArtifactMetadataResponse'), | |
| '401': jsonContent('#/components/schemas/AgentError'), | |
| '404': jsonContent('#/components/schemas/AgentError') | |
| } | |
| }, | |
| delete: { | |
| summary: '删除产物', | |
| security: agentSecurity, | |
| parameters: [{ $ref: '#/components/parameters/ArtifactId' }], | |
| responses: { | |
| '200': jsonContent('#/components/schemas/DeleteArtifactResponse'), | |
| '401': jsonContent('#/components/schemas/AgentError'), | |
| '404': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.artifact_content]: { | |
| get: { | |
| summary: '下载产物内容', | |
| security: agentSecurity, | |
| parameters: [{ $ref: '#/components/parameters/ArtifactId' }], | |
| responses: { | |
| '200': { | |
| description: '图片二进制内容', | |
| content: { | |
| 'image/png': { schema: { type: 'string', format: 'binary' } }, | |
| 'image/jpeg': { schema: { type: 'string', format: 'binary' } }, | |
| 'image/webp': { schema: { type: 'string', format: 'binary' } } | |
| } | |
| }, | |
| '401': jsonContent('#/components/schemas/AgentError'), | |
| '404': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.artifact_share]: { | |
| post: { | |
| summary: '为 Agent 产物创建浏览器可访问的分享链接', | |
| security: agentSecurity, | |
| parameters: [{ $ref: '#/components/parameters/ArtifactId' }], | |
| requestBody: { | |
| required: false, | |
| ...jsonContent('#/components/schemas/CreateArtifactShareRequest') | |
| }, | |
| responses: { | |
| '201': jsonContent('#/components/schemas/ArtifactShareResponse'), | |
| '400': jsonContent('#/components/schemas/AgentError'), | |
| '401': jsonContent('#/components/schemas/AgentError'), | |
| '404': jsonContent('#/components/schemas/AgentError'), | |
| '500': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.page_request_feedback_batch]: { | |
| post: { | |
| summary: '批量读取页面请求的结果反馈', | |
| security: agentSecurity, | |
| requestBody: { | |
| required: true, | |
| ...jsonContent('#/components/schemas/PageRequestFeedbackBatchRequest') | |
| }, | |
| responses: { | |
| '200': jsonContent('#/components/schemas/PageRequestFeedbackBatchResponse'), | |
| '401': jsonContent('#/components/schemas/AgentError'), | |
| '422': jsonContent('#/components/schemas/AgentError'), | |
| '500': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.page_request_feedback]: { | |
| get: { | |
| summary: '读取页面请求的结果反馈', | |
| security: agentSecurity, | |
| parameters: [{ $ref: '#/components/parameters/PageRequestId' }], | |
| responses: { | |
| '200': jsonContent('#/components/schemas/PageRequestFeedbackResponse'), | |
| '401': jsonContent('#/components/schemas/AgentError'), | |
| '422': jsonContent('#/components/schemas/AgentError'), | |
| '500': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.channel_health_diagnostics]: { | |
| get: { | |
| summary: '读取当前进程的渠道健康诊断快照', | |
| description: | |
| '只读返回当前进程内存中的渠道、凭证和请求方式状态;不会为了读取而初始化路由或启动恢复探测,因此不会触发上游探测或图片生成,也不代表真实上游可用性。', | |
| security: agentSecurity, | |
| responses: { | |
| '200': jsonContent('#/components/schemas/AgentChannelHealthDiagnosticsResponse'), | |
| '401': jsonContent('#/components/schemas/AgentError'), | |
| '500': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.agent_request_diagnostics_lookup]: { | |
| get: { | |
| summary: '按 request_id 或 idempotency_key 读取 Agent state 请求诊断', | |
| security: agentSecurity, | |
| parameters: [ | |
| { | |
| name: 'request_id', | |
| in: 'query', | |
| required: false, | |
| schema: { type: 'string', minLength: 1, maxLength: 200 } | |
| }, | |
| { | |
| name: 'idempotency_key', | |
| in: 'query', | |
| required: false, | |
| schema: { type: 'string', minLength: 1, maxLength: 200 } | |
| } | |
| ], | |
| responses: { | |
| '200': jsonContent('#/components/schemas/AgentRequestDiagnosticsLookupResponse'), | |
| '401': jsonContent('#/components/schemas/AgentError'), | |
| '404': jsonContent('#/components/schemas/AgentRequestDiagnosticsLookupResponse'), | |
| '422': jsonContent('#/components/schemas/AgentError'), | |
| '500': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.agent_request_diagnostics]: { | |
| get: { | |
| summary: '按 request_id 读取 Agent state 请求诊断', | |
| security: agentSecurity, | |
| parameters: [{ $ref: '#/components/parameters/AgentRequestId' }], | |
| responses: { | |
| '200': jsonContent('#/components/schemas/AgentRequestDiagnosticsLookupResponse'), | |
| '401': jsonContent('#/components/schemas/AgentError'), | |
| '404': jsonContent('#/components/schemas/AgentRequestDiagnosticsLookupResponse'), | |
| '422': jsonContent('#/components/schemas/AgentError'), | |
| '500': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.page_request_diagnostics_batch]: { | |
| post: { | |
| summary: '批量读取页面请求的日志诊断摘要', | |
| security: agentSecurity, | |
| requestBody: { | |
| required: true, | |
| ...jsonContent('#/components/schemas/PageRequestDiagnosticsBatchRequest') | |
| }, | |
| responses: { | |
| '200': jsonContent('#/components/schemas/PageRequestDiagnosticsBatchResponse'), | |
| '401': jsonContent('#/components/schemas/AgentError'), | |
| '422': jsonContent('#/components/schemas/AgentError'), | |
| '500': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| }, | |
| [AGENT_ENDPOINTS.page_request_diagnostics]: { | |
| get: { | |
| summary: '读取页面请求的日志诊断摘要', | |
| security: agentSecurity, | |
| parameters: [ | |
| { $ref: '#/components/parameters/PageRequestId' }, | |
| { | |
| name: 'filename', | |
| in: 'query', | |
| required: false, | |
| schema: { type: 'array', items: { type: 'string' } }, | |
| style: 'form', | |
| explode: true | |
| } | |
| ], | |
| responses: { | |
| '200': jsonContent('#/components/schemas/PageRequestDiagnosticsResponse'), | |
| '401': jsonContent('#/components/schemas/AgentError'), | |
| '422': jsonContent('#/components/schemas/AgentError'), | |
| '500': jsonContent('#/components/schemas/AgentError') | |
| } | |
| } | |
| } | |
| }, | |
| components: { | |
| securitySchemes, | |
| parameters: { | |
| IdempotencyKey: { | |
| name: 'Idempotency-Key', | |
| in: 'header', | |
| required: true, | |
| schema: { type: 'string', minLength: 1, maxLength: 200 } | |
| }, | |
| ArtifactId: { | |
| name: 'id', | |
| in: 'path', | |
| required: true, | |
| schema: { type: 'string', minLength: 1 } | |
| }, | |
| JobId: { | |
| name: 'id', | |
| in: 'path', | |
| required: true, | |
| schema: { type: 'string', minLength: 1 } | |
| }, | |
| AgentRequestId: { | |
| name: 'id', | |
| in: 'path', | |
| required: true, | |
| schema: { type: 'string', minLength: 1, maxLength: 200 } | |
| }, | |
| PageRequestId: { | |
| name: 'id', | |
| in: 'path', | |
| required: true, | |
| schema: { type: 'string', minLength: 1, maxLength: 200 } | |
| } | |
| }, | |
| schemas: { | |
| AgentCapabilities: { | |
| type: 'object', | |
| required: [ | |
| 'api_version', | |
| 'schema_version', | |
| 'auth', | |
| 'endpoints', | |
| 'image_transport', | |
| 'upstream_profile', | |
| 'upstream_request_headers', | |
| 'request_mode_controls', | |
| 'defaults', | |
| 'limits', | |
| 'force_request_controls', | |
| 'model_limits', | |
| 'agent_streaming', | |
| 'orchestration', | |
| 'routing_rules', | |
| 'agent_jobs', | |
| 'supported', | |
| 'storage', | |
| 'page_request_diagnostics', | |
| 'agent_request_diagnostics', | |
| 'channel_health_diagnostics', | |
| 'idempotency' | |
| ], | |
| properties: { | |
| api_version: { type: 'string' }, | |
| schema_version: { type: 'string' }, | |
| auth: { | |
| type: 'object', | |
| required: ['required', 'schemes'], | |
| properties: { | |
| required: { type: 'boolean', const: capabilities.auth.required }, | |
| schemes: { | |
| type: 'array', | |
| items: { type: 'string' }, | |
| const: capabilities.auth.schemes | |
| } | |
| } | |
| }, | |
| endpoints: { type: 'object', additionalProperties: { type: 'string' } }, | |
| image_transport: { $ref: '#/components/schemas/ImageTransportCapabilities' }, | |
| upstream_request_headers: { | |
| type: 'object', | |
| required: ['default', 'channels'], | |
| properties: { | |
| default: { $ref: '#/components/schemas/UpstreamRequestHeaderSummary' }, | |
| channels: { | |
| type: 'array', | |
| items: { | |
| type: 'object', | |
| required: [ | |
| 'id', | |
| 'upstream_proxy', | |
| 'request_modes', | |
| 'request_mode_priority', | |
| 'request_headers' | |
| ], | |
| properties: { | |
| id: { type: 'string' }, | |
| upstream_proxy: { $ref: '#/components/schemas/UpstreamProxySummary' }, | |
| request_modes: { | |
| type: 'array', | |
| items: { type: 'string', enum: CHANNEL_REQUEST_MODES } | |
| }, | |
| request_mode_priority: { | |
| type: 'array', | |
| items: { type: 'string', enum: CHANNEL_REQUEST_MODES } | |
| }, | |
| request_headers: { | |
| $ref: '#/components/schemas/UpstreamRequestHeaderSummary' | |
| } | |
| }, | |
| additionalProperties: false | |
| } | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| request_mode_controls: { $ref: '#/components/schemas/AgentRequestModeControls' }, | |
| upstream_profile: { | |
| type: 'object', | |
| required: [ | |
| 'activeProfile', | |
| 'serverProfile', | |
| 'serverProfileMixed', | |
| 'requestProfile', | |
| 'activeConstraints', | |
| 'serverConstraints', | |
| 'requestConstraints' | |
| ], | |
| properties: { | |
| activeProfile: { | |
| type: 'string', | |
| enum: ['openai-compatible', 'matsca'], | |
| const: capabilities.upstream_profile.activeProfile | |
| }, | |
| serverProfile: { | |
| type: 'string', | |
| enum: ['openai-compatible', 'matsca'], | |
| const: capabilities.upstream_profile.serverProfile | |
| }, | |
| serverProfileMixed: { | |
| type: 'boolean', | |
| const: capabilities.upstream_profile.serverProfileMixed | |
| }, | |
| requestProfile: { | |
| type: 'string', | |
| enum: ['openai-compatible', 'matsca'], | |
| const: capabilities.upstream_profile.requestProfile | |
| }, | |
| activeConstraints: { $ref: '#/components/schemas/ImageUpstreamProfile' }, | |
| serverConstraints: { $ref: '#/components/schemas/ImageUpstreamProfile' }, | |
| requestConstraints: { $ref: '#/components/schemas/ImageUpstreamProfile' } | |
| }, | |
| additionalProperties: false | |
| }, | |
| defaults: { | |
| type: 'object', | |
| required: [ | |
| 'model', | |
| 'response_mode', | |
| 'state_backend', | |
| 'image_backend', | |
| 'stream_mode', | |
| 'streaming_strategy', | |
| 'partial_images' | |
| ], | |
| properties: { | |
| model: { type: 'string', enum: AGENT_MODELS }, | |
| response_mode: { type: 'string', enum: AGENT_RESPONSE_MODES }, | |
| state_backend: { type: 'string', enum: ['memory', 'sqlite', 'postgres'] }, | |
| image_backend: { type: 'string', enum: AGENT_IMAGE_BACKENDS }, | |
| stream_mode: { type: 'string', enum: AGENT_STREAM_MODES }, | |
| streaming_strategy: { type: 'string', enum: AGENT_STREAMING_STRATEGIES }, | |
| partial_images: { | |
| type: 'integer', | |
| minimum: capabilities.limits.partial_images.min, | |
| maximum: capabilities.limits.partial_images.max | |
| } | |
| } | |
| }, | |
| limits: { | |
| type: 'object', | |
| required: [ | |
| 'max_prompt_length', | |
| 'max_images', | |
| 'generate_images', | |
| 'edit_images', | |
| 'upload_images', | |
| 'max_upload_mb', | |
| 'partial_images', | |
| 'partial_images_by_backend', | |
| 'upstream_profile', | |
| 'upstream_profile_mixed' | |
| ], | |
| properties: { | |
| max_prompt_length: { type: 'integer', const: capabilities.limits.max_prompt_length }, | |
| max_images: { type: 'integer', const: capabilities.limits.max_images }, | |
| generate_images: { | |
| type: 'object', | |
| required: ['min', 'max'], | |
| properties: { | |
| min: { type: 'integer', const: capabilities.limits.generate_images.min }, | |
| max: { type: 'integer', const: capabilities.limits.generate_images.max } | |
| }, | |
| additionalProperties: false | |
| }, | |
| edit_images: { | |
| type: 'object', | |
| required: ['min', 'max'], | |
| properties: { | |
| min: { type: 'integer', const: capabilities.limits.edit_images.min }, | |
| max: { type: 'integer', const: capabilities.limits.edit_images.max } | |
| }, | |
| additionalProperties: false | |
| }, | |
| upload_images: { | |
| type: 'object', | |
| required: ['max'], | |
| properties: { | |
| max: { type: 'integer', const: capabilities.limits.upload_images.max } | |
| }, | |
| additionalProperties: false | |
| }, | |
| max_upload_mb: { type: 'number', const: capabilities.limits.max_upload_mb }, | |
| max_total_upload_mb: { type: 'number', const: capabilities.limits.max_total_upload_mb }, | |
| partial_images: { | |
| type: 'object', | |
| required: ['min', 'max'], | |
| properties: { | |
| min: { type: 'integer', const: capabilities.limits.partial_images.min }, | |
| max: { type: 'integer', const: capabilities.limits.partial_images.max } | |
| }, | |
| additionalProperties: false | |
| }, | |
| partial_images_by_backend: { | |
| type: 'object', | |
| required: ['images-api', 'responses-image-generation'], | |
| properties: { | |
| 'images-api': { | |
| type: 'object', | |
| required: ['min', 'max'], | |
| properties: { | |
| min: { | |
| type: 'integer', | |
| const: capabilities.limits.partial_images_by_backend['images-api'] | |
| .min | |
| }, | |
| max: { | |
| type: 'integer', | |
| const: capabilities.limits.partial_images_by_backend['images-api'] | |
| .max | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| 'responses-image-generation': { | |
| type: 'object', | |
| required: ['min', 'max'], | |
| properties: { | |
| min: { | |
| type: 'integer', | |
| const: capabilities.limits.partial_images_by_backend[ | |
| 'responses-image-generation' | |
| ].min | |
| }, | |
| max: { | |
| type: 'integer', | |
| const: capabilities.limits.partial_images_by_backend[ | |
| 'responses-image-generation' | |
| ].max | |
| } | |
| }, | |
| additionalProperties: false | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| upstream_profile: { | |
| type: 'string', | |
| enum: ['openai-compatible', 'matsca'], | |
| const: capabilities.limits.upstream_profile | |
| }, | |
| upstream_profile_mixed: { | |
| type: 'boolean', | |
| const: capabilities.limits.upstream_profile_mixed | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| model_limits: { $ref: '#/components/schemas/AgentModelLimits' }, | |
| force_request_controls: { | |
| type: 'object', | |
| required: ['field', 'cli_flag', 'default', 'effect', 'still_enforced', 'intended_for'], | |
| properties: { | |
| field: { type: 'string', const: capabilities.force_request_controls.field }, | |
| cli_flag: { type: 'string', const: capabilities.force_request_controls.cli_flag }, | |
| default: { type: 'boolean', const: false }, | |
| effect: { type: 'string', const: capabilities.force_request_controls.effect }, | |
| still_enforced: { | |
| type: 'array', | |
| items: { type: 'string' }, | |
| const: capabilities.force_request_controls.still_enforced | |
| }, | |
| intended_for: { | |
| type: 'array', | |
| items: { type: 'string' }, | |
| const: capabilities.force_request_controls.intended_for | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| agent_streaming: { $ref: '#/components/schemas/AgentStreamingCapabilities' }, | |
| orchestration: { $ref: '#/components/schemas/AgentOrchestrationCapabilities' }, | |
| routing_rules: { $ref: '#/components/schemas/AgentRoutingRules' }, | |
| agent_jobs: { $ref: '#/components/schemas/AgentJobCapabilities' }, | |
| supported: { | |
| type: 'object', | |
| required: [ | |
| 'models', | |
| 'output_formats', | |
| 'response_modes', | |
| 'qualities', | |
| 'backgrounds', | |
| 'moderations', | |
| 'legacy_sizes', | |
| 'image_backends', | |
| 'enabled_image_backends', | |
| 'image_backend_requirements', | |
| 'request_modes', | |
| 'streaming_strategies', | |
| 'stream_modes' | |
| ], | |
| properties: { | |
| models: { type: 'array', items: { type: 'string', enum: AGENT_MODELS } }, | |
| output_formats: { | |
| type: 'array', | |
| items: { type: 'string', enum: AGENT_OUTPUT_FORMATS } | |
| }, | |
| response_modes: { | |
| type: 'array', | |
| items: { type: 'string', enum: AGENT_RESPONSE_MODES } | |
| }, | |
| qualities: { type: 'array', items: { type: 'string', enum: AGENT_QUALITIES } }, | |
| backgrounds: { type: 'array', items: { type: 'string', enum: AGENT_BACKGROUNDS } }, | |
| moderations: { type: 'array', items: { type: 'string', enum: AGENT_MODERATIONS } }, | |
| legacy_sizes: { type: 'array', items: { type: 'string' } }, | |
| image_backends: { | |
| type: 'array', | |
| items: { type: 'string', enum: AGENT_IMAGE_BACKENDS } | |
| }, | |
| enabled_image_backends: { | |
| type: 'array', | |
| items: { type: 'string', enum: AGENT_IMAGE_BACKENDS } | |
| }, | |
| image_backend_requirements: { | |
| type: 'object', | |
| additionalProperties: { $ref: '#/components/schemas/ImageBackendRequirement' } | |
| }, | |
| request_modes: { | |
| type: 'array', | |
| items: { type: 'string', enum: CHANNEL_REQUEST_MODES } | |
| }, | |
| streaming_strategies: { | |
| type: 'array', | |
| items: { type: 'string', enum: AGENT_STREAMING_STRATEGIES } | |
| }, | |
| stream_modes: { | |
| type: 'array', | |
| items: { type: 'string', enum: AGENT_STREAM_MODES } | |
| } | |
| } | |
| }, | |
| storage: { | |
| type: 'object', | |
| required: ['image_storage_mode', 'postgres_configured'], | |
| properties: { | |
| image_storage_mode: { type: 'string' }, | |
| postgres_configured: { type: 'boolean' } | |
| } | |
| }, | |
| page_request_diagnostics: { | |
| $ref: '#/components/schemas/AgentPageRequestDiagnosticsCapabilities' | |
| }, | |
| agent_request_diagnostics: { | |
| $ref: '#/components/schemas/AgentRequestDiagnosticsCapabilities' | |
| }, | |
| channel_health_diagnostics: { | |
| $ref: '#/components/schemas/AgentChannelHealthDiagnosticsCapabilities' | |
| }, | |
| idempotency: { type: 'object' } | |
| } | |
| }, | |
| AgentModelLimits: { | |
| type: 'object', | |
| required: ['gpt-image-2'], | |
| properties: { | |
| 'gpt-image-2': { | |
| type: 'object', | |
| required: [ | |
| 'max_edge', | |
| 'max_pixels', | |
| 'edge_multiple', | |
| 'max_aspect', | |
| 'min_pixels', | |
| 'recommended_presets', | |
| 'large_image_risk' | |
| ], | |
| properties: { | |
| max_edge: { type: 'integer', minimum: 1 }, | |
| max_pixels: { type: 'integer', minimum: 1 }, | |
| edge_multiple: { type: 'integer', minimum: 1 }, | |
| max_aspect: { type: 'number', minimum: 1 }, | |
| min_pixels: { type: 'integer', minimum: 1 }, | |
| recommended_presets: { | |
| type: 'array', | |
| items: { | |
| type: 'object', | |
| required: ['name', 'size', 'purpose'], | |
| properties: { | |
| name: { type: 'string' }, | |
| size: { type: 'string' }, | |
| purpose: { type: 'string' } | |
| } | |
| } | |
| }, | |
| large_image_risk: { | |
| type: 'object', | |
| required: ['applies_to', 'guidance'], | |
| properties: { | |
| applies_to: { type: 'array', items: { type: 'string' } }, | |
| guidance: { type: 'string' } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| ImageUpstreamProfile: { | |
| type: 'object', | |
| required: ['id', 'generateCount', 'editCount', 'partialImages', 'upload', 'gptImage2'], | |
| properties: { | |
| id: { type: 'string', enum: ['openai-compatible', 'matsca'] }, | |
| generateCount: { | |
| type: 'object', | |
| required: ['min', 'max'], | |
| properties: { | |
| min: { type: 'integer', minimum: 1 }, | |
| max: { type: 'integer', minimum: 1 } | |
| }, | |
| additionalProperties: false | |
| }, | |
| editCount: { | |
| type: 'object', | |
| required: ['min', 'max'], | |
| properties: { | |
| min: { type: 'integer', minimum: 1 }, | |
| max: { type: 'integer', minimum: 1 } | |
| }, | |
| additionalProperties: false | |
| }, | |
| partialImages: { | |
| type: 'object', | |
| required: ['min', 'max'], | |
| properties: { | |
| min: { type: 'integer', minimum: 0 }, | |
| max: { type: 'integer', minimum: 0 } | |
| }, | |
| additionalProperties: false | |
| }, | |
| upload: { | |
| type: 'object', | |
| required: ['maxImages', 'maxSingleBytes'], | |
| properties: { | |
| maxImages: { type: 'integer', minimum: 1 }, | |
| maxSingleBytes: { type: 'integer', minimum: 1 }, | |
| maxTotalBytes: { type: 'integer', minimum: 1 } | |
| }, | |
| additionalProperties: false | |
| }, | |
| gptImage2: { | |
| type: 'object', | |
| required: ['allowTransparentBackground', 'sizePolicy'], | |
| properties: { | |
| allowTransparentBackground: { type: 'boolean' }, | |
| sizePolicy: { type: 'string', enum: ['openai-compatible', 'positive-integer'] } | |
| }, | |
| additionalProperties: false | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| ImageBackendRequirement: { | |
| type: 'object', | |
| required: ['supported', 'enabled', 'required_env', 'missing_env'], | |
| properties: { | |
| supported: { type: 'boolean', const: true }, | |
| enabled: { type: 'boolean' }, | |
| required_env: { type: 'array', items: { type: 'string' } }, | |
| missing_env: { type: 'array', items: { type: 'string' } } | |
| } | |
| }, | |
| AppLogRetentionMetadata: { | |
| type: 'object', | |
| required: [ | |
| 'storage', | |
| 'max_entries', | |
| 'default_max_entries', | |
| 'min_entries', | |
| 'max_configured_entries', | |
| 'configured_by', | |
| 'persisted_across_process_restart', | |
| 'loss_modes', | |
| 'bounded', | |
| 'not_agent_state_backend' | |
| ], | |
| properties: { | |
| storage: { | |
| type: 'string', | |
| const: capabilities.page_request_diagnostics.retention.storage | |
| }, | |
| max_entries: { | |
| type: 'integer', | |
| minimum: 1, | |
| const: capabilities.page_request_diagnostics.retention.max_entries | |
| }, | |
| default_max_entries: { | |
| type: 'integer', | |
| minimum: 1, | |
| const: capabilities.page_request_diagnostics.retention.default_max_entries | |
| }, | |
| min_entries: { | |
| type: 'integer', | |
| minimum: 1, | |
| const: capabilities.page_request_diagnostics.retention.min_entries | |
| }, | |
| max_configured_entries: { | |
| type: 'integer', | |
| minimum: 1, | |
| const: capabilities.page_request_diagnostics.retention.max_configured_entries | |
| }, | |
| configured_by: { | |
| type: 'string', | |
| const: capabilities.page_request_diagnostics.retention.configured_by | |
| }, | |
| persisted_across_process_restart: { type: 'boolean', const: true }, | |
| loss_modes: { | |
| type: 'array', | |
| items: { type: 'string' }, | |
| const: capabilities.page_request_diagnostics.retention.loss_modes | |
| }, | |
| bounded: { type: 'boolean', const: true }, | |
| not_agent_state_backend: { type: 'boolean', const: true } | |
| } | |
| }, | |
| AgentPageRequestDiagnosticsCapabilities: { | |
| type: 'object', | |
| required: ['supported', 'source', 'endpoints', 'retention', 'no_match_hint'], | |
| properties: { | |
| supported: { type: 'boolean', const: true }, | |
| source: { type: 'string', enum: ['app_log'] }, | |
| endpoints: { | |
| type: 'object', | |
| required: ['single', 'batch'], | |
| properties: { | |
| single: { type: 'string', const: AGENT_ENDPOINTS.page_request_diagnostics }, | |
| batch: { type: 'string', const: AGENT_ENDPOINTS.page_request_diagnostics_batch } | |
| } | |
| }, | |
| retention: { $ref: '#/components/schemas/AppLogRetentionMetadata' }, | |
| no_match_hint: { | |
| type: 'string', | |
| const: capabilities.page_request_diagnostics.no_match_hint | |
| } | |
| } | |
| }, | |
| AgentRequestDiagnosticsRetention: { | |
| type: 'object', | |
| required: ['storage', 'ttl_seconds', 'bounded', 'loss_modes'], | |
| properties: { | |
| storage: { | |
| type: 'string', | |
| const: capabilities.agent_request_diagnostics.retention.storage | |
| }, | |
| ttl_seconds: { | |
| type: 'integer', | |
| minimum: 1, | |
| const: capabilities.agent_request_diagnostics.retention.ttl_seconds | |
| }, | |
| bounded: { type: 'boolean', const: true }, | |
| loss_modes: { | |
| type: 'array', | |
| items: { type: 'string' }, | |
| const: capabilities.agent_request_diagnostics.retention.loss_modes | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentRequestDiagnosticsCapabilities: { | |
| type: 'object', | |
| required: ['supported', 'source', 'endpoints', 'lookup', 'retention'], | |
| properties: { | |
| supported: { type: 'boolean', const: true }, | |
| source: { type: 'string', enum: ['agent_state'] }, | |
| endpoints: { | |
| type: 'object', | |
| required: ['lookup', 'single'], | |
| properties: { | |
| lookup: { type: 'string', const: AGENT_ENDPOINTS.agent_request_diagnostics_lookup }, | |
| single: { type: 'string', const: AGENT_ENDPOINTS.agent_request_diagnostics } | |
| }, | |
| additionalProperties: false | |
| }, | |
| lookup: { | |
| type: 'object', | |
| required: ['by_request_id', 'by_idempotency_key'], | |
| properties: { | |
| by_request_id: { type: 'boolean', const: true }, | |
| by_idempotency_key: { type: 'boolean', const: true } | |
| }, | |
| additionalProperties: false | |
| }, | |
| retention: { $ref: '#/components/schemas/AgentRequestDiagnosticsRetention' } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentChannelHealthDiagnosticsCapabilities: { | |
| type: 'object', | |
| required: ['supported', 'endpoint', 'source', 'state_scope', 'billable'], | |
| properties: { | |
| supported: { type: 'boolean', const: true }, | |
| endpoint: { type: 'string', const: AGENT_ENDPOINTS.channel_health_diagnostics }, | |
| source: { type: 'string', const: 'in_process_channel_router' }, | |
| state_scope: { type: 'string', const: 'process_local' }, | |
| billable: { type: 'boolean', const: false } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentChannelHealthDiagnosticsResponse: { | |
| type: 'object', | |
| required: ['ok', 'billable', 'source', 'state_scope', 'state_initialized', 'snapshot'], | |
| properties: { | |
| ok: { type: 'boolean', const: true }, | |
| billable: { type: 'boolean', const: false }, | |
| source: { type: 'string', const: 'in_process_channel_router' }, | |
| state_scope: { type: 'string', const: 'process_local' }, | |
| state_initialized: { type: 'boolean' }, | |
| snapshot: { $ref: '#/components/schemas/AgentChannelHealthSnapshot' } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentChannelHealthSnapshot: { | |
| type: 'object', | |
| required: ['observed_at', 'channels'], | |
| properties: { | |
| observed_at: { type: 'integer', minimum: 0 }, | |
| channels: { | |
| type: 'array', | |
| items: { $ref: '#/components/schemas/AgentChannelHealthChannel' } | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentChannelHealthChannel: { | |
| type: 'object', | |
| required: [ | |
| 'channel_id', | |
| 'credential_count', | |
| 'healthy_credential_count', | |
| 'unhealthy_credential_count', | |
| 'state', | |
| 'probe_required', | |
| 'upstream_proxy', | |
| 'credentials' | |
| ], | |
| properties: { | |
| channel_id: { type: 'string' }, | |
| upstream_proxy: { $ref: '#/components/schemas/UpstreamProxySummary' }, | |
| credential_count: { type: 'integer', minimum: 0 }, | |
| healthy_credential_count: { type: 'integer', minimum: 0 }, | |
| unhealthy_credential_count: { type: 'integer', minimum: 0 }, | |
| state: { type: 'string', enum: ['healthy', 'cooldown', 'probe_pending'] }, | |
| probe_required: { type: 'boolean' }, | |
| credentials: { | |
| type: 'array', | |
| items: { $ref: '#/components/schemas/AgentChannelHealthCredential' } | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentChannelHealthCredential: { | |
| type: 'object', | |
| required: ['credential_id', 'state', 'probe_required', 'request_modes'], | |
| properties: { | |
| credential_id: { type: 'string' }, | |
| state: { type: 'string', enum: ['healthy', 'cooldown', 'probe_pending'] }, | |
| cooldown_until: { type: 'integer', minimum: 0 }, | |
| probe_required: { type: 'boolean' }, | |
| last_failure: { $ref: '#/components/schemas/AgentChannelHealthFailure' }, | |
| request_modes: { | |
| type: 'array', | |
| items: { $ref: '#/components/schemas/AgentChannelHealthRequestMode' } | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentChannelHealthRequestMode: { | |
| type: 'object', | |
| required: ['mode', 'state', 'probe_required'], | |
| properties: { | |
| mode: { type: 'string', enum: CHANNEL_REQUEST_MODES }, | |
| state: { type: 'string', enum: ['healthy', 'cooldown', 'probe_pending'] }, | |
| cooldown_until: { type: 'integer', minimum: 0 }, | |
| probe_required: { type: 'boolean' } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentChannelHealthFailure: { | |
| type: 'object', | |
| required: ['at', 'scope'], | |
| properties: { | |
| at: { type: 'integer', minimum: 0 }, | |
| scope: { type: 'string', enum: ['credential', 'channel'] }, | |
| status: { type: 'integer' }, | |
| code: { type: 'string' }, | |
| request_id: { type: 'string' }, | |
| request_mode: { type: 'string', enum: CHANNEL_REQUEST_MODES } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentStreamingCapabilities: { | |
| type: 'object', | |
| required: ['generate', 'edit', 'upstream_sse', 'page_sse'], | |
| properties: { | |
| generate: { $ref: '#/components/schemas/AgentEndpointStreamingCapability' }, | |
| edit: { $ref: '#/components/schemas/AgentEndpointStreamingCapability' }, | |
| upstream_sse: { | |
| type: 'object', | |
| required: [ | |
| 'supported', | |
| 'mode', | |
| 'endpoint', | |
| 'request_fields', | |
| 'request_fields_by_mode', | |
| 'image_backends', | |
| 'enabled_image_backends', | |
| 'streaming_strategies', | |
| 'stream_modes', | |
| 'activation_strategies', | |
| 'final_response_contract' | |
| ], | |
| properties: { | |
| supported: { type: 'boolean', const: true }, | |
| mode: { type: 'string', enum: ['internal_upstream_sse'] }, | |
| endpoint: { type: 'string' }, | |
| request_fields: { | |
| type: 'array', | |
| items: { type: 'string' }, | |
| const: AGENT_UPSTREAM_SSE_GENERATE_REQUEST_FIELDS | |
| }, | |
| request_fields_by_mode: { | |
| type: 'object', | |
| required: ['generate', 'edit'], | |
| properties: { | |
| generate: { | |
| type: 'array', | |
| items: { type: 'string' }, | |
| const: AGENT_UPSTREAM_SSE_GENERATE_REQUEST_FIELDS | |
| }, | |
| edit: { | |
| type: 'array', | |
| items: { type: 'string' }, | |
| const: AGENT_UPSTREAM_SSE_EDIT_REQUEST_FIELDS | |
| } | |
| } | |
| }, | |
| image_backends: { | |
| type: 'array', | |
| items: { type: 'string', enum: AGENT_IMAGE_BACKENDS } | |
| }, | |
| enabled_image_backends: { | |
| type: 'array', | |
| items: { type: 'string', enum: AGENT_IMAGE_BACKENDS } | |
| }, | |
| streaming_strategies: { | |
| type: 'array', | |
| items: { type: 'string', enum: AGENT_STREAMING_STRATEGIES } | |
| }, | |
| stream_modes: { | |
| type: 'array', | |
| items: { type: 'string', enum: AGENT_STREAM_MODES } | |
| }, | |
| activation_strategies: { | |
| type: 'array', | |
| items: { type: 'string', enum: AGENT_UPSTREAM_SSE_ACTIVATION_STRATEGIES } | |
| }, | |
| final_response_contract: { type: 'string', enum: ['AgentImageResponse'] } | |
| } | |
| }, | |
| page_sse: { | |
| type: 'object', | |
| required: [ | |
| 'supported', | |
| 'mode', | |
| 'endpoint', | |
| 'contract', | |
| 'transport_contract', | |
| 'auth', | |
| 'client_request_id', | |
| 'agent_usage' | |
| ], | |
| properties: { | |
| supported: { type: 'boolean', const: true }, | |
| mode: { type: 'string', enum: ['form_data_sse'] }, | |
| endpoint: { type: 'string' }, | |
| contract: { type: 'string', enum: ['page_ui_only'] }, | |
| transport_contract: { type: 'string', enum: ['page_form_data_sse'] }, | |
| auth: { | |
| type: 'object', | |
| required: ['required', 'schemes', 'form_field'], | |
| properties: { | |
| required: { | |
| type: 'boolean', | |
| const: capabilities.agent_streaming.page_sse.auth.required | |
| }, | |
| schemes: { | |
| type: 'array', | |
| items: { type: 'string', enum: ['form-password-hash'] }, | |
| const: capabilities.agent_streaming.page_sse.auth.schemes | |
| }, | |
| form_field: { type: 'string', const: 'passwordHash' } | |
| } | |
| }, | |
| client_request_id: { | |
| type: 'object', | |
| required: ['form_field', 'source_header', 'max_length'], | |
| properties: { | |
| form_field: { type: 'string', const: 'clientRequestId' }, | |
| source_header: { type: 'string', const: 'Idempotency-Key' }, | |
| max_length: { | |
| type: 'integer', | |
| const: capabilities.agent_streaming.page_sse.client_request_id.max_length | |
| } | |
| } | |
| }, | |
| agent_usage: { | |
| type: 'string', | |
| enum: [AGENT_PAGE_SSE_AGENT_USAGE] | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| AgentRoutingRules: { | |
| type: 'object', | |
| required: [ | |
| 'high_resolution_edit', | |
| 'complex_ui_batch', | |
| 'long_image_recovery', | |
| 'agent_generate_small_smoke', | |
| 'page_sse_generate_diagnostics', | |
| 'retry_recovery' | |
| ], | |
| properties: { | |
| high_resolution_edit: { $ref: '#/components/schemas/AgentRoutingRule' }, | |
| complex_ui_batch: { $ref: '#/components/schemas/AgentRoutingRule' }, | |
| long_image_recovery: { $ref: '#/components/schemas/AgentRoutingRule' }, | |
| agent_generate_small_smoke: { $ref: '#/components/schemas/AgentRoutingRule' }, | |
| page_sse_generate_diagnostics: { $ref: '#/components/schemas/AgentRoutingRule' }, | |
| retry_recovery: { | |
| type: 'object', | |
| required: ['reuse_failed_idempotency_key', 'new_attempt_guidance'], | |
| properties: { | |
| reuse_failed_idempotency_key: { type: 'boolean', const: false }, | |
| new_attempt_guidance: { type: 'string' } | |
| } | |
| } | |
| } | |
| }, | |
| AgentRoutingRule: { | |
| type: 'object', | |
| required: ['when', 'conditions', 'endpoint', 'transport', 'strength', 'action', 'reason'], | |
| properties: { | |
| when: { type: 'array', items: { type: 'string' } }, | |
| conditions: { $ref: '#/components/schemas/AgentRoutingCondition' }, | |
| endpoint: { type: 'string' }, | |
| transport: { | |
| type: 'string', | |
| enum: ['agent_json', 'agent_job_polling', 'page_sse'] satisfies AgentRoutingTransport[] | |
| }, | |
| strength: { | |
| type: 'string', | |
| enum: ['default', 'recommended', 'explicit'] satisfies AgentRoutingStrength[] | |
| }, | |
| action: { $ref: '#/components/schemas/AgentRoutingAction' }, | |
| reason: { type: 'string' } | |
| } | |
| }, | |
| AgentRoutingCondition: { | |
| type: 'object', | |
| required: ['operation'], | |
| properties: { | |
| operation: { | |
| type: 'string', | |
| enum: ['generate', 'edit', 'generate_or_edit'] | |
| }, | |
| max_edge: { | |
| type: 'object', | |
| required: ['operator', 'value'], | |
| properties: { | |
| operator: { type: 'string', enum: ['gt', 'lte'] }, | |
| value: { type: 'integer', minimum: 1 } | |
| } | |
| }, | |
| batch: { type: 'boolean' }, | |
| single_request: { type: 'boolean' }, | |
| explicit_page_sse: { type: 'boolean' }, | |
| complex_ui: { type: 'boolean' }, | |
| long_image: { type: 'boolean' }, | |
| resume_or_recover: { type: 'boolean' } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentRoutingAction: { | |
| type: 'object', | |
| required: [ | |
| 'endpoint', | |
| 'transport', | |
| 'strength', | |
| 'requires_new_idempotency_key_on_retry', | |
| 'no_automatic_fallback' | |
| ], | |
| properties: { | |
| endpoint: { type: 'string' }, | |
| transport: { | |
| type: 'string', | |
| enum: ['agent_json', 'agent_job_polling', 'page_sse'] satisfies AgentRoutingTransport[] | |
| }, | |
| strength: { | |
| type: 'string', | |
| enum: ['default', 'recommended', 'explicit'] satisfies AgentRoutingStrength[] | |
| }, | |
| fallback_endpoint: { type: 'string' }, | |
| fallback_mode: { | |
| type: 'string', | |
| enum: ['manual_after_diagnosis', 'fix_request_before_retry'] | |
| }, | |
| requires_new_idempotency_key_on_retry: { type: 'boolean' }, | |
| no_automatic_fallback: { type: 'boolean' } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentEndpointStreamingCapability: { | |
| type: 'object', | |
| required: ['supported', 'mode', 'endpoint'], | |
| properties: { | |
| supported: { type: 'boolean', const: false }, | |
| mode: { type: 'string', enum: ['non_streaming_only'] }, | |
| endpoint: { type: 'string' } | |
| } | |
| }, | |
| AgentJobCapabilities: { | |
| type: 'object', | |
| required: ['supported', 'mode', 'intended_for', 'endpoints', 'states', 'current_guidance'], | |
| properties: { | |
| supported: { type: 'boolean', const: true }, | |
| mode: { type: 'string', enum: ['job_polling'] }, | |
| intended_for: { type: 'array', items: { type: 'string' } }, | |
| endpoints: { | |
| type: 'object', | |
| required: ['create_generate_job', 'get_job', 'get_job_result'], | |
| properties: { | |
| create_generate_job: { type: 'string' }, | |
| get_job: { type: 'string' }, | |
| get_job_result: { type: 'string' } | |
| } | |
| }, | |
| states: { type: 'array', items: { type: 'string', enum: AGENT_JOB_STATES } }, | |
| current_guidance: { type: 'string' } | |
| } | |
| }, | |
| AgentOrchestrationCapabilities: { | |
| type: 'object', | |
| required: [ | |
| 'supported', | |
| 'policy', | |
| 'endpoint', | |
| 'client_contract', | |
| 'transport_selection', | |
| 'result_mode', | |
| 'hidden_controls', | |
| 'diagnostics', | |
| 'current_guidance' | |
| ], | |
| properties: { | |
| supported: { type: 'boolean', const: true }, | |
| policy: { | |
| type: 'string', | |
| enum: ['server_orchestrated_generate_v1'] | |
| }, | |
| endpoint: { type: 'string', const: AGENT_ENDPOINTS.create_image_request }, | |
| client_contract: { type: 'string', enum: ['intent_only'] }, | |
| transport_selection: { type: 'string', enum: ['server_owned'] }, | |
| result_mode: { type: 'string', enum: ['job_polling'] }, | |
| hidden_controls: { type: 'array', items: { type: 'string' } }, | |
| diagnostics: { | |
| type: 'object', | |
| required: ['job_result', 'request_lookup'], | |
| properties: { | |
| job_result: { type: 'string', const: AGENT_ENDPOINTS.job_result }, | |
| request_lookup: { | |
| type: 'string', | |
| const: AGENT_ENDPOINTS.agent_request_diagnostics_lookup | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| current_guidance: { type: 'string' } | |
| }, | |
| additionalProperties: false | |
| }, | |
| GenerateRequest: { | |
| type: 'object', | |
| required: ['prompt'], | |
| allOf: [ | |
| { | |
| if: { | |
| properties: { | |
| image_backend: { const: 'responses-image-generation' } | |
| }, | |
| required: ['image_backend'] | |
| }, | |
| then: { | |
| properties: { | |
| partial_images: { | |
| type: 'integer', | |
| minimum: | |
| capabilities.limits.partial_images_by_backend['responses-image-generation'] | |
| .min, | |
| maximum: | |
| capabilities.limits.partial_images_by_backend['responses-image-generation'] | |
| .max, | |
| default: capabilities.defaults.partial_images | |
| } | |
| } | |
| } | |
| }, | |
| { | |
| if: { | |
| not: { | |
| properties: { | |
| force_request: { const: true } | |
| }, | |
| required: ['force_request'] | |
| } | |
| }, | |
| then: { | |
| properties: { | |
| background: { type: 'string', enum: supportedBackgrounds } | |
| } | |
| } | |
| } | |
| ], | |
| properties: { | |
| prompt: { type: 'string', maxLength: MAX_PROMPT_LENGTH }, | |
| model: { type: 'string', enum: AGENT_MODELS }, | |
| n: { | |
| type: 'integer', | |
| minimum: capabilities.limits.generate_images.min, | |
| maximum: maxGenerateImageCount | |
| }, | |
| size: { type: 'string' }, | |
| quality: { type: 'string', enum: AGENT_QUALITIES, default: 'high' }, | |
| output_format: { type: 'string', enum: AGENT_OUTPUT_FORMATS }, | |
| output_compression: { type: 'integer', minimum: 0, maximum: 100 }, | |
| background: { type: 'string', enum: AGENT_BACKGROUNDS }, | |
| moderation: { type: 'string', enum: AGENT_MODERATIONS }, | |
| response_mode: { type: 'string', enum: AGENT_RESPONSE_MODES, default: 'path' }, | |
| image_backend: { | |
| type: 'string', | |
| enum: AGENT_IMAGE_BACKENDS, | |
| default: 'images-api' | |
| }, | |
| responsesModel: { | |
| type: 'string', | |
| maxLength: 128, | |
| description: | |
| 'Responses image_generation 顶层模型;仅适用于 image_backend=responses-image-generation。' | |
| }, | |
| thinking: { | |
| type: 'string', | |
| enum: ['minimal', 'none', 'low', 'medium', 'high', 'xhigh'] | |
| }, | |
| promptOptimization: { type: 'boolean' }, | |
| force_web: { type: 'boolean' }, | |
| force_request: { | |
| type: 'boolean', | |
| description: | |
| '显式强制请求上游,跳过本服务本地 upstream profile 尺寸/背景限制;鉴权、幂等键、渠道白名单和安全校验仍然生效。' | |
| }, | |
| streaming_strategy: { | |
| type: 'string', | |
| enum: AGENT_STREAMING_STRATEGIES, | |
| default: 'auto' | |
| }, | |
| stream_mode: { | |
| type: 'string', | |
| enum: AGENT_STREAM_MODES, | |
| default: 'auto' | |
| }, | |
| partial_images: { | |
| type: 'integer', | |
| minimum: capabilities.limits.partial_images.min, | |
| maximum: capabilities.limits.partial_images.max, | |
| default: capabilities.defaults.partial_images | |
| } | |
| } | |
| }, | |
| EditRequest: { | |
| type: 'object', | |
| required: ['prompt'], | |
| anyOf: Array.from({ length: maxSourceImageCount }, (_, index) => ({ | |
| required: [`image_${index}`] | |
| })), | |
| description: `Agent edit 返回最终 JSON。请求必须至少提供一个 image_0..image_${maxSourceImageCount - 1} 源图字段。高分辨率 edit 默认优先使用页面端 /api/images form-data SSE;页面流式有问题时可显式回退到 Agent edit 诊断或执行。`, | |
| properties: { | |
| prompt: { type: 'string', maxLength: MAX_PROMPT_LENGTH }, | |
| model: { type: 'string', enum: AGENT_MODELS, default: 'gpt-image-2' }, | |
| n: { | |
| type: 'integer', | |
| minimum: capabilities.limits.edit_images.min, | |
| maximum: maxEditImageCount | |
| }, | |
| size: { type: 'string', default: 'auto' }, | |
| quality: { type: 'string', enum: AGENT_QUALITIES, default: 'auto' }, | |
| response_mode: { type: 'string', enum: AGENT_RESPONSE_MODES, default: 'path' }, | |
| stream_mode: { type: 'string', enum: AGENT_STREAM_MODES, default: 'auto' }, | |
| streaming_strategy: { | |
| type: 'string', | |
| enum: AGENT_STREAMING_STRATEGIES, | |
| default: 'auto' | |
| }, | |
| force_request: { | |
| type: 'boolean', | |
| description: | |
| '显式强制请求上游,跳过本服务本地 upstream profile 尺寸限制;鉴权、幂等键、渠道白名单、图片数量、partial_images、文件大小和 mask 校验仍然生效。' | |
| }, | |
| partial_images: { | |
| type: 'integer', | |
| minimum: capabilities.limits.partial_images.min, | |
| maximum: capabilities.limits.partial_images.max, | |
| default: capabilities.defaults.partial_images | |
| }, | |
| ...Object.fromEntries( | |
| Array.from({ length: maxSourceImageCount }, (_, index) => [ | |
| `image_${index}`, | |
| { type: 'string', format: 'binary' } | |
| ]) | |
| ), | |
| mask: { type: 'string', format: 'binary' } | |
| } | |
| }, | |
| AgentArtifact: { | |
| type: 'object', | |
| required: [ | |
| 'id', | |
| 'filename', | |
| 'content_url', | |
| 'metadata_url', | |
| 'output_format', | |
| 'mime_type', | |
| 'size_bytes', | |
| 'width', | |
| 'height' | |
| ], | |
| properties: { | |
| id: { type: 'string' }, | |
| filename: { type: 'string' }, | |
| content_url: { type: 'string' }, | |
| metadata_url: { type: 'string' }, | |
| output_format: { type: 'string', enum: AGENT_OUTPUT_FORMATS }, | |
| mime_type: { type: 'string' }, | |
| size_bytes: { type: 'integer', minimum: 0 }, | |
| width: { type: ['integer', 'null'] }, | |
| height: { type: ['integer', 'null'] }, | |
| b64_json: { type: 'string' } | |
| } | |
| }, | |
| AgentImageResponse: { | |
| type: 'object', | |
| required: ['request_id', 'idempotency_key', 'cached', 'images', 'created_at'], | |
| properties: { | |
| request_id: { type: 'string' }, | |
| idempotency_key: { type: 'string' }, | |
| cached: { type: 'boolean' }, | |
| images: { | |
| type: 'array', | |
| items: { $ref: '#/components/schemas/AgentArtifact' } | |
| }, | |
| usage: { type: 'object' }, | |
| created_at: { type: 'string', format: 'date-time' }, | |
| timing: { $ref: '#/components/schemas/AgentImageResponseTiming' }, | |
| execution: { $ref: '#/components/schemas/AgentImageResponseExecution' } | |
| } | |
| }, | |
| AgentImageResponseTiming: { | |
| type: 'object', | |
| required: ['started_at', 'completed_at', 'elapsed_ms', 'server_elapsed_ms'], | |
| properties: { | |
| started_at: { type: 'string', format: 'date-time' }, | |
| completed_at: { type: 'string', format: 'date-time' }, | |
| elapsed_ms: { type: 'integer', minimum: 0 }, | |
| server_elapsed_ms: { type: 'integer', minimum: 0 } | |
| }, | |
| additionalProperties: false | |
| }, | |
| ChannelRequestModeDecision: { | |
| type: 'object', | |
| required: ['requested_backend', 'fallback_applied'], | |
| properties: { | |
| requested_backend: { type: 'string', enum: AGENT_IMAGE_BACKENDS }, | |
| candidate_channel_request_modes: { | |
| type: 'array', | |
| items: { type: 'string', enum: CHANNEL_REQUEST_MODES } | |
| }, | |
| request_mode_priority: { | |
| type: 'array', | |
| items: { type: 'string', enum: CHANNEL_REQUEST_MODES } | |
| }, | |
| preferred_channel_request_mode: { type: 'string', enum: CHANNEL_REQUEST_MODES }, | |
| fallback_channel_request_mode: { type: 'string', enum: CHANNEL_REQUEST_MODES }, | |
| selected_channel_request_mode: { type: 'string', enum: CHANNEL_REQUEST_MODES }, | |
| fallback_applied: { type: 'boolean' }, | |
| selected_channel_id: { type: 'string' }, | |
| upstream_host: { type: 'string' }, | |
| no_channel_reason: { type: 'string' } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentImageResponseExecution: { | |
| type: 'object', | |
| required: [ | |
| 'transport', | |
| 'endpoint', | |
| 'route_mode', | |
| 'operation', | |
| 'image_backend', | |
| 'stream_mode', | |
| 'streaming_strategy', | |
| 'channel_request_mode_fallback_applied', | |
| 'route_decision', | |
| 'request_headers' | |
| ], | |
| properties: { | |
| transport: { type: 'string', enum: ['agent_json', 'agent_job_polling', 'page_sse'] }, | |
| endpoint: { type: 'string' }, | |
| route_mode: { type: 'string', enum: ['agent', 'job', 'page_sse'] }, | |
| operation: { type: 'string', enum: ['generate', 'edit'] }, | |
| image_backend: { type: 'string', enum: AGENT_IMAGE_BACKENDS }, | |
| stream_mode: { type: 'string', enum: AGENT_STREAM_MODES }, | |
| streaming_strategy: { type: 'string', enum: AGENT_STREAMING_STRATEGIES }, | |
| channel_request_mode: { type: 'string', enum: CHANNEL_REQUEST_MODES }, | |
| channel_request_mode_fallback_applied: { type: 'boolean' }, | |
| route_decision: { $ref: '#/components/schemas/ChannelRequestModeDecision' }, | |
| selected_channel_id: { type: 'string' }, | |
| upstream_host: { type: 'string' }, | |
| request_headers: { $ref: '#/components/schemas/UpstreamRequestHeaderSummary' } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentJobStatusResponse: { | |
| type: 'object', | |
| required: ['job'], | |
| properties: { | |
| job: { | |
| type: 'object', | |
| required: [ | |
| 'id', | |
| 'request_id', | |
| 'idempotency_key', | |
| 'mode', | |
| 'state', | |
| 'created_at', | |
| 'updated_at', | |
| 'expires_at' | |
| ], | |
| properties: { | |
| id: { type: 'string' }, | |
| request_id: { type: 'string' }, | |
| idempotency_key: { type: 'string' }, | |
| mode: { type: 'string', enum: ['generate', 'edit'] }, | |
| state: { type: 'string', enum: AGENT_JOB_STATES }, | |
| created_at: { type: 'string', format: 'date-time' }, | |
| updated_at: { type: 'string', format: 'date-time' }, | |
| expires_at: { type: 'string', format: 'date-time' }, | |
| result_url: { type: 'string' }, | |
| retry_after_seconds: { type: 'integer', minimum: 1 }, | |
| error: { | |
| type: 'object', | |
| required: ['code', 'message', 'retryable'], | |
| properties: { | |
| code: { type: 'string' }, | |
| message: { type: 'string' }, | |
| retryable: { type: 'boolean' }, | |
| details: { type: 'object' }, | |
| upstream_status: { type: 'integer' }, | |
| diagnostics: { $ref: '#/components/schemas/AgentErrorDiagnostics' } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| ArtifactMetadataResponse: { | |
| type: 'object', | |
| required: ['artifact'], | |
| properties: { | |
| artifact: { $ref: '#/components/schemas/AgentArtifact' } | |
| } | |
| }, | |
| CreateArtifactShareRequest: { | |
| type: 'object', | |
| properties: { | |
| expires_in_minutes: { | |
| oneOf: [{ type: 'integer', minimum: 1 }, { type: 'null' }], | |
| description: '分享有效期分钟数;null 表示不过期,省略时使用服务端默认值。' | |
| }, | |
| access_code: { | |
| anyOf: [ | |
| { type: 'string', pattern: '^\\s*$' }, | |
| { type: 'string', minLength: 8, maxLength: 128 } | |
| ], | |
| description: '可选访问码;省略或空白字符串表示公开分享。' | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| ArtifactShareResponse: { | |
| type: 'object', | |
| required: [ | |
| 'artifact_id', | |
| 'token', | |
| 'share_url', | |
| 'direct_content_url', | |
| 'expires_at', | |
| 'access_code_required' | |
| ], | |
| properties: { | |
| artifact_id: { type: 'string' }, | |
| token: { type: 'string', pattern: '^[a-f0-9]{24}$' }, | |
| share_url: { type: 'string' }, | |
| direct_content_url: { type: 'string' }, | |
| expires_at: { | |
| oneOf: [{ type: 'string', format: 'date-time' }, { type: 'null' }] | |
| }, | |
| access_code_required: { type: 'boolean' } | |
| }, | |
| additionalProperties: false | |
| }, | |
| DeleteArtifactResponse: { | |
| type: 'object', | |
| required: ['deleted', 'id'], | |
| properties: { | |
| deleted: { type: 'boolean' }, | |
| id: { type: 'string' } | |
| } | |
| }, | |
| ResultFeedback: { | |
| type: 'object', | |
| required: ['target_type', 'target_id', 'value', 'source', 'updated_at'], | |
| properties: { | |
| target_type: { type: 'string', enum: ['page_request', 'agent_request', 'agent_artifact'] }, | |
| target_id: { type: 'string' }, | |
| value: { type: 'string', enum: ['usable', 'needs_revision'] }, | |
| source: { type: 'string', enum: ['webui', 'agent'] }, | |
| updated_at: { type: 'string', format: 'date-time' }, | |
| note: { type: 'string', maxLength: 500 } | |
| } | |
| }, | |
| FeedbackTarget: { | |
| type: 'object', | |
| required: ['type', 'id'], | |
| properties: { | |
| type: { type: 'string', enum: ['page_request'] }, | |
| id: { type: 'string' } | |
| } | |
| }, | |
| PageRequestFeedbackBatchRequest: { | |
| type: 'object', | |
| required: ['ids'], | |
| properties: { | |
| ids: { type: 'array', minItems: 1, maxItems: 50, items: { type: 'string' } } | |
| } | |
| }, | |
| PageRequestFeedbackBatchResponse: { | |
| type: 'object', | |
| required: ['targets', 'feedback'], | |
| properties: { | |
| targets: { type: 'array', items: { $ref: '#/components/schemas/FeedbackTarget' } }, | |
| feedback: { type: 'array', items: { $ref: '#/components/schemas/ResultFeedback' } } | |
| } | |
| }, | |
| PageRequestFeedbackResponse: { | |
| type: 'object', | |
| required: ['target', 'feedback'], | |
| properties: { | |
| target: { $ref: '#/components/schemas/FeedbackTarget' }, | |
| feedback: { | |
| oneOf: [{ $ref: '#/components/schemas/ResultFeedback' }, { type: 'null' }] | |
| } | |
| } | |
| }, | |
| PageRequestDiagnosticsBatchRequest: { | |
| type: 'object', | |
| required: ['ids'], | |
| properties: { | |
| ids: { type: 'array', minItems: 1, maxItems: 50, items: { type: 'string' } }, | |
| filenames: { type: 'array', maxItems: 20, items: { type: 'string' } } | |
| } | |
| }, | |
| AgentRequestDiagnosticsLookupResponse: { | |
| type: 'object', | |
| required: ['found'], | |
| properties: { | |
| found: { type: 'boolean' }, | |
| diagnostics: { $ref: '#/components/schemas/AgentRequestDiagnostics' } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentRequestDiagnostics: { | |
| type: 'object', | |
| required: [ | |
| 'request', | |
| 'timeline', | |
| 'artifacts', | |
| 'state_backend', | |
| 'diagnostics_retention', | |
| 'diagnostics_boundary' | |
| ], | |
| properties: { | |
| request: { $ref: '#/components/schemas/AgentRequestDiagnosticsRequest' }, | |
| timeline: { | |
| type: 'array', | |
| items: { $ref: '#/components/schemas/AgentRequestTimelineEvent' } | |
| }, | |
| artifacts: { | |
| type: 'array', | |
| items: { $ref: '#/components/schemas/AgentRequestDiagnosticsArtifact' } | |
| }, | |
| response: { $ref: '#/components/schemas/AgentRequestDiagnosticsResponseSummary' }, | |
| error: { $ref: '#/components/schemas/AgentRequestDiagnosticsErrorSummary' }, | |
| feedback: { $ref: '#/components/schemas/ResultFeedback' }, | |
| state_backend: { type: 'string', enum: ['memory', 'sqlite', 'postgres'] }, | |
| diagnostics_retention: { $ref: '#/components/schemas/AgentRequestDiagnosticsRetention' }, | |
| diagnostics_boundary: { | |
| type: 'object', | |
| required: [ | |
| 'source', | |
| 'not_page_request_log', | |
| 'raw_request_json_redacted', | |
| 'api_key_redacted' | |
| ], | |
| properties: { | |
| source: { type: 'string', enum: ['agent_state'] }, | |
| not_page_request_log: { type: 'boolean', const: true }, | |
| raw_request_json_redacted: { type: 'boolean', const: true }, | |
| api_key_redacted: { type: 'boolean', const: true } | |
| }, | |
| additionalProperties: false | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentRequestDiagnosticsRequest: { | |
| type: 'object', | |
| required: [ | |
| 'request_id', | |
| 'idempotency_key', | |
| 'mode', | |
| 'status', | |
| 'cached', | |
| 'created_at', | |
| 'updated_at', | |
| 'expires_at' | |
| ], | |
| properties: { | |
| request_id: { type: 'string' }, | |
| idempotency_key: { type: 'string' }, | |
| mode: { type: 'string', enum: ['generate', 'edit'] }, | |
| status: { type: 'string', enum: ['pending', 'running', 'succeeded', 'failed', 'orphaned'] }, | |
| cached: { type: 'boolean' }, | |
| created_at: { type: 'string', format: 'date-time' }, | |
| updated_at: { type: 'string', format: 'date-time' }, | |
| expires_at: { type: 'string', format: 'date-time' }, | |
| locked_until: { type: 'string', format: 'date-time' } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentRequestTimelineEvent: { | |
| type: 'object', | |
| required: ['at', 'event'], | |
| properties: { | |
| at: { type: 'string', format: 'date-time' }, | |
| event: { type: 'string', enum: ['created', 'updated', 'locked_until', 'expires'] } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentRequestDiagnosticsArtifact: { | |
| type: 'object', | |
| required: [ | |
| 'id', | |
| 'filename', | |
| 'content_url', | |
| 'metadata_url', | |
| 'output_format', | |
| 'mime_type', | |
| 'size_bytes', | |
| 'width', | |
| 'height', | |
| 'model', | |
| 'created_at' | |
| ], | |
| properties: { | |
| id: { type: 'string' }, | |
| filename: { type: 'string' }, | |
| content_url: { type: 'string' }, | |
| metadata_url: { type: 'string' }, | |
| output_format: { type: 'string' }, | |
| mime_type: { type: 'string' }, | |
| size_bytes: { type: 'integer', minimum: 0 }, | |
| width: { type: ['integer', 'null'] }, | |
| height: { type: ['integer', 'null'] }, | |
| model: { type: 'string' }, | |
| created_at: { type: 'string', format: 'date-time' } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentRequestDiagnosticsResponseSummary: { | |
| type: 'object', | |
| required: [ | |
| 'request_id', | |
| 'idempotency_key', | |
| 'cached', | |
| 'image_count', | |
| 'artifact_ids', | |
| 'content_urls', | |
| 'created_at' | |
| ], | |
| properties: { | |
| request_id: { type: 'string' }, | |
| idempotency_key: { type: 'string' }, | |
| cached: { type: 'boolean' }, | |
| image_count: { type: 'integer', minimum: 0 }, | |
| artifact_ids: { type: 'array', items: { type: 'string' } }, | |
| content_urls: { type: 'array', items: { type: 'string' } }, | |
| created_at: { type: 'string', format: 'date-time' }, | |
| timing: { $ref: '#/components/schemas/AgentImageResponseTiming' }, | |
| execution: { $ref: '#/components/schemas/AgentImageResponseExecution' } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentRequestDiagnosticsErrorSummary: { | |
| type: 'object', | |
| required: ['code', 'message', 'retryable'], | |
| properties: { | |
| code: { type: 'string' }, | |
| message: { type: 'string' }, | |
| retryable: { type: 'boolean' }, | |
| upstream_status: { type: 'integer' }, | |
| diagnostics: { $ref: '#/components/schemas/AgentErrorDiagnostics' } | |
| }, | |
| additionalProperties: false | |
| }, | |
| PageRequestDiagnosticsBatchItem: { | |
| allOf: [ | |
| { $ref: '#/components/schemas/PageRequestDiagnosticsResponse' }, | |
| { | |
| type: 'object', | |
| required: ['client_request_id'], | |
| properties: { | |
| client_request_id: { type: 'string' } | |
| } | |
| } | |
| ] | |
| }, | |
| PageRequestDiagnosticsBatchResponse: { | |
| type: 'object', | |
| required: ['targets', 'diagnostics_retention', 'diagnostics'], | |
| properties: { | |
| targets: { type: 'array', items: { $ref: '#/components/schemas/FeedbackTarget' } }, | |
| diagnostics_retention: { $ref: '#/components/schemas/AppLogRetentionMetadata' }, | |
| diagnostics: { | |
| type: 'array', | |
| items: { $ref: '#/components/schemas/PageRequestDiagnosticsBatchItem' } | |
| } | |
| } | |
| }, | |
| PageRequestDiagnosticsResponse: { | |
| type: 'object', | |
| required: ['scope', 'matched_log_count', 'events', 'diagnostics_retention'], | |
| properties: { | |
| scope: { | |
| type: 'object', | |
| required: ['request_ids', 'filenames', 'filename_matched_request_ids', 'copy_text'], | |
| properties: { | |
| request_ids: { type: 'array', items: { type: 'string' } }, | |
| filenames: { type: 'array', items: { type: 'string' } }, | |
| filename_matched_request_ids: { type: 'array', items: { type: 'string' } }, | |
| copy_text: { type: 'string' } | |
| } | |
| }, | |
| matched_log_count: { type: 'integer', minimum: 0 }, | |
| events: { | |
| type: 'array', | |
| items: { $ref: '#/components/schemas/PageRequestDiagnosticEvent' } | |
| }, | |
| diagnostics_retention: { $ref: '#/components/schemas/AppLogRetentionMetadata' }, | |
| diagnostics_note: { $ref: '#/components/schemas/PageRequestDiagnosticsNote' } | |
| } | |
| }, | |
| PageRequestDiagnosticsNote: { | |
| type: 'object', | |
| required: ['code', 'message', 'retention'], | |
| properties: { | |
| code: { type: 'string', enum: ['no_matching_logs_in_retention_window'] }, | |
| message: { type: 'string' }, | |
| retention: { $ref: '#/components/schemas/AppLogRetentionMetadata' } | |
| } | |
| }, | |
| PageRequestDiagnosticEvent: { | |
| type: 'object', | |
| required: ['id', 'at', 'level', 'message'], | |
| properties: { | |
| id: { type: 'integer' }, | |
| at: { type: 'string', format: 'date-time' }, | |
| level: { type: 'string', enum: ['debug', 'info', 'warn', 'error'] }, | |
| message: { type: 'string' }, | |
| client_request_id: { type: 'string' }, | |
| filenames: { type: 'array', items: { type: 'string' } }, | |
| diagnostics: { $ref: '#/components/schemas/PageRequestDiagnosticContext' } | |
| } | |
| }, | |
| PageRequestDiagnosticContext: { | |
| type: 'object', | |
| additionalProperties: false, | |
| properties: { | |
| providerDialect: { type: 'string' }, | |
| normalizedEventCount: { type: 'number' }, | |
| reason: { type: 'string' }, | |
| channel_id: { type: 'string' }, | |
| image_backend: { type: 'string' }, | |
| operation: { type: 'string' }, | |
| stream_mode: { type: 'string' }, | |
| streamingStrategy: { type: 'string' }, | |
| streaming_strategy: { type: 'string' }, | |
| partialImages: { type: 'number' }, | |
| partial_images: { type: 'number' }, | |
| upstream_status: { type: 'number' }, | |
| upstream_event_type: { type: 'string' }, | |
| transport_error: { type: 'boolean' } | |
| } | |
| }, | |
| AgentError: { | |
| type: 'object', | |
| required: ['error'], | |
| properties: { | |
| error: { | |
| type: 'object', | |
| required: ['code', 'message', 'retryable', 'request_id'], | |
| properties: { | |
| code: { type: 'string' }, | |
| message: { type: 'string' }, | |
| retryable: { type: 'boolean' }, | |
| details: { type: 'object' }, | |
| upstream_status: { type: 'integer' }, | |
| diagnostics: { $ref: '#/components/schemas/AgentErrorDiagnostics' }, | |
| request_id: { type: 'string' } | |
| } | |
| } | |
| } | |
| }, | |
| AgentErrorDiagnostics: { | |
| type: 'object', | |
| properties: { | |
| elapsed_ms: { type: 'integer', minimum: 0 }, | |
| channel_request_mode: { type: 'string', enum: CHANNEL_REQUEST_MODES }, | |
| channel_request_mode_fallback_applied: { type: 'boolean' }, | |
| route_decision: { $ref: '#/components/schemas/ChannelRequestModeDecision' }, | |
| selected_channel_id: { type: 'string' }, | |
| upstream_host: { type: 'string' }, | |
| upstream_status: { type: 'integer' }, | |
| upstream_event_type: { type: 'string' }, | |
| partial_image_count: { type: 'integer', minimum: 0 }, | |
| transport_error: { type: 'boolean' }, | |
| transport_error_kind: { | |
| type: 'string', | |
| enum: [ | |
| 'dns', | |
| 'tls', | |
| 'connect_timeout', | |
| 'connection_refused', | |
| 'socket_closed', | |
| 'upstream_timeout', | |
| 'sse_final_missing', | |
| 'fetch_failed', | |
| 'unknown_transport' | |
| ] | |
| }, | |
| retry_after_seconds: { type: 'integer', minimum: 1 }, | |
| retry_after_ms: { type: 'integer', minimum: 0 }, | |
| cooldown_until: { type: 'string', format: 'date-time' }, | |
| cooldown_target: { | |
| type: 'object', | |
| required: ['channel_id'], | |
| properties: { | |
| channel_id: { type: 'string' }, | |
| credential_id: { type: 'string' }, | |
| request_mode: { type: 'string', enum: CHANNEL_REQUEST_MODES } | |
| }, | |
| additionalProperties: false | |
| }, | |
| channel_cooldown_scope: { type: 'string', enum: ['credential', 'channel'] }, | |
| response_headers: { | |
| type: 'object', | |
| additionalProperties: { type: 'string' } | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| UpstreamRequestHeaderSummary: { | |
| type: 'object', | |
| required: [ | |
| 'user_agent_effective', | |
| 'has_extra_headers', | |
| 'allowed_header_names', | |
| 'configured_header_names' | |
| ], | |
| properties: { | |
| user_agent_effective: { type: 'string' }, | |
| has_extra_headers: { type: 'boolean' }, | |
| allowed_header_names: { | |
| type: 'array', | |
| items: { type: 'string' } | |
| }, | |
| configured_header_names: { | |
| type: 'array', | |
| items: { type: 'string' } | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| AgentRequestModeControls: { | |
| type: 'object', | |
| required: [ | |
| 'source', | |
| 'global_env', | |
| 'channel_env_pattern', | |
| 'global_priority_env', | |
| 'channel_priority_env_pattern', | |
| 'default_priority', | |
| 'default_priority_policy', | |
| 'mutable_at_runtime', | |
| 'agent_client_policy', | |
| 'final_gate_command', | |
| 'smoke_gate_commands' | |
| ], | |
| properties: { | |
| source: { type: 'string', const: 'admin_env_whitelist' }, | |
| global_env: { type: 'string' }, | |
| channel_env_pattern: { type: 'string' }, | |
| global_priority_env: { type: 'string' }, | |
| channel_priority_env_pattern: { type: 'string' }, | |
| default_priority: { | |
| type: 'array', | |
| items: { type: 'string', enum: CHANNEL_REQUEST_MODES } | |
| }, | |
| default_priority_policy: { type: 'string', const: 'lowest_cost_first' }, | |
| mutable_at_runtime: { type: 'boolean', const: false }, | |
| agent_client_policy: { type: 'string', const: 'diagnostics_only' }, | |
| final_gate_command: { type: 'string' }, | |
| smoke_gate_commands: { | |
| type: 'object', | |
| additionalProperties: { | |
| type: 'array', | |
| items: { type: 'string' } | |
| } | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| ImageTransportCapabilities: { | |
| type: 'object', | |
| required: [ | |
| 'upstream_timeout_ms', | |
| 'stream_data_interval_timeout_ms', | |
| 'upstream_max_retries', | |
| 'upstream_proxy' | |
| ], | |
| properties: { | |
| upstream_timeout_ms: { | |
| type: 'integer', | |
| minimum: 1, | |
| const: capabilities.image_transport.upstream_timeout_ms | |
| }, | |
| stream_data_interval_timeout_ms: { | |
| type: 'integer', | |
| minimum: 0, | |
| const: capabilities.image_transport.stream_data_interval_timeout_ms | |
| }, | |
| upstream_max_retries: { | |
| type: 'integer', | |
| minimum: 0, | |
| const: capabilities.image_transport.upstream_max_retries | |
| }, | |
| upstream_proxy: { | |
| $ref: '#/components/schemas/UpstreamProxySummary' | |
| } | |
| }, | |
| additionalProperties: false | |
| }, | |
| UpstreamProxySummary: { | |
| type: 'object', | |
| required: ['configured'], | |
| properties: { | |
| configured: { type: 'boolean' }, | |
| protocol: { type: 'string', enum: ['http', 'https'] } | |
| }, | |
| additionalProperties: false | |
| } | |
| } | |
| } | |
| }; | |
| } | |