Merged in feature/chatbot1 (pull request #223)

Chatbot functionality

* baseline working

* missing test file

* more tests
This commit is contained in:
Jay Brown
2026-05-07 20:56:18 +00:00
parent 17fc813823
commit 72de690894
62 changed files with 19150 additions and 445 deletions
+55 -1
View File
@@ -31,6 +31,47 @@ The API is organized into the following service groups:
| UISettingsService | Operations related to UI-scoped key-value settings (per user, client, or global) |
| SuperAdminSchemaService | Operations related to custom schema management (super_admin only) |
| CustomMetadataService | Operations related to per-document custom metadata (client_user and above) |
| BotService | Chatbot session/scope/turn endpoints plus read-only document schema and all-metadata bundles for `client_user`. See [Chatbot Guide](12-chatbot-guide.md) for the complete reference. |
| SuperAdminBotService | Super-admin chatbot session list/get/soft-delete across all users in a client. See [Chatbot Guide](12-chatbot-guide.md). |
## Chatbot Endpoints
The chatbot endpoints expose a synchronous facade over the Aaria FastAPI
agent service. Plan §3 mandates the singular `/client/...` form so the
existing Permit.io `client_user` policy applies. See
[Chatbot Guide](12-chatbot-guide.md) for the operator runbook,
configuration reference, AddTurn algorithm, and HTTP status mapping.
| Method | Path | OperationId | Auth |
| ------ | --------------------------------------------------------------------- | --------------------------------- | --------------------- |
| POST | `/client/{clientId}/bot/sessions` | `createBotSession` | client_user |
| GET | `/client/{clientId}/bot/sessions` | `listBotSessions` | client_user |
| GET | `/client/{clientId}/bot/sessions/{sessionId}` | `getBotSession` | client_user (owner) |
| PATCH | `/client/{clientId}/bot/sessions/{sessionId}/scope` | `patchBotSessionScope` | client_user (owner) |
| POST | `/client/{clientId}/bot/sessions/{sessionId}/turns` | `createBotTurn` | client_user (owner) |
| GET | `/client/{clientId}/bot/sessions/{sessionId}/turns` | `listBotTurns` | client_user (owner) |
| GET | `/client/{clientId}/documents/{documentId}/schema` | `getDocumentSchema` | client_user |
| GET | `/client/{clientId}/documents/{documentId}/all-metadata` | `getDocumentAllMetadata` | client_user |
| GET | `/super-admin/bot/sessions?clientId=...` | `listBotSessionsAsSuperAdmin` | super_admin |
| GET | `/super-admin/bot/sessions/{sessionId}?clientId=...` | `getBotSessionAsSuperAdmin` | super_admin |
| DELETE | `/super-admin/bot/sessions/{sessionId}?clientId=...` | `deleteBotSessionAsSuperAdmin` | super_admin |
`BotSessionResponse.lastTurn` is the derived `last_terminal_ordinal`
from `bot_turns` (highest ordinal whose status is not `in_flight`),
NOT the highest seen ordinal. `last_seen_ordinal` is computed but used
only internally by `AddTurn` for ordinal classification.
`DocumentSchemaResponse.schema` is omitted from the JSON wire response
when the document has no `custom_schema_id` binding (the field is
declared `omitempty`); the document still exists, only the optional
binding is absent. Plan §10 M5: HTTP 200 in this case, NOT 404.
The all-metadata endpoint emits `BotLabelRecord` (plain-string
`appliedBy`) instead of the existing `LabelRecord` (email-validated)
for the embedded labels list. Both wrap the same
`documentLabels.appliedBy varchar` column; the chatbot variant tolerates
non-email values that pre-date the email-typing convention. Long-term
cleanup is to relax `LabelRecord.AppliedBy` to plain string.
## Authentication and Authorization
@@ -148,7 +189,20 @@ RATE_LIMIT_DEFAULT_RATE=5 # req/s per IP
RATE_LIMIT_DEFAULT_BURST=10 # burst per IP
RATE_LIMIT_EXPIRES_IN=180 # seconds (3 minutes)
# Per-endpoint overrides (JSON format)
# Per-endpoint overrides (JSON format).
# Plan §10 M6 + §11: setting an override here NOW throttles the actual
# per-(IP, route) request rate (Allow() decision), not just the
# RateLimit / Retry-After response headers. Operators upgrading from
# pre-M6 deployments should review existing overrides for unintended
# tightening.
#
# Keys use Echo's path template form (`:clientId`, `:sessionId`), NOT
# the OpenAPI `{clientId}` form. The middleware uses c.Path() which
# returns Echo's registered path string.
#
# Example for the chatbot turn endpoint (illustrative — adjust before
# production rollout):
# RATE_LIMIT_ENDPOINT_OVERRIDES='{"POST /client/:clientId/bot/sessions/:sessionId/turns":{"global_rate":50,"global_burst":100,"rate":2,"burst":4}}'
RATE_LIMIT_ENDPOINT_OVERRIDES={}
```