Skip to content

Commit f8b7021

Browse files
committed
docs(spec,client): regenerate the protocol reference and document the new ai methods
`check:docs` regenerates `content/docs/references` from the schemas and fails when the committed copy drifts. The seven new AI schemas produce new reference entries, so that check went red on the first push — the artifact half of the same commit, not a separate defect. Also updates the hand-written SDK doc, which enumerates the whole `client.ai.*` surface and carried the #3718 history note. Leaving it at ten methods while shipping seventeen would be the exact drift this line of work keeps closing — and the docs-drift check flagged `content/docs/api/client-sdk.mdx` as affected, which on inspection it genuinely was (the other 107 files it lists are package-level fan-out, unrelated to this diff). The added block documents the two things a caller gets wrong by default: an access-filtered agent catalog is legitimately EMPTY for a seat-less user, and `pendingActions.approve` returns `{ status: 'failed' }` on HTTP 200 when the tool fails after approval — reading only `res.ok` calls that a success. check:docs / check:api-surface / check:spec-changes / check:upgrade-guide all pass; 250 generated files in sync. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WJX6GnuNix7HisBc92THMN
1 parent 8cf6f83 commit f8b7021

2 files changed

Lines changed: 165 additions & 3 deletions

File tree

content/docs/api/client-sdk.mdx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,28 @@ await client.ai.conversations.addMessage(conv.id, { role: 'user', content: 'hi'
337337
await client.ai.conversations.update(conv.id, { title: 'Renamed' });
338338
await client.ai.conversations.delete(conv.id);
339339

340+
// Named agents — `ai.chat` talks to the environment default; these talk to one
341+
// you name. The catalog is access-filtered server-side (ADR-0049), so an empty
342+
// list is a legitimate answer for a seat-less user, not an error to retry.
343+
const agents = await client.ai.agents.list();
344+
await client.ai.agents.chat('build', { messages, context: { appId: 'crm' } });
345+
for await (const frame of await client.ai.agents.chatStream('build', { messages })) {
346+
if (frame.type === 'text-delta') process.stdout.write(frame.delta as string);
347+
}
348+
349+
// Pending actions — the human-in-the-loop queue. A tool call needing a human
350+
// decision parks here instead of executing.
351+
await client.ai.pendingActions.list({ status: 'pending', limit: 20 });
352+
await client.ai.pendingActions.get('pa_1');
353+
const outcome = await client.ai.pendingActions.approve('pa_1');
354+
// CHECK `outcome.status`: approve runs the tool, and a tool that fails comes
355+
// back { status: 'failed', error } on HTTP 200 — the approval succeeded, the
356+
// execution did not. Code that reads only `res.ok` calls that a success.
357+
if (outcome.status === 'failed') console.error(outcome.error);
358+
await client.ai.pendingActions.reject('pa_1', 'wrong account');
359+
// Listing takes `ai:read`, deciding takes `ai:approve` — a caller that can see
360+
// the queue may still be refused on approve. Handle the 403.
361+
340362
// In a React chat UI prefer `useChat()` (`@ai-sdk/react`) over `ai.chatStream`:
341363
// it speaks the same protocol and owns message state. These methods are for
342364
// everything that is not a component — server code, jobs, CLIs, tests.

content/docs/references/api/protocol.mdx

Lines changed: 143 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,65 @@ validation. Each entry is a canonical `ActionDescriptorSchema`.
2020
## TypeScript Usage
2121

2222
```typescript
23-
import { AiChatRequest, AiChatResponse, AiCompleteRequest, AiConversation, AiMessage, AiModelsResponse, AiStreamChunk, AutomationActionsResponse, AutomationTriggerRequest, AutomationTriggerResponse, BatchDataRequest, BatchDataResponse, CheckPermissionRequest, CheckPermissionResponse, CreateAiConversationRequest, CreateDataRequest, CreateDataResponse, CreateManyDataRequest, CreateManyDataResponse, CreateViewRequest, CreateViewResponse, DeleteDataRequest, DeleteDataResponse, DeleteManyDataRequest, DeleteManyDataResponse, DeleteMetaItemRequest, DeleteMetaItemResponse, DeleteViewRequest, DeleteViewResponse, FindDataRequest, FindDataResponse, GetDataRequest, GetDataResponse, GetDiscoveryRequest, GetDiscoveryResponse, GetEffectivePermissionsRequest, GetEffectivePermissionsResponse, GetFieldLabelsRequest, GetFieldLabelsResponse, GetLocalesRequest, GetLocalesResponse, GetMetaItemCachedRequest, GetMetaItemCachedResponse, GetMetaItemRequest, GetMetaItemResponse, GetMetaItemsRequest, GetMetaItemsResponse, GetMetaTypesRequest, GetMetaTypesResponse, GetNotificationPreferencesRequest, GetNotificationPreferencesResponse, GetObjectPermissionsRequest, GetObjectPermissionsResponse, GetPresenceRequest, GetPresenceResponse, GetTranslationsRequest, GetTranslationsResponse, GetUiViewRequest, GetUiViewResponse, GetViewRequest, GetViewResponse, GetWorkflowConfigRequest, GetWorkflowConfigResponse, GetWorkflowStateRequest, GetWorkflowStateResponse, HttpFindQueryParams, ListAiConversationsRequest, ListAiConversationsResponse, ListNotificationsRequest, ListNotificationsResponse, ListViewsRequest, ListViewsResponse, MarkAllNotificationsReadRequest, MarkAllNotificationsReadResponse, MarkNotificationsReadRequest, MarkNotificationsReadResponse, NotificationPreferences, RealtimeConnectRequest, RealtimeConnectResponse, RealtimeDisconnectRequest, RealtimeDisconnectResponse, RealtimeSubscribeRequest, RealtimeSubscribeResponse, RealtimeUnsubscribeRequest, RealtimeUnsubscribeResponse, RegisterDeviceRequest, RegisterDeviceResponse, SaveMetaItemRequest, SaveMetaItemResponse, SetPresenceRequest, SetPresenceResponse, UnregisterDeviceRequest, UnregisterDeviceResponse, UpdateAiConversationRequest, UpdateDataRequest, UpdateDataResponse, UpdateManyDataRequest, UpdateManyDataResponse, UpdateNotificationPreferencesRequest, UpdateNotificationPreferencesResponse, UpdateViewRequest, UpdateViewResponse, WorkflowState, WorkflowTransitionRequest, WorkflowTransitionResponse } from '@objectstack/spec/api';
24-
import type { AiChatRequest, AiChatResponse, AiCompleteRequest, AiConversation, AiMessage, AiModelsResponse, AiStreamChunk, AutomationActionsResponse, AutomationTriggerRequest, AutomationTriggerResponse, BatchDataRequest, BatchDataResponse, CheckPermissionRequest, CheckPermissionResponse, CreateAiConversationRequest, CreateDataRequest, CreateDataResponse, CreateManyDataRequest, CreateManyDataResponse, CreateViewRequest, CreateViewResponse, DeleteDataRequest, DeleteDataResponse, DeleteManyDataRequest, DeleteManyDataResponse, DeleteMetaItemRequest, DeleteMetaItemResponse, DeleteViewRequest, DeleteViewResponse, FindDataRequest, FindDataResponse, GetDataRequest, GetDataResponse, GetDiscoveryRequest, GetDiscoveryResponse, GetEffectivePermissionsRequest, GetEffectivePermissionsResponse, GetFieldLabelsRequest, GetFieldLabelsResponse, GetLocalesRequest, GetLocalesResponse, GetMetaItemCachedRequest, GetMetaItemCachedResponse, GetMetaItemRequest, GetMetaItemResponse, GetMetaItemsRequest, GetMetaItemsResponse, GetMetaTypesRequest, GetMetaTypesResponse, GetNotificationPreferencesRequest, GetNotificationPreferencesResponse, GetObjectPermissionsRequest, GetObjectPermissionsResponse, GetPresenceRequest, GetPresenceResponse, GetTranslationsRequest, GetTranslationsResponse, GetUiViewRequest, GetUiViewResponse, GetViewRequest, GetViewResponse, GetWorkflowConfigRequest, GetWorkflowConfigResponse, GetWorkflowStateRequest, GetWorkflowStateResponse, HttpFindQueryParams, ListAiConversationsRequest, ListAiConversationsResponse, ListNotificationsRequest, ListNotificationsResponse, ListViewsRequest, ListViewsResponse, MarkAllNotificationsReadRequest, MarkAllNotificationsReadResponse, MarkNotificationsReadRequest, MarkNotificationsReadResponse, NotificationPreferences, RealtimeConnectRequest, RealtimeConnectResponse, RealtimeDisconnectRequest, RealtimeDisconnectResponse, RealtimeSubscribeRequest, RealtimeSubscribeResponse, RealtimeUnsubscribeRequest, RealtimeUnsubscribeResponse, RegisterDeviceRequest, RegisterDeviceResponse, SaveMetaItemRequest, SaveMetaItemResponse, SetPresenceRequest, SetPresenceResponse, UnregisterDeviceRequest, UnregisterDeviceResponse, UpdateAiConversationRequest, UpdateDataRequest, UpdateDataResponse, UpdateManyDataRequest, UpdateManyDataResponse, UpdateNotificationPreferencesRequest, UpdateNotificationPreferencesResponse, UpdateViewRequest, UpdateViewResponse, WorkflowState, WorkflowTransitionRequest, WorkflowTransitionResponse } from '@objectstack/spec/api';
23+
import { AiAgentCapabilities, AiAgentChatRequest, AiAgentSummary, AiAgentsResponse, AiChatRequest, AiChatResponse, AiCompleteRequest, AiConversation, AiMessage, AiModelsResponse, AiPendingAction, AiPendingActionStatus, AiStreamChunk, ApproveAiPendingActionResponse, AutomationActionsResponse, AutomationTriggerRequest, AutomationTriggerResponse, BatchDataRequest, BatchDataResponse, CheckPermissionRequest, CheckPermissionResponse, CreateAiConversationRequest, CreateDataRequest, CreateDataResponse, CreateManyDataRequest, CreateManyDataResponse, CreateViewRequest, CreateViewResponse, DeleteDataRequest, DeleteDataResponse, DeleteManyDataRequest, DeleteManyDataResponse, DeleteMetaItemRequest, DeleteMetaItemResponse, DeleteViewRequest, DeleteViewResponse, FindDataRequest, FindDataResponse, GetDataRequest, GetDataResponse, GetDiscoveryRequest, GetDiscoveryResponse, GetEffectivePermissionsRequest, GetEffectivePermissionsResponse, GetFieldLabelsRequest, GetFieldLabelsResponse, GetLocalesRequest, GetLocalesResponse, GetMetaItemCachedRequest, GetMetaItemCachedResponse, GetMetaItemRequest, GetMetaItemResponse, GetMetaItemsRequest, GetMetaItemsResponse, GetMetaTypesRequest, GetMetaTypesResponse, GetNotificationPreferencesRequest, GetNotificationPreferencesResponse, GetObjectPermissionsRequest, GetObjectPermissionsResponse, GetPresenceRequest, GetPresenceResponse, GetTranslationsRequest, GetTranslationsResponse, GetUiViewRequest, GetUiViewResponse, GetViewRequest, GetViewResponse, GetWorkflowConfigRequest, GetWorkflowConfigResponse, GetWorkflowStateRequest, GetWorkflowStateResponse, HttpFindQueryParams, ListAiConversationsRequest, ListAiConversationsResponse, ListAiPendingActionsRequest, ListAiPendingActionsResponse, ListNotificationsRequest, ListNotificationsResponse, ListViewsRequest, ListViewsResponse, MarkAllNotificationsReadRequest, MarkAllNotificationsReadResponse, MarkNotificationsReadRequest, MarkNotificationsReadResponse, NotificationPreferences, RealtimeConnectRequest, RealtimeConnectResponse, RealtimeDisconnectRequest, RealtimeDisconnectResponse, RealtimeSubscribeRequest, RealtimeSubscribeResponse, RealtimeUnsubscribeRequest, RealtimeUnsubscribeResponse, RegisterDeviceRequest, RegisterDeviceResponse, RejectAiPendingActionResponse, SaveMetaItemRequest, SaveMetaItemResponse, SetPresenceRequest, SetPresenceResponse, UnregisterDeviceRequest, UnregisterDeviceResponse, UpdateAiConversationRequest, UpdateDataRequest, UpdateDataResponse, UpdateManyDataRequest, UpdateManyDataResponse, UpdateNotificationPreferencesRequest, UpdateNotificationPreferencesResponse, UpdateViewRequest, UpdateViewResponse, WorkflowState, WorkflowTransitionRequest, WorkflowTransitionResponse } from '@objectstack/spec/api';
24+
import type { AiAgentCapabilities, AiAgentChatRequest, AiAgentSummary, AiAgentsResponse, AiChatRequest, AiChatResponse, AiCompleteRequest, AiConversation, AiMessage, AiModelsResponse, AiPendingAction, AiPendingActionStatus, AiStreamChunk, ApproveAiPendingActionResponse, AutomationActionsResponse, AutomationTriggerRequest, AutomationTriggerResponse, BatchDataRequest, BatchDataResponse, CheckPermissionRequest, CheckPermissionResponse, CreateAiConversationRequest, CreateDataRequest, CreateDataResponse, CreateManyDataRequest, CreateManyDataResponse, CreateViewRequest, CreateViewResponse, DeleteDataRequest, DeleteDataResponse, DeleteManyDataRequest, DeleteManyDataResponse, DeleteMetaItemRequest, DeleteMetaItemResponse, DeleteViewRequest, DeleteViewResponse, FindDataRequest, FindDataResponse, GetDataRequest, GetDataResponse, GetDiscoveryRequest, GetDiscoveryResponse, GetEffectivePermissionsRequest, GetEffectivePermissionsResponse, GetFieldLabelsRequest, GetFieldLabelsResponse, GetLocalesRequest, GetLocalesResponse, GetMetaItemCachedRequest, GetMetaItemCachedResponse, GetMetaItemRequest, GetMetaItemResponse, GetMetaItemsRequest, GetMetaItemsResponse, GetMetaTypesRequest, GetMetaTypesResponse, GetNotificationPreferencesRequest, GetNotificationPreferencesResponse, GetObjectPermissionsRequest, GetObjectPermissionsResponse, GetPresenceRequest, GetPresenceResponse, GetTranslationsRequest, GetTranslationsResponse, GetUiViewRequest, GetUiViewResponse, GetViewRequest, GetViewResponse, GetWorkflowConfigRequest, GetWorkflowConfigResponse, GetWorkflowStateRequest, GetWorkflowStateResponse, HttpFindQueryParams, ListAiConversationsRequest, ListAiConversationsResponse, ListAiPendingActionsRequest, ListAiPendingActionsResponse, ListNotificationsRequest, ListNotificationsResponse, ListViewsRequest, ListViewsResponse, MarkAllNotificationsReadRequest, MarkAllNotificationsReadResponse, MarkNotificationsReadRequest, MarkNotificationsReadResponse, NotificationPreferences, RealtimeConnectRequest, RealtimeConnectResponse, RealtimeDisconnectRequest, RealtimeDisconnectResponse, RealtimeSubscribeRequest, RealtimeSubscribeResponse, RealtimeUnsubscribeRequest, RealtimeUnsubscribeResponse, RegisterDeviceRequest, RegisterDeviceResponse, RejectAiPendingActionResponse, SaveMetaItemRequest, SaveMetaItemResponse, SetPresenceRequest, SetPresenceResponse, UnregisterDeviceRequest, UnregisterDeviceResponse, UpdateAiConversationRequest, UpdateDataRequest, UpdateDataResponse, UpdateManyDataRequest, UpdateManyDataResponse, UpdateNotificationPreferencesRequest, UpdateNotificationPreferencesResponse, UpdateViewRequest, UpdateViewResponse, WorkflowState, WorkflowTransitionRequest, WorkflowTransitionResponse } from '@objectstack/spec/api';
2525

2626
// Validate data
27-
const result = AiChatRequest.parse(data);
27+
const result = AiAgentCapabilities.parse(data);
2828
```
2929

30+
---
31+
32+
## AiAgentCapabilities
33+
34+
### Properties
35+
36+
| Property | Type | Required | Description |
37+
| :--- | :--- | :--- | :--- |
38+
| **authoring** | `boolean` || Authors app metadata (objects/views/flows) |
39+
| **canvas** | `boolean` || Drives the Live Canvas split view (ADR-0037) |
40+
| **debug** | `boolean` || Exposes the build-doctor debug drawer |
41+
| **resume** | `boolean` || Turns resume durable multi-step runs (ADR-0013) |
42+
43+
44+
---
45+
46+
## AiAgentChatRequest
47+
48+
### Properties
49+
50+
| Property | Type | Required | Description |
51+
| :--- | :--- | :--- | :--- |
52+
| **messages** | `Record<string, any>[]` || Conversation messages (at least one) |
53+
| **context** | `Record<string, any>` | optional | Agent context (app, object, record, …) |
54+
| **options** | `Record<string, any>` | optional | Request options (model, temperature, …) |
55+
56+
57+
---
58+
59+
## AiAgentSummary
60+
61+
### Properties
62+
63+
| Property | Type | Required | Description |
64+
| :--- | :--- | :--- | :--- |
65+
| **name** | `string` || Agent name — the `:agentName` path segment |
66+
| **label** | `string` || Display label |
67+
| **role** | `string` || Agent role |
68+
| **capabilities** | `{ authoring: boolean; canvas: boolean; debug: boolean; resume: boolean }` || Capability set implied by the agent surface |
69+
70+
71+
---
72+
73+
## AiAgentsResponse
74+
75+
### Properties
76+
77+
| Property | Type | Required | Description |
78+
| :--- | :--- | :--- | :--- |
79+
| **agents** | `{ name: string; label: string; role: string; capabilities: object }[]` || Agents this caller may chat with |
80+
81+
3082
---
3183

3284
## AiChatRequest
@@ -116,6 +168,44 @@ const result = AiChatRequest.parse(data);
116168
| **defaultModel** | `string` | optional | Default model id, when the service reports one |
117169

118170

171+
---
172+
173+
## AiPendingAction
174+
175+
### Properties
176+
177+
| Property | Type | Required | Description |
178+
| :--- | :--- | :--- | :--- |
179+
| **id** | `string` || Pending action id |
180+
| **object_name** | `string` || Object the action targets |
181+
| **action_name** | `string` || Action name |
182+
| **tool_name** | `string` || Tool that would execute it |
183+
| **tool_input** | `string` || Serialized tool input |
184+
| **status** | `Enum<'pending' \| 'approved' \| 'executed' \| 'failed' \| 'rejected'>` || Lifecycle status |
185+
| **result** | `string` | optional | Serialized result, once executed |
186+
| **error** | `string` | optional | Failure message, when status is failed |
187+
| **rejection_reason** | `string` | optional | Reason given at rejection |
188+
| **conversation_id** | `string` | optional | Conversation that proposed it |
189+
| **message_id** | `string` | optional | Message that proposed it |
190+
| **proposed_by** | `string` | optional | Actor that proposed it |
191+
| **decided_by** | `string` | optional | Actor that approved or rejected it |
192+
| **proposed_at** | `string` || Proposal timestamp (ISO 8601) |
193+
| **decided_at** | `string` | optional | Decision timestamp (ISO 8601) |
194+
195+
196+
---
197+
198+
## AiPendingActionStatus
199+
200+
### Allowed Values
201+
202+
* `pending`
203+
* `approved`
204+
* `executed`
205+
* `failed`
206+
* `rejected`
207+
208+
119209
---
120210

121211
## AiStreamChunk
@@ -127,6 +217,19 @@ const result = AiChatRequest.parse(data);
127217
| **type** | `string` || Frame type (text-delta, tool-input-available, finish, error, …) |
128218

129219

220+
---
221+
222+
## ApproveAiPendingActionResponse
223+
224+
### Properties
225+
226+
| Property | Type | Required | Description |
227+
| :--- | :--- | :--- | :--- |
228+
| **status** | `Enum<'executed' \| 'failed'>` || Outcome of executing the approved action |
229+
| **result** | `any` | optional | Tool result, when executed |
230+
| **error** | `string` | optional | Failure reason, when failed |
231+
232+
130233
---
131234

132235
## AutomationActionsResponse
@@ -913,6 +1016,31 @@ const result = AiChatRequest.parse(data);
9131016
| **conversations** | `{ id: string; title?: string; agentId?: string; userId?: string; … }[]` || Matching conversations |
9141017

9151018

1019+
---
1020+
1021+
## ListAiPendingActionsRequest
1022+
1023+
### Properties
1024+
1025+
| Property | Type | Required | Description |
1026+
| :--- | :--- | :--- | :--- |
1027+
| **status** | `Enum<'pending' \| 'approved' \| 'executed' \| 'failed' \| 'rejected'>` | optional | Filter by status |
1028+
| **conversationId** | `string` | optional | Filter by proposing conversation |
1029+
| **limit** | `integer` | optional | Max rows (server default 100) |
1030+
1031+
1032+
---
1033+
1034+
## ListAiPendingActionsResponse
1035+
1036+
### Properties
1037+
1038+
| Property | Type | Required | Description |
1039+
| :--- | :--- | :--- | :--- |
1040+
| **items** | `{ id: string; object_name: string; action_name: string; tool_name: string; … }[]` || Queued actions, newest first |
1041+
| **total** | `number` || Number of rows returned (not a total across pages) |
1042+
1043+
9161044
---
9171045

9181046
## ListNotificationsRequest
@@ -1145,6 +1273,18 @@ const result = AiChatRequest.parse(data);
11451273
| **success** | `boolean` || Whether registration succeeded |
11461274

11471275

1276+
---
1277+
1278+
## RejectAiPendingActionResponse
1279+
1280+
### Properties
1281+
1282+
| Property | Type | Required | Description |
1283+
| :--- | :--- | :--- | :--- |
1284+
| **status** | `'rejected'` || Always "rejected" |
1285+
| **id** | `string` || The rejected action id |
1286+
1287+
11481288
---
11491289

11501290
## SaveMetaItemRequest

0 commit comments

Comments
 (0)