Merged in feature/chatbot1 (pull request #223)
Chatbot functionality * baseline working * missing test file * more tests
This commit is contained in:
@@ -50,6 +50,16 @@ tags:
|
||||
(auditor is read-only). Requires the owning document to first be
|
||||
bound to a client_metadata_schemas row via PATCH
|
||||
/super-admin/documents/{id}/schema.
|
||||
- name: BotService
|
||||
description: |
|
||||
Owner-scoped chatbot session/scope/turn endpoints for client_user.
|
||||
Sessions are visible only to their creator within a client.
|
||||
Routes use the singular `/client/{clientId}/...` form per plan §3.
|
||||
- name: SuperAdminBotService
|
||||
description: |
|
||||
Super-admin-only chatbot session endpoints. Lists, reads, and
|
||||
soft-deletes bot sessions across all users within a client.
|
||||
Restricted to the super_admin Permit.io role.
|
||||
|
||||
paths:
|
||||
|
||||
@@ -3245,6 +3255,496 @@ paths:
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/client/{clientId}/bot/sessions:
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/BotClientID"
|
||||
post:
|
||||
operationId: createBotSession
|
||||
tags:
|
||||
- BotService
|
||||
summary: Create a new chatbot session
|
||||
description: >-
|
||||
Creates an owner-scoped chatbot session for the authenticated
|
||||
client_user. The Cognito subject (JWT sub) becomes createdBy.
|
||||
Title defaults to empty until the first turn arrives.
|
||||
security:
|
||||
- jwtAuth: []
|
||||
requestBody:
|
||||
description: Empty body — accepted for forward compatibility.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/CreateBotSessionRequest"
|
||||
responses:
|
||||
"201":
|
||||
description: Session created.
|
||||
headers:
|
||||
RateLimit:
|
||||
$ref: "#/components/headers/RateLimit"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BotSessionResponse"
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"429":
|
||||
$ref: "#/components/responses/TooManyRequests"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
get:
|
||||
operationId: listBotSessions
|
||||
tags:
|
||||
- BotService
|
||||
summary: List the caller's chatbot sessions for a client
|
||||
description: >-
|
||||
Returns sessions owned by the authenticated user under this
|
||||
clientId, newest-updated first. Each session carries a recentTurns
|
||||
preview whose length is min(request.limit, cfg.RecentTurns)
|
||||
per plan §3. Plan §3 bounds: limit in [1, 200] and offset >= 0.
|
||||
security:
|
||||
- jwtAuth: []
|
||||
parameters:
|
||||
- name: limit
|
||||
in: query
|
||||
required: false
|
||||
description: Maximum number of sessions to return (1-200, default 20).
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 1
|
||||
maximum: 200
|
||||
default: 20
|
||||
- name: offset
|
||||
in: query
|
||||
required: false
|
||||
description: Number of sessions to skip for pagination (default 0).
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 0
|
||||
maximum: 2147483647
|
||||
default: 0
|
||||
responses:
|
||||
"200":
|
||||
description: Session list with embedded recent-turn previews.
|
||||
headers:
|
||||
RateLimit:
|
||||
$ref: "#/components/headers/RateLimit"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BotSessionListResponse"
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"429":
|
||||
$ref: "#/components/responses/TooManyRequests"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/client/{clientId}/bot/sessions/{sessionId}:
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/BotClientID"
|
||||
- $ref: "#/components/parameters/BotSessionID"
|
||||
get:
|
||||
operationId: getBotSession
|
||||
tags:
|
||||
- BotService
|
||||
summary: Get one chatbot session by id
|
||||
description: >-
|
||||
Owner-scoped read. Returns 404 when the session belongs to a
|
||||
different client, a different user, or has been soft-deleted.
|
||||
security:
|
||||
- jwtAuth: []
|
||||
responses:
|
||||
"200":
|
||||
description: Session details.
|
||||
headers:
|
||||
RateLimit:
|
||||
$ref: "#/components/headers/RateLimit"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BotSessionResponse"
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"429":
|
||||
$ref: "#/components/responses/TooManyRequests"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/client/{clientId}/bot/sessions/{sessionId}/turns:
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/BotClientID"
|
||||
- $ref: "#/components/parameters/BotSessionID"
|
||||
post:
|
||||
operationId: createBotTurn
|
||||
tags:
|
||||
- BotService
|
||||
summary: Submit a new chatbot turn
|
||||
description: >-
|
||||
Posts a new turn to the chatbot session. Plan §6 algorithm: tx1
|
||||
locks the session, abandons grace-expired in_flight rows, and
|
||||
either inserts a fresh in_flight row at the next ordinal or
|
||||
resets a terminal-failure row for retry. The FastAPI agent is
|
||||
called outside any DB transaction, then tx2 records the
|
||||
outcome via compare-and-set on attempt_id. Returns 201 on
|
||||
success with the persisted turn body. FastAPI failures persist
|
||||
an errored row and return 502 with the error body.
|
||||
security:
|
||||
- jwtAuth: []
|
||||
requestBody:
|
||||
description: Prompt to submit.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/CreateBotTurnRequest"
|
||||
responses:
|
||||
"201":
|
||||
description: Turn completed.
|
||||
headers:
|
||||
RateLimit:
|
||||
$ref: "#/components/headers/RateLimit"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BotTurnResponse"
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"409":
|
||||
$ref: "#/components/responses/Conflict"
|
||||
"410":
|
||||
description: Session was deleted while the agent call was in flight.
|
||||
headers:
|
||||
RateLimit:
|
||||
$ref: "#/components/headers/RateLimit"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorMessage"
|
||||
"429":
|
||||
$ref: "#/components/responses/TooManyRequests"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
"502":
|
||||
description: FastAPI agent failed; persisted errored row in body.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorMessage"
|
||||
get:
|
||||
operationId: listBotTurns
|
||||
tags:
|
||||
- BotService
|
||||
summary: List all turns for a chatbot session
|
||||
description: >-
|
||||
Returns every persisted turn for the owner-scoped session,
|
||||
ordered ASC by ordinal. Plan §11.
|
||||
security:
|
||||
- jwtAuth: []
|
||||
responses:
|
||||
"200":
|
||||
description: Ordered list of turns.
|
||||
headers:
|
||||
RateLimit:
|
||||
$ref: "#/components/headers/RateLimit"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BotTurnListResponse"
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"429":
|
||||
$ref: "#/components/responses/TooManyRequests"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/client/{clientId}/bot/sessions/{sessionId}/scope:
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/BotClientID"
|
||||
- $ref: "#/components/parameters/BotSessionID"
|
||||
patch:
|
||||
operationId: patchBotSessionScope
|
||||
tags:
|
||||
- BotService
|
||||
summary: Patch a session's document/folder scope
|
||||
description: >-
|
||||
Adds or removes documents and folders from a session's scope.
|
||||
Duplicate ids inside add/remove are deduplicated. An id appearing
|
||||
in both add and remove returns 400 add_remove_conflict. A document
|
||||
or folder belonging to a different client returns 400
|
||||
document_cross_client / folder_cross_client. The persisted scope
|
||||
is the union of (existing - remove) ∪ add.
|
||||
security:
|
||||
- jwtAuth: []
|
||||
requestBody:
|
||||
description: Add/remove sets for documents and folders.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BotSessionScopePatchRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: Updated session, including the new scope.
|
||||
headers:
|
||||
RateLimit:
|
||||
$ref: "#/components/headers/RateLimit"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BotSessionResponse"
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"429":
|
||||
$ref: "#/components/responses/TooManyRequests"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/client/{clientId}/documents/{documentId}/schema:
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/BotClientID"
|
||||
- $ref: "#/components/parameters/M5DocumentID"
|
||||
get:
|
||||
operationId: getDocumentSchema
|
||||
tags:
|
||||
- BotService
|
||||
summary: Get the bound custom schema for a document
|
||||
description: >-
|
||||
Returns the JSON Schema body bound to the document via
|
||||
documents.custom_schema_id. The composite FK in migration 128
|
||||
guarantees the schema row's client_id matches the document's
|
||||
clientId, so the M1 GetDocumentEnrichedForClient query is
|
||||
sufficient for cross-client rejection. When the document has no
|
||||
schema bound, the endpoint returns 200 with `schema: null`. Plan
|
||||
§3 + §10 M5.
|
||||
security:
|
||||
- jwtAuth: []
|
||||
responses:
|
||||
"200":
|
||||
description: Schema body or null when unbound.
|
||||
headers:
|
||||
RateLimit:
|
||||
$ref: "#/components/headers/RateLimit"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DocumentSchemaResponse"
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"429":
|
||||
$ref: "#/components/responses/TooManyRequests"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/client/{clientId}/documents/{documentId}/all-metadata:
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/BotClientID"
|
||||
- $ref: "#/components/parameters/M5DocumentID"
|
||||
get:
|
||||
operationId: getDocumentAllMetadata
|
||||
tags:
|
||||
- BotService
|
||||
summary: Get document metadata bundle (document + labels + customMetadata)
|
||||
description: >-
|
||||
Composes three M1 client-scoped reads
|
||||
(GetDocumentEnrichedForClient, GetDocumentLabelsForClient,
|
||||
GetCurrentDocumentCustomMetadataForClient) into a single bundle
|
||||
for the chatbot UI. labels is always a non-null array; when the
|
||||
document has no schema bound or no metadata rows, customMetadata
|
||||
is null. Plan §3 + §10 M5.
|
||||
security:
|
||||
- jwtAuth: []
|
||||
responses:
|
||||
"200":
|
||||
description: Document, labels, and customMetadata.
|
||||
headers:
|
||||
RateLimit:
|
||||
$ref: "#/components/headers/RateLimit"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DocumentAllMetadataResponse"
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"429":
|
||||
$ref: "#/components/responses/TooManyRequests"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/super-admin/bot/sessions:
|
||||
get:
|
||||
operationId: listBotSessionsAsSuperAdmin
|
||||
tags:
|
||||
- SuperAdminBotService
|
||||
summary: List chatbot sessions for a client (super-admin)
|
||||
description: >-
|
||||
Super-admin client-scoped list. Filters on clientId and
|
||||
is_deleted=false; no created_by predicate. limit in [1, 200],
|
||||
offset >= 0.
|
||||
security:
|
||||
- jwtAuth: []
|
||||
parameters:
|
||||
- name: clientId
|
||||
in: query
|
||||
required: true
|
||||
description: The client whose sessions to list.
|
||||
schema:
|
||||
type: string
|
||||
maxLength: 255
|
||||
- name: limit
|
||||
in: query
|
||||
required: false
|
||||
description: Maximum number of sessions to return (1-200, default 20).
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 1
|
||||
maximum: 200
|
||||
default: 20
|
||||
- name: offset
|
||||
in: query
|
||||
required: false
|
||||
description: Number of sessions to skip for pagination (default 0).
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 0
|
||||
maximum: 2147483647
|
||||
default: 0
|
||||
responses:
|
||||
"200":
|
||||
description: Session list across all users in the client.
|
||||
headers:
|
||||
RateLimit:
|
||||
$ref: "#/components/headers/RateLimit"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BotSessionListResponse"
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/Forbidden"
|
||||
"429":
|
||||
$ref: "#/components/responses/TooManyRequests"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/super-admin/bot/sessions/{sessionId}:
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/BotSessionID"
|
||||
get:
|
||||
operationId: getBotSessionAsSuperAdmin
|
||||
tags:
|
||||
- SuperAdminBotService
|
||||
summary: Get one chatbot session by id (super-admin)
|
||||
description: >-
|
||||
Super-admin read. Filters on clientId (query param) and
|
||||
is_deleted=false. Returns 404 when the session does not match.
|
||||
security:
|
||||
- jwtAuth: []
|
||||
parameters:
|
||||
- name: clientId
|
||||
in: query
|
||||
required: true
|
||||
description: The client that owns the session.
|
||||
schema:
|
||||
type: string
|
||||
maxLength: 255
|
||||
responses:
|
||||
"200":
|
||||
description: Session details.
|
||||
headers:
|
||||
RateLimit:
|
||||
$ref: "#/components/headers/RateLimit"
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BotSessionResponse"
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/Forbidden"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"429":
|
||||
$ref: "#/components/responses/TooManyRequests"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
delete:
|
||||
operationId: deleteBotSessionAsSuperAdmin
|
||||
tags:
|
||||
- SuperAdminBotService
|
||||
summary: Soft-delete a chatbot session (super-admin)
|
||||
description: >-
|
||||
Sets is_deleted=true on the session. Any in-flight turns on the
|
||||
session transition to status='session_deleted' so the M4 AddTurn
|
||||
tx2 callback finds a terminal row.
|
||||
security:
|
||||
- jwtAuth: []
|
||||
parameters:
|
||||
- name: clientId
|
||||
in: query
|
||||
required: true
|
||||
description: The client that owns the session.
|
||||
schema:
|
||||
type: string
|
||||
maxLength: 255
|
||||
responses:
|
||||
"204":
|
||||
description: Session soft-deleted.
|
||||
headers:
|
||||
RateLimit:
|
||||
$ref: "#/components/headers/RateLimit"
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/Forbidden"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"429":
|
||||
$ref: "#/components/responses/TooManyRequests"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
components:
|
||||
parameters:
|
||||
ClientID:
|
||||
@@ -3311,6 +3811,35 @@ components:
|
||||
maxLength: 36
|
||||
description: The UI setting ID.
|
||||
|
||||
BotClientID:
|
||||
in: path
|
||||
name: clientId
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
maxLength: 255
|
||||
description: The owning client ID for chatbot routes.
|
||||
|
||||
BotSessionID:
|
||||
in: path
|
||||
name: sessionId
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
maxLength: 36
|
||||
description: The chatbot session ID.
|
||||
|
||||
M5DocumentID:
|
||||
in: path
|
||||
name: documentId
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
maxLength: 36
|
||||
description: The document ID for the M5 schema/all-metadata routes.
|
||||
|
||||
headers:
|
||||
RateLimit:
|
||||
schema:
|
||||
@@ -6373,3 +6902,379 @@ components:
|
||||
type: string
|
||||
maxLength: 1024
|
||||
description: Full S3 path (s3://bucket/key) of the orphaned source file
|
||||
|
||||
# ---------- Bot (chatbot) M2 schemas ----------
|
||||
|
||||
BotSessionScope:
|
||||
description: |
|
||||
The persisted document/folder scope of a chatbot session.
|
||||
Empty arrays mean "all documents for the client" per plan §4.
|
||||
Folder ids are returned as-is; folder expansion to documents
|
||||
happens only in the M3 FastAPI payload assembly path, not here.
|
||||
type: object
|
||||
required:
|
||||
- documentIds
|
||||
- folderIds
|
||||
properties:
|
||||
documentIds:
|
||||
type: array
|
||||
maxItems: 10000
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
maxLength: 36
|
||||
description: Document ids in the session scope.
|
||||
folderIds:
|
||||
type: array
|
||||
maxItems: 10000
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
maxLength: 36
|
||||
description: Folder ids in the session scope.
|
||||
|
||||
BotTurnPreview:
|
||||
description: |
|
||||
A single turn surfaced inside a session list response. M2 returns
|
||||
only the columns the UI needs to render preview cards: ordinal,
|
||||
prompt, optional completion, status, createdAt. Plan §5
|
||||
ListLastTurnsForSessions returns the full row column set; the
|
||||
response trims it to the preview view here.
|
||||
type: object
|
||||
required:
|
||||
- ordinal
|
||||
- prompt
|
||||
- status
|
||||
- createdAt
|
||||
properties:
|
||||
ordinal:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 1
|
||||
maximum: 2147483647
|
||||
description: 1-based turn ordinal within the session.
|
||||
prompt:
|
||||
type: string
|
||||
maxLength: 65536
|
||||
description: User prompt text.
|
||||
completion:
|
||||
type: string
|
||||
maxLength: 65536
|
||||
nullable: true
|
||||
description: Assistant completion (markdown) when status=completed.
|
||||
status:
|
||||
type: string
|
||||
enum:
|
||||
- in_flight
|
||||
- completed
|
||||
- errored
|
||||
- abandoned
|
||||
- session_deleted
|
||||
description: Turn status per plan §4.
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
maxLength: 50
|
||||
description: When the turn was inserted.
|
||||
|
||||
BotSessionResponse:
|
||||
description: |
|
||||
The canonical chatbot session entity. Used as the response body
|
||||
for create / get / patch and as the element type of the list
|
||||
response. lastTurn is the derived last_terminal_ordinal from
|
||||
plan §4 — never the in-flight ordinal.
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- clientId
|
||||
- createdBy
|
||||
- title
|
||||
- state
|
||||
- lastTurn
|
||||
- createdAt
|
||||
- updatedAt
|
||||
- scope
|
||||
- recentTurns
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
maxLength: 36
|
||||
clientId:
|
||||
type: string
|
||||
maxLength: 255
|
||||
createdBy:
|
||||
type: string
|
||||
maxLength: 255
|
||||
description: Cognito subject (JWT sub) of the creator.
|
||||
title:
|
||||
type: string
|
||||
maxLength: 255
|
||||
description: Empty until the first turn arrives (plan §6).
|
||||
state:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
maxProperties: 1024
|
||||
description: Session state object persisted as jsonb.
|
||||
lastTurn:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 0
|
||||
maximum: 2147483647
|
||||
description: |
|
||||
Derived last_terminal_ordinal per plan §4. 0 when the session
|
||||
has no terminal turns yet.
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
maxLength: 50
|
||||
updatedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
maxLength: 50
|
||||
scope:
|
||||
$ref: "#/components/schemas/BotSessionScope"
|
||||
recentTurns:
|
||||
type: array
|
||||
maxItems: 5
|
||||
description: |
|
||||
Most recent terminal turns. Populated by the list endpoint
|
||||
with min(request.limit, cfg.RecentTurns) entries per plan §3.
|
||||
Single-session reads (GET / POST / PATCH) emit an empty array.
|
||||
items:
|
||||
$ref: "#/components/schemas/BotTurnPreview"
|
||||
|
||||
BotSessionListResponse:
|
||||
description: Paged list of chatbot sessions.
|
||||
type: object
|
||||
required:
|
||||
- sessions
|
||||
properties:
|
||||
sessions:
|
||||
type: array
|
||||
maxItems: 200
|
||||
items:
|
||||
$ref: "#/components/schemas/BotSessionResponse"
|
||||
|
||||
CreateBotSessionRequest:
|
||||
description: |
|
||||
Empty body for now — accepted as JSON object to leave room for
|
||||
future fields (title hint, initial scope) without a breaking
|
||||
change. M2 ignores any properties the caller supplies.
|
||||
type: object
|
||||
additionalProperties: true
|
||||
maxProperties: 32
|
||||
|
||||
BotSessionScopePatchRequest:
|
||||
description: |
|
||||
Add/remove sets for documents and folders. Each array is
|
||||
deduplicated server-side. An id appearing in both add and remove
|
||||
sets is rejected with 400 add_remove_conflict. Cross-client ids
|
||||
are rejected with 400 document_cross_client / folder_cross_client.
|
||||
type: object
|
||||
properties:
|
||||
addDocuments:
|
||||
type: array
|
||||
maxItems: 10000
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
maxLength: 36
|
||||
removeDocuments:
|
||||
type: array
|
||||
maxItems: 10000
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
maxLength: 36
|
||||
addFolders:
|
||||
type: array
|
||||
maxItems: 10000
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
maxLength: 36
|
||||
removeFolders:
|
||||
type: array
|
||||
maxItems: 10000
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
maxLength: 36
|
||||
|
||||
# ---------- M4: bot turn schemas ----------
|
||||
|
||||
CreateBotTurnRequest:
|
||||
description: |
|
||||
Body for POST /client/{clientId}/bot/sessions/{sessionId}/turns.
|
||||
The handler computes the target ordinal from session state via
|
||||
prompt-match semantics (a retry of an existing terminal-failure
|
||||
or completed turn reuses that row's ordinal). The wire body
|
||||
therefore carries only the prompt; plan §6.
|
||||
type: object
|
||||
required:
|
||||
- prompt
|
||||
properties:
|
||||
prompt:
|
||||
type: string
|
||||
maxLength: 65536
|
||||
description: User prompt. Plan §6 mandates 1 <= rune count <= MaxTurnChars.
|
||||
|
||||
BotTurnResponse:
|
||||
description: |
|
||||
One persisted bot_turns row exposed on the wire. Status enum
|
||||
mirrors the bot_turns_status_values CHECK constraint from
|
||||
migration 131. error is the persisted JSON when status is
|
||||
errored / abandoned / session_deleted, omitted otherwise.
|
||||
type: object
|
||||
required:
|
||||
- ordinal
|
||||
- prompt
|
||||
- status
|
||||
- createdAt
|
||||
properties:
|
||||
ordinal:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 1
|
||||
maximum: 2147483647
|
||||
prompt:
|
||||
type: string
|
||||
maxLength: 65536
|
||||
completion:
|
||||
type: string
|
||||
maxLength: 65536
|
||||
status:
|
||||
type: string
|
||||
enum:
|
||||
- completed
|
||||
- errored
|
||||
- abandoned
|
||||
- session_deleted
|
||||
- in_flight
|
||||
latencyMs:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 0
|
||||
maximum: 2147483647
|
||||
tokensIn:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 0
|
||||
maximum: 2147483647
|
||||
tokensOut:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 0
|
||||
maximum: 2147483647
|
||||
error:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
maxProperties: 32
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
maxLength: 50
|
||||
|
||||
BotTurnListResponse:
|
||||
description: |
|
||||
GET turns response. Turns are ordered ASC by ordinal.
|
||||
type: object
|
||||
required:
|
||||
- turns
|
||||
properties:
|
||||
turns:
|
||||
type: array
|
||||
maxItems: 10000
|
||||
items:
|
||||
$ref: "#/components/schemas/BotTurnResponse"
|
||||
|
||||
# ---------- M5: read-only document endpoints ----------
|
||||
|
||||
DocumentSchemaResponse:
|
||||
description: |
|
||||
Body returned by GET /client/{clientId}/documents/{documentId}/schema.
|
||||
schema is the JSON Schema body bound to the document, or null
|
||||
when the document has no custom_schema_id binding. The
|
||||
clientId / documentId echo the URL parameters so the caller can
|
||||
reuse the response without parsing the path.
|
||||
type: object
|
||||
required:
|
||||
- documentId
|
||||
- clientId
|
||||
properties:
|
||||
documentId:
|
||||
type: string
|
||||
format: uuid
|
||||
maxLength: 36
|
||||
clientId:
|
||||
type: string
|
||||
maxLength: 255
|
||||
schema:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
maxProperties: 1024
|
||||
description: |
|
||||
JSON Schema body, or null when the document has no schema
|
||||
bound. The body round-trips verbatim from
|
||||
client_metadata_schemas.schema_def.
|
||||
|
||||
DocumentAllMetadataResponse:
|
||||
description: |
|
||||
Bundle returned by GET /client/{clientId}/documents/{documentId}/all-metadata.
|
||||
document is the M1 enriched-document shape; labels is always a
|
||||
non-null array (empty when no labels are applied); customMetadata
|
||||
is null when no schema is bound or no metadata rows exist.
|
||||
type: object
|
||||
required:
|
||||
- document
|
||||
- labels
|
||||
properties:
|
||||
document:
|
||||
$ref: "#/components/schemas/DocumentEnriched"
|
||||
labels:
|
||||
type: array
|
||||
maxItems: 10000
|
||||
items:
|
||||
$ref: "#/components/schemas/BotLabelRecord"
|
||||
customMetadata:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
maxProperties: 1024
|
||||
description: |
|
||||
Latest custom metadata payload for the document, or null
|
||||
when no schema is bound / no metadata rows exist.
|
||||
|
||||
BotLabelRecord:
|
||||
description: |
|
||||
Label record exposed by the M5 all-metadata endpoint. Mirrors
|
||||
LabelRecord but treats appliedBy as a plain string so the
|
||||
bundle survives non-email AppliedBy values (the underlying
|
||||
documentLabels.appliedBy is varchar(255), not email-validated
|
||||
at the database layer).
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- documentId
|
||||
- label
|
||||
- appliedBy
|
||||
- appliedAt
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
maxLength: 36
|
||||
documentId:
|
||||
type: string
|
||||
format: uuid
|
||||
maxLength: 36
|
||||
label:
|
||||
type: string
|
||||
maxLength: 255
|
||||
appliedBy:
|
||||
type: string
|
||||
maxLength: 320
|
||||
appliedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
maxLength: 50
|
||||
|
||||
Reference in New Issue
Block a user