diff --git a/docs/openapi-tess.yaml b/docs/openapi-tess.yaml index f170a33..29616d8 100644 --- a/docs/openapi-tess.yaml +++ b/docs/openapi-tess.yaml @@ -1,5 +1,6 @@ openapi: 3.1.0 info: { title: Mosaic Tess Gateway, version: 1.0.0 } +security: [{ sessionAuth: [] }] paths: /api/interaction/{agentName}/sessions: { @@ -12,19 +13,14 @@ paths: { $ref: '#/components/parameters/provider' }, { $ref: '#/components/parameters/correlation' }, ], - responses: - { - '200': { description: Sessions }, - '401': { description: Auth required }, - '403': { description: Scope denied }, - }, + responses: { '200': { description: Sessions } }, }, } /api/interaction/{agentName}/transitional-capabilities: { get: { - summary: Transitional capability matrix, + summary: Get transitional capability matrix, parameters: [ { $ref: '#/components/parameters/agentName' }, @@ -38,7 +34,7 @@ paths: { get: { - summary: Authorized session tree, + summary: Get authorized session tree, parameters: [ { $ref: '#/components/parameters/agentName' }, @@ -48,79 +44,259 @@ paths: responses: { '200': { description: Tree } }, }, } - /api/interaction/{agentName}/sessions/{sessionId}/{operation}: + /api/interaction/{agentName}/sessions/{sessionId}/enroll: { post: { - summary: Enroll, - attach, - send, - stop, - or recover a durable session, + summary: Enroll a durable session, parameters: [ { $ref: '#/components/parameters/agentName' }, { $ref: '#/components/parameters/sessionId' }, - { - name: operation, - in: path, - required: true, - schema: { enum: [enroll, attach, send, stop, recover] }, - }, { $ref: '#/components/parameters/correlation' }, ], - requestBody: - { required: false, content: { application/json: { schema: { type: object } } } }, - responses: - { - '200': { description: Operation result }, - '403': { description: Scope or approval denied }, - }, + requestBody: { $ref: '#/components/requestBodies/Enroll' }, + responses: { '200': { description: Enrolled } }, }, } - /api/coord/mos/handoff: + /api/interaction/{agentName}/sessions/{sessionId}/attach: { post: { - summary: Submit a Mos handoff, - parameters: [{ $ref: '#/components/parameters/correlation' }], - responses: { '200': { description: Receipt } }, + summary: Attach to a runtime session, + parameters: + [ + { $ref: '#/components/parameters/agentName' }, + { $ref: '#/components/parameters/sessionId' }, + { $ref: '#/components/parameters/correlation' }, + ], + requestBody: { $ref: '#/components/requestBodies/Attach' }, + responses: { '200': { description: Attachment } }, }, } - /api/coord/mos/{handoffId}/observe: + /api/interaction/{agentName}/sessions/{sessionId}/send: + { + post: + { + summary: Queue a durable provider send, + parameters: + [ + { $ref: '#/components/parameters/agentName' }, + { $ref: '#/components/parameters/sessionId' }, + { $ref: '#/components/parameters/correlation' }, + ], + requestBody: { $ref: '#/components/requestBodies/Send' }, + responses: { '200': { description: Queued } }, + }, + } + /api/interaction/{agentName}/sessions/{sessionId}/stop: + { + post: + { + summary: Stop a session with approval, + parameters: + [ + { $ref: '#/components/parameters/agentName' }, + { $ref: '#/components/parameters/sessionId' }, + { $ref: '#/components/parameters/correlation' }, + ], + requestBody: { $ref: '#/components/requestBodies/Stop' }, + responses: { '200': { description: Stopped }, '403': { description: Approval denied } }, + }, + } + /api/interaction/{agentName}/sessions/{sessionId}/recover: + { + post: + { + summary: Recover interrupted durable work, + parameters: + [ + { $ref: '#/components/parameters/agentName' }, + { $ref: '#/components/parameters/sessionId' }, + { $ref: '#/components/parameters/correlation' }, + ], + responses: { '200': { description: Recovered } }, + }, + } + /api/memory/preferences: + { + get: { summary: List preferences, responses: { '200': { description: Preferences } } }, + post: + { + summary: Upsert preference, + requestBody: { $ref: '#/components/requestBodies/Preference' }, + responses: { '200': { description: Preference } }, + }, + } + /api/memory/preferences/{key}: { get: { - summary: Observe a handoff, - parameters: - [ - { $ref: '#/components/parameters/handoffId' }, - { $ref: '#/components/parameters/correlation' }, - ], - responses: { '200': { description: Observation } }, + summary: Get preference, + parameters: [{ $ref: '#/components/parameters/key' }], + responses: { '200': { description: Preference } }, + }, + delete: + { + summary: Delete preference, + parameters: [{ $ref: '#/components/parameters/key' }], + responses: { '204': { description: Deleted } }, }, } - /api/coord/mos/{handoffId}/result: + /api/memory/insights: + { + get: { summary: List insights, responses: { '200': { description: Insights } } }, + post: + { + summary: Create insight, + requestBody: { $ref: '#/components/requestBodies/Insight' }, + responses: { '200': { description: Insight } }, + }, + } + /api/memory/insights/{id}: { get: { - summary: Get a handoff result, - parameters: - [ - { $ref: '#/components/parameters/handoffId' }, - { $ref: '#/components/parameters/correlation' }, - ], - responses: { '200': { description: Result } }, + summary: Get insight, + parameters: [{ $ref: '#/components/parameters/id' }], + responses: { '200': { description: Insight } }, + }, + delete: + { + summary: Delete insight, + parameters: [{ $ref: '#/components/parameters/id' }], + responses: { '204': { description: Deleted } }, }, } /api/memory/search: - { post: { summary: Search scoped memory, responses: { '200': { description: Results } } } } + { + post: + { + summary: Search memory, + requestBody: { $ref: '#/components/requestBodies/Search' }, + responses: { '200': { description: Search results } }, + }, + } components: securitySchemes: { sessionAuth: { type: http, scheme: bearer } } parameters: agentName: { name: agentName, in: path, required: true, schema: { type: string } } sessionId: { name: sessionId, in: path, required: true, schema: { type: string } } - handoffId: { name: handoffId, in: path, required: true, schema: { type: string } } provider: { name: provider, in: query, required: true, schema: { type: string } } correlation: { name: X-Correlation-Id, in: header, required: true, schema: { type: string } } -security: [{ sessionAuth: [] }] + key: { name: key, in: path, required: true, schema: { type: string } } + id: { name: id, in: path, required: true, schema: { type: string } } + requestBodies: + Enroll: + { + required: true, + content: + { + application/json: + { + schema: + { + type: object, + required: [providerId, runtimeSessionId], + properties: + { providerId: { type: string }, runtimeSessionId: { type: string } }, + }, + }, + }, + } + Attach: + { + content: + { + application/json: { schema: { type: object, properties: { mode: { enum: [read] } } } }, + }, + } + Send: + { + required: true, + content: + { + application/json: + { + schema: + { + type: object, + properties: { content: { type: string }, idempotencyKey: { type: string } }, + }, + }, + }, + } + Stop: + { + required: true, + content: + { + application/json: + { schema: { type: object, properties: { approvalRef: { type: string } } } }, + }, + } + Preference: + { + required: true, + content: + { + application/json: + { + schema: + { + type: object, + required: [key, value], + properties: + { + key: { type: string }, + value: {}, + category: { type: string }, + source: { type: string }, + }, + }, + }, + }, + } + Insight: + { + required: true, + content: + { + application/json: + { + schema: + { + type: object, + required: [content, source, category], + properties: + { + content: { type: string }, + source: { type: string }, + category: { type: string }, + metadata: { type: object }, + }, + }, + }, + }, + } + Search: + { + required: true, + content: + { + application/json: + { + schema: + { + type: object, + required: [query], + properties: + { + query: { type: string }, + limit: { type: integer }, + maxDistance: { type: number }, + }, + }, + }, + }, + } diff --git a/docs/tess/ADMIN-GUIDE.md b/docs/tess/ADMIN-GUIDE.md index 2bc7b68..03b78c3 100644 --- a/docs/tess/ADMIN-GUIDE.md +++ b/docs/tess/ADMIN-GUIDE.md @@ -1,3 +1,5 @@ # Tess Administration -Provision authenticated users, configured agent identities, providers, and approved channel bindings. Never expose service credentials in status or logs. Use health/readiness and provider status endpoints for recovery diagnostics; privileged termination remains approval-bound and auditable. +Configure agent/provider identities outside client input. Verify `/health/ready` and provider health before enabling interaction clients. Every interaction request requires an authenticated actor and correlation header; tenant and owner scope are server-derived. Do not log or return service credentials. + +For an incident, preserve correlation IDs, inspect provider status and durable checkpoint/inbox/outbox state, then use the recovery endpoint. Do not retry an ambiguous external effect automatically. Stop operations require an exact one-time approval reference; provisioning or granting a broad admin capability does not replace that check. diff --git a/docs/tess/USER-GUIDE.md b/docs/tess/USER-GUIDE.md index 62f8c7d..90a85f1 100644 --- a/docs/tess/USER-GUIDE.md +++ b/docs/tess/USER-GUIDE.md @@ -1,3 +1,5 @@ # Tess User Guide -Use authenticated interaction endpoints with an `X-Correlation-Id`. List sessions, attach, send, and recover only sessions visible to your server-derived tenant scope. Stop requires a durable exact-action approval. Mos handoffs are submitted through `/api/coord/mos/handoff` and can be observed or read by receipt ID. +All HTTP interaction calls require authenticated session credentials and `X-Correlation-Id`. Use `GET /api/interaction/{agentName}/sessions?provider=...` to list only visible runtime sessions, then enroll with `POST .../sessions/{sessionId}/enroll` body `{providerId,runtimeSessionId}`. Attach uses `{mode:"read"}`; send uses `{content,idempotencyKey}`. Stop requires `{approvalRef}` and fails with 403 without the exact durable approval. Recovery only requeues interrupted durable work. + +Memory is user-scoped: preferences support list/get/upsert/delete; insights support list/get/create/delete; search body is `{query,limit?,maxDistance?}`. Mos work is handed off with `POST /api/coord/mos/handoff`; observe and result use the returned handoff ID.