@robota-sdk/agent-transport 3.0.0-beta.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1137 -0
- package/LICENSE +661 -0
- package/README.md +121 -0
- package/dist/browser/client.d.ts +2 -0
- package/dist/browser/client.js +1 -0
- package/dist/browser/index.d.ts +624 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +2 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/observer-messages-4fRQZU2D.d.ts +499 -0
- package/dist/browser/observer-messages-4fRQZU2D.d.ts.map +1 -0
- package/dist/browser/observer-messages-O8jTPEQO.js +2 -0
- package/dist/browser/observer-messages-O8jTPEQO.js.map +1 -0
- package/dist/node/index.cjs +1 -0
- package/dist/node/index.d.cts +1115 -0
- package/dist/node/index.d.cts.map +1 -0
- package/dist/node/index.d.ts +1115 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +2 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/node.cjs +1 -0
- package/dist/node/node.d.cts +317 -0
- package/dist/node/node.d.cts.map +1 -0
- package/dist/node/node.d.ts +317 -0
- package/dist/node/node.d.ts.map +1 -0
- package/dist/node/node.js +2 -0
- package/dist/node/node.js.map +1 -0
- package/package.json +122 -0
- package/src/__tests__/__fixtures__/korean-text.json +6 -0
- package/src/__tests__/access-token-verifier.test.ts +672 -0
- package/src/__tests__/admission.test.ts +130 -0
- package/src/__tests__/app-tool-messages.test.ts +463 -0
- package/src/__tests__/bearer-resource-gate.test.ts +120 -0
- package/src/__tests__/channel-frames.test.ts +215 -0
- package/src/__tests__/driver-attribution-capability.test.ts +83 -0
- package/src/__tests__/file-transfer.test.ts +281 -0
- package/src/__tests__/handoff-chunking.test.ts +261 -0
- package/src/__tests__/handoff-manifest.test.ts +52 -0
- package/src/__tests__/history-attached-budget.test.ts +216 -0
- package/src/__tests__/message-decoders.test.ts +870 -0
- package/src/__tests__/outbound-delivery.test.ts +558 -0
- package/src/__tests__/peer-message-ledger.test.ts +200 -0
- package/src/__tests__/permission-summary.test.ts +18 -0
- package/src/__tests__/personal-usage-report.test.ts +193 -0
- package/src/__tests__/project-read-messages.test.ts +118 -0
- package/src/__tests__/resume-buffer.test.ts +93 -0
- package/src/__tests__/session-detail-loop-status.test.ts +169 -0
- package/src/__tests__/session-directory-messages.test.ts +322 -0
- package/src/__tests__/session-error-classification.test.ts +113 -0
- package/src/__tests__/session-event-delivery.test.ts +101 -0
- package/src/__tests__/session-history-wire.test.ts +364 -0
- package/src/__tests__/session-message-handler-e5.test.ts +99 -0
- package/src/__tests__/session-message-handler-observe.test.ts +223 -0
- package/src/__tests__/session-message-handler.test.ts +726 -0
- package/src/__tests__/session-resume-bridge.test.ts +472 -0
- package/src/__tests__/settings-messages.test.ts +193 -0
- package/src/__tests__/stdio-carrier.test.ts +85 -0
- package/src/__tests__/submit-prompt-shape.test.ts +78 -0
- package/src/__tests__/usage-report-carrier.test.ts +98 -0
- package/src/__tests__/ws-broadcast-events.test.ts +94 -0
- package/src/app-tool-messages.ts +140 -0
- package/src/background-messages.ts +169 -0
- package/src/channel-frames.ts +182 -0
- package/src/client.ts +17 -0
- package/src/handoff-chunking.ts +275 -0
- package/src/index.ts +135 -0
- package/src/loop-control-messages.ts +34 -0
- package/src/message-decoders.ts +485 -0
- package/src/message-parser.ts +33 -0
- package/src/node/access-token-verifier.ts +363 -0
- package/src/node/admission.ts +153 -0
- package/src/node/bearer-resource-gate.ts +331 -0
- package/src/node/file-transfer.ts +530 -0
- package/src/node/handoff-manifest.ts +77 -0
- package/src/node/index.ts +45 -0
- package/src/node/stdio-carrier.ts +59 -0
- package/src/observer-messages.ts +47 -0
- package/src/open-prompts.ts +76 -0
- package/src/outbound-delivery.ts +240 -0
- package/src/peer-message-ledger.ts +193 -0
- package/src/permission-summary.ts +18 -0
- package/src/project-read-messages.ts +74 -0
- package/src/protocol-session.ts +56 -0
- package/src/resume-buffer.ts +123 -0
- package/src/session-directory-messages.ts +162 -0
- package/src/session-error-classification.ts +91 -0
- package/src/session-events.ts +290 -0
- package/src/session-message-handler.ts +413 -0
- package/src/session-query-messages.ts +160 -0
- package/src/session-resume-bridge.ts +275 -0
- package/src/settings-messages.ts +103 -0
- package/src/usage-messages.ts +195 -0
- package/src/wire-messages.ts +436 -0
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
IToolAppView,
|
|
3
|
+
IToolExecutionResult,
|
|
4
|
+
TToolParameters,
|
|
5
|
+
TUniversalMessagePart,
|
|
6
|
+
} from '@robota-sdk/agent-core';
|
|
7
|
+
import type {
|
|
8
|
+
IPersonalUsageReport,
|
|
9
|
+
IPersonalUsageRequest,
|
|
10
|
+
IUsageBySourceReport,
|
|
11
|
+
} from '@robota-sdk/agent-interface-analytics';
|
|
12
|
+
import type {
|
|
13
|
+
ICommandListEntry,
|
|
14
|
+
ICommandResult,
|
|
15
|
+
ICommandSkillListEntry,
|
|
16
|
+
} from '@robota-sdk/agent-interface-command';
|
|
17
|
+
import type {
|
|
18
|
+
IBackgroundJobGroupState,
|
|
19
|
+
IExecutionDetailCursor,
|
|
20
|
+
IExecutionDetailPage,
|
|
21
|
+
IExecutionWorkspaceSnapshot,
|
|
22
|
+
TBackgroundJobGroupEvent,
|
|
23
|
+
} from '@robota-sdk/agent-interface-execution';
|
|
24
|
+
import type {
|
|
25
|
+
IBackgroundTaskInput,
|
|
26
|
+
IBackgroundTaskListFilter,
|
|
27
|
+
IBackgroundTaskLogCursor,
|
|
28
|
+
IBackgroundTaskLogPage,
|
|
29
|
+
IBackgroundTaskState,
|
|
30
|
+
TBackgroundTaskEvent,
|
|
31
|
+
} from '@robota-sdk/agent-interface-execution';
|
|
32
|
+
import type {
|
|
33
|
+
IAskRequestEvent,
|
|
34
|
+
IBranchEvent,
|
|
35
|
+
ICompactEvent,
|
|
36
|
+
IExecutionResult,
|
|
37
|
+
IContextFileRefreshedEvent,
|
|
38
|
+
IModelListGroup,
|
|
39
|
+
IPermissionRequestEvent,
|
|
40
|
+
IPromptResolvedEvent,
|
|
41
|
+
IPlanApprovalEvent,
|
|
42
|
+
ISessionRenamedEvent,
|
|
43
|
+
ISettingsSnapshot,
|
|
44
|
+
IToolState,
|
|
45
|
+
ISessionListing,
|
|
46
|
+
ISessionStatusSnapshot,
|
|
47
|
+
ISessionSwitchedEvent,
|
|
48
|
+
TSessionChangeRefusalCode,
|
|
49
|
+
TSessionDeleteRefusalCode,
|
|
50
|
+
TSettingsPatch,
|
|
51
|
+
IUiIntentEvent,
|
|
52
|
+
TPermissionResultValue,
|
|
53
|
+
TProjectDiffRead,
|
|
54
|
+
TProjectMemoryRead,
|
|
55
|
+
TProjectStatusRead,
|
|
56
|
+
TWaitingLoopStopOutcome,
|
|
57
|
+
} from '@robota-sdk/agent-interface-session';
|
|
58
|
+
import type {
|
|
59
|
+
ISessionConversationRead,
|
|
60
|
+
TDriverId,
|
|
61
|
+
TTurnSource,
|
|
62
|
+
} from '@robota-sdk/agent-interface-session';
|
|
63
|
+
import type { TActionResponse } from '@robota-sdk/agent-interface-transport';
|
|
64
|
+
|
|
65
|
+
export type TBackgroundControlAction = 'cancel' | 'close' | 'send';
|
|
66
|
+
|
|
67
|
+
type THistoryEntry = ReturnType<ISessionConversationRead['getFullHistory']>[number];
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* #3282 §4: one agent the switcher can offer. `definedIn` is a plain-words location — a discovered
|
|
71
|
+
* file's path, or "Built-in" — never a raw internal id.
|
|
72
|
+
*/
|
|
73
|
+
export interface IWireAgentDefinitionSummary {
|
|
74
|
+
name: string;
|
|
75
|
+
description: string;
|
|
76
|
+
definedIn: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* #3189: one entry of the session's full history as it crosses the wire. The same record the session
|
|
81
|
+
* keeps, except that `timestamp` is an ISO 8601 string: a `Date` does not survive JSON, and a
|
|
82
|
+
* declared `Date` that arrives as a string would let a client call `Date` methods on a string.
|
|
83
|
+
*/
|
|
84
|
+
export interface IWireHistoryEntry extends Omit<THistoryEntry, 'timestamp'> {
|
|
85
|
+
/** ISO 8601. */
|
|
86
|
+
timestamp: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* #3189: a turn's result as it crosses the wire. The session's whole history stays behind: it only
|
|
91
|
+
* grows, so a client reads it in bounded pages with `get-history` instead.
|
|
92
|
+
*/
|
|
93
|
+
export type TWireExecutionResult = Omit<IExecutionResult, 'history'>;
|
|
94
|
+
|
|
95
|
+
/** Inbound message from client to server. */
|
|
96
|
+
export type TClientMessage =
|
|
97
|
+
| { type: 'submit'; prompt: string }
|
|
98
|
+
// `requestId` is echoed on the command's `command_result` or `protocol_error`, so a client with
|
|
99
|
+
// several commands in flight knows which one each answer settles.
|
|
100
|
+
| { type: 'command'; name: string; args?: string; requestId?: string }
|
|
101
|
+
| { type: 'abort' }
|
|
102
|
+
| { type: 'cancel-queue' }
|
|
103
|
+
| { type: 'get-messages' }
|
|
104
|
+
// #3189: the session's full history — what a client that renders the whole session (the TUI) shows —
|
|
105
|
+
// one bounded page at a time, from `fromIndex` (default 0). The client asks for the next page
|
|
106
|
+
// after the previous one arrived, so replies never pile up in the connection.
|
|
107
|
+
| { type: 'get-history'; fromIndex?: number }
|
|
108
|
+
// #3189: the permission and ask prompts open now, each sent again as the frame that asked it: a
|
|
109
|
+
// client that attached after a prompt was asked has not seen it.
|
|
110
|
+
| { type: 'get-prompts' }
|
|
111
|
+
| { type: 'get-context' }
|
|
112
|
+
// #3186: what every client needs beside the conversation — the commands and skills it can offer
|
|
113
|
+
// (a `/` menu), and the session's status (model, permission mode, effort, context).
|
|
114
|
+
| { type: 'get-commands' }
|
|
115
|
+
| { type: 'get-status' }
|
|
116
|
+
// #3282 §2: the models the GUI's model menu offers, grouped by configured provider profile — so
|
|
117
|
+
// the GUI never scrapes `/model`'s picker text. Choosing one sends `command` with `name: 'model'`,
|
|
118
|
+
// the SAME path `/model <id>` runs; this message only reads the choices.
|
|
119
|
+
| { type: 'list-models'; requestId: string }
|
|
120
|
+
// #3282 §4: the agent switcher's roster and its currently-selected default — so the GUI never
|
|
121
|
+
// scrapes `/agent`'s text. Choosing one sends `command` with `name: 'agent'`, the SAME path
|
|
122
|
+
// `/agent <name>` runs; this message only reads the roster and the current selection.
|
|
123
|
+
| { type: 'get-agent-definitions'; requestId: string }
|
|
124
|
+
// #3189: the host's sessions — list them, start a new one, make another current. A refused change
|
|
125
|
+
// answers `session_change_failed` with the same `requestId`.
|
|
126
|
+
| { type: 'list-sessions'; requestId: string }
|
|
127
|
+
| { type: 'new-session'; requestId?: string }
|
|
128
|
+
| { type: 'switch-session'; sessionId: string; requestId?: string }
|
|
129
|
+
// #3289 §1: rename a session from the list — current or not. Answered by `session_renamed_in_list`
|
|
130
|
+
// or `session_rename_failed`, both carrying the same `requestId`.
|
|
131
|
+
| { type: 'rename-session'; sessionId: string; name: string; requestId: string }
|
|
132
|
+
// #3289 §1: remove a stored session's record for good. Answered by `session_deleted` or
|
|
133
|
+
// `session_delete_failed`, both carrying the same `requestId`.
|
|
134
|
+
| { type: 'delete-session'; sessionId: string; requestId: string }
|
|
135
|
+
// SELFHOST-004: request the assembled trace/cost read-model (spans + cost-by-source) for the run.
|
|
136
|
+
| { type: 'get-usage-report' }
|
|
137
|
+
| {
|
|
138
|
+
type: 'get-personal-usage-report';
|
|
139
|
+
requestId: string;
|
|
140
|
+
period: IPersonalUsageRequest['period'];
|
|
141
|
+
timezone: string;
|
|
142
|
+
}
|
|
143
|
+
| { type: 'get-stored-session-usage-report'; requestId: string; sessionId: string }
|
|
144
|
+
| { type: 'get-executing' }
|
|
145
|
+
| { type: 'get-pending' }
|
|
146
|
+
| { type: 'get-execution-workspace' }
|
|
147
|
+
// One page of what a workspace entry recorded, from `cursor` (the previous page's `nextCursor`).
|
|
148
|
+
// Answered by `execution_detail` or `execution_detail_error` with the same `requestId`.
|
|
149
|
+
| {
|
|
150
|
+
type: 'read-execution-detail';
|
|
151
|
+
requestId: string;
|
|
152
|
+
entryId: string;
|
|
153
|
+
cursor?: IExecutionDetailCursor;
|
|
154
|
+
}
|
|
155
|
+
// Stop the self-paced loop that is waiting for its next wake; answered by `waiting_loop_stop`.
|
|
156
|
+
| { type: 'stop-waiting-loop'; requestId: string }
|
|
157
|
+
// #3282 §4c: the Project panel's "Changes" section — this workspace's git status. Answered by
|
|
158
|
+
// `project_status`, echoing `requestId`.
|
|
159
|
+
| { type: 'project-status'; requestId: string }
|
|
160
|
+
// The Project panel's "File diff" section for one file `project_status` reported — `path` exactly
|
|
161
|
+
// as reported (workspace-relative; the server re-checks it stays inside the workspace). Answered by
|
|
162
|
+
// `project_diff`.
|
|
163
|
+
| { type: 'project-diff'; requestId: string; path: string }
|
|
164
|
+
// The Project panel's "Memory" section — project memory as readable text. Answered by
|
|
165
|
+
// `project_memory`.
|
|
166
|
+
| { type: 'project-memory'; requestId: string }
|
|
167
|
+
// A driving surface invokes one runtime tool for a hosted app view, through the session's
|
|
168
|
+
// permission gate; a prompt it raises is attributed to that surface's driver. `viewId` names the
|
|
169
|
+
// view (from a `tool_end`'s `appView`) and limits the call to the tools that view's own source
|
|
170
|
+
// declared. Answered by `app_tool_result`; a call that decoded but is refused (the view is gone,
|
|
171
|
+
// the tool is not the view's, the invocation is refused) is answered by `protocol_error` echoing
|
|
172
|
+
// `requestId`. A frame that does not decode, or one an observer sends, carries no `requestId`.
|
|
173
|
+
| {
|
|
174
|
+
type: 'call-app-tool';
|
|
175
|
+
requestId: string;
|
|
176
|
+
viewId: string;
|
|
177
|
+
name: string;
|
|
178
|
+
arguments: TToolParameters;
|
|
179
|
+
}
|
|
180
|
+
// A driving surface reads the view a finished model call named in its `tool_end` (`appView`).
|
|
181
|
+
// Answered by `app_view`; a read that decoded but cannot be served (gone, or too large to send)
|
|
182
|
+
// is answered by `protocol_error` echoing `requestId`.
|
|
183
|
+
| { type: 'read-app-view'; requestId: string; viewId: string }
|
|
184
|
+
| { type: 'get-background-tasks'; filter?: IBackgroundTaskListFilter }
|
|
185
|
+
| { type: 'get-background-task'; taskId: string }
|
|
186
|
+
| { type: 'get-background-job-groups' }
|
|
187
|
+
| { type: 'get-background-job-group'; groupId: string }
|
|
188
|
+
| { type: 'wait-background-job-group'; groupId: string }
|
|
189
|
+
| { type: 'cancel-background-task'; taskId: string; reason?: string }
|
|
190
|
+
| { type: 'close-background-task'; taskId: string }
|
|
191
|
+
| { type: 'send-background-task'; taskId: string; input: IBackgroundTaskInput }
|
|
192
|
+
| { type: 'read-background-task-log'; taskId: string; cursor?: IBackgroundTaskLogCursor }
|
|
193
|
+
// REMOTE-007: a driving client answers a pending permission/ask prompt by id (first answer wins).
|
|
194
|
+
| { type: 'permission-response'; id: string; result: TPermissionResultValue }
|
|
195
|
+
| { type: 'ask-response'; id: string; response: TActionResponse }
|
|
196
|
+
// REMOTE-013 E4 session-resume: `resume` asks the host to replay the tail after `lastSeq` (the last seq the
|
|
197
|
+
// client applied); `ack` lets the host free its un-acked buffer up to `seq`. Only meaningful post-E3-accept.
|
|
198
|
+
| { type: 'resume'; lastSeq: number }
|
|
199
|
+
| { type: 'ack'; seq: number }
|
|
200
|
+
// #3282 §4a: the GUI Settings screen. A snapshot fetch and a discriminated single-field patch,
|
|
201
|
+
// never command text — the server applies a patch through the same function its slash command
|
|
202
|
+
// uses, so the two paths cannot drift. Answered by `settings` or `settings_error`.
|
|
203
|
+
| { type: 'get-settings'; requestId: string }
|
|
204
|
+
| { type: 'update-settings'; requestId: string; patch: TSettingsPatch };
|
|
205
|
+
|
|
206
|
+
/** Outbound message from server to client. */
|
|
207
|
+
export type TServerMessage =
|
|
208
|
+
// REMOTE-014 E5: turn-authored events optionally carry the ACTIVE turn's `driverId` (co-drive authorship,
|
|
209
|
+
// display-only). Stamped at `subscribeSessionEvents` from `getActiveDriverId()`; background/goal/memory/
|
|
210
|
+
// execution-workspace events are NEVER stamped (they are not authored by a driver turn).
|
|
211
|
+
| { type: 'text_delta'; delta: string; driverId?: TDriverId }
|
|
212
|
+
| { type: 'user_message'; content: string; driverId?: TDriverId }
|
|
213
|
+
| { type: 'tool_start'; state: IToolState; driverId?: TDriverId }
|
|
214
|
+
| { type: 'tool_end'; state: IToolState; driverId?: TDriverId }
|
|
215
|
+
| { type: 'thinking'; isThinking: boolean; driverId?: TDriverId }
|
|
216
|
+
| { type: 'complete'; result: TWireExecutionResult; driverId?: TDriverId }
|
|
217
|
+
| { type: 'interrupted'; result: TWireExecutionResult; driverId?: TDriverId }
|
|
218
|
+
| {
|
|
219
|
+
type: 'error';
|
|
220
|
+
/** The raw failure text — kept for a "Details" disclosure; never the whole story on its own. */
|
|
221
|
+
message: string;
|
|
222
|
+
/**
|
|
223
|
+
* What kind of failure this was, when it's known — so a renderer can say what happened and
|
|
224
|
+
* what to do next in plain words instead of showing `message` verbatim (#3289 §3). Additive:
|
|
225
|
+
* absent for a session error this classification does not recognize (unchanged behavior).
|
|
226
|
+
*/
|
|
227
|
+
code?: 'auth' | 'rate_limit' | 'model_unavailable' | 'network' | 'provider';
|
|
228
|
+
/** The provider/profile name the failure came from, when `code` names one. */
|
|
229
|
+
provider?: string;
|
|
230
|
+
/** For `code: 'rate_limit'`, how long until a retry may succeed, when the provider said so. */
|
|
231
|
+
retryAfterSeconds?: number;
|
|
232
|
+
/**
|
|
233
|
+
* For `code: 'model_unavailable'`, the model the failed request tried — captured at the moment
|
|
234
|
+
* of failure so a renderer never has to fall back to whatever model is live by the time it
|
|
235
|
+
* draws this notice (which may already be a different one the person switched to).
|
|
236
|
+
*/
|
|
237
|
+
model?: string;
|
|
238
|
+
driverId?: TDriverId;
|
|
239
|
+
}
|
|
240
|
+
| {
|
|
241
|
+
type: 'command_result';
|
|
242
|
+
name: string;
|
|
243
|
+
message: string;
|
|
244
|
+
success: boolean;
|
|
245
|
+
data?: ICommandResult['data'];
|
|
246
|
+
/** The `requestId` of the `command` this answers, when it carried one. */
|
|
247
|
+
requestId?: string;
|
|
248
|
+
}
|
|
249
|
+
| {
|
|
250
|
+
type: 'messages';
|
|
251
|
+
messages: ReturnType<ISessionConversationRead['getMessages']>;
|
|
252
|
+
/**
|
|
253
|
+
* #3288 §2: the SAME history, projected into display segments (text runs and finished tool
|
|
254
|
+
* calls, diffs included) — so a reload/reconnect/resume replay shows tool rows instead of bare
|
|
255
|
+
* text. Optional so an older host that has not grown `getMessagesDisplay()` yet still sends a
|
|
256
|
+
* valid frame; a client without this field falls back to `messages`-only (text bubbles), the
|
|
257
|
+
* same as before this existed.
|
|
258
|
+
*/
|
|
259
|
+
display?: ReturnType<ISessionConversationRead['getMessagesDisplay']>;
|
|
260
|
+
/**
|
|
261
|
+
* #3289 §3: this connection's own server-assigned driver id, carried on the first frame every
|
|
262
|
+
* connection already gets — so a client can tell its OWN turns from a co-driver's instead of
|
|
263
|
+
* treating everything but the literal `'owner'` id as someone else (REMOTE-014 E5 display-only).
|
|
264
|
+
*/
|
|
265
|
+
driverId?: TDriverId;
|
|
266
|
+
}
|
|
267
|
+
// #3189: one page of the full history. `entries` start at `startIndex` of the `total` the session
|
|
268
|
+
// holds now, and stop before a page grows past a bounded size (a single larger entry is sent alone).
|
|
269
|
+
| { type: 'history'; startIndex: number; total: number; entries: IWireHistoryEntry[] }
|
|
270
|
+
// Sent in reply to `get-context`, and pushed whenever the session's context window changes.
|
|
271
|
+
| { type: 'context'; state: ReturnType<ISessionConversationRead['getContextState']> }
|
|
272
|
+
// #3189: the full history gained entries that no streamed frame carries (a compaction, a skill
|
|
273
|
+
// activation, a memory event). A client that shows the full history re-reads it with `get-history`.
|
|
274
|
+
| {
|
|
275
|
+
type: 'history_changed';
|
|
276
|
+
/** A completed compaction, for clients that do not render the full system history. */
|
|
277
|
+
compact?: {
|
|
278
|
+
trigger: ICompactEvent['trigger'];
|
|
279
|
+
beforeUsedPercentage: number;
|
|
280
|
+
afterUsedPercentage: number;
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
// #3189: where the turn now starting came from (the user, a wake-up, a peer, an external event).
|
|
284
|
+
| { type: 'turn_source'; source: TTurnSource }
|
|
285
|
+
| { type: 'commands'; commands: ICommandListEntry[]; skills: ICommandSkillListEntry[] }
|
|
286
|
+
// Sent in reply to `get-status`, and pushed whenever the session's status changes.
|
|
287
|
+
| { type: 'session_status'; status: ISessionStatusSnapshot }
|
|
288
|
+
// #3282 §2: reply to `list-models`, echoing its `requestId`. `groups` is current-profile first;
|
|
289
|
+
// `currentProfile` is absent only when no provider profile is configured at all.
|
|
290
|
+
| {
|
|
291
|
+
type: 'model_list';
|
|
292
|
+
requestId: string;
|
|
293
|
+
groups: readonly IModelListGroup[];
|
|
294
|
+
currentProfile?: string;
|
|
295
|
+
currentModel: string;
|
|
296
|
+
}
|
|
297
|
+
// #3282 §4: reply to `get-agent-definitions`, echoing its `requestId`. `current` is always one of
|
|
298
|
+
// `agents`' names (the fallback default when nothing was ever selected).
|
|
299
|
+
| {
|
|
300
|
+
type: 'agent_definitions';
|
|
301
|
+
requestId: string;
|
|
302
|
+
agents: readonly IWireAgentDefinitionSummary[];
|
|
303
|
+
current: string;
|
|
304
|
+
}
|
|
305
|
+
| { type: 'sessions'; requestId: string; listing: ISessionListing }
|
|
306
|
+
| {
|
|
307
|
+
type: 'sessions_error';
|
|
308
|
+
requestId: string;
|
|
309
|
+
code: 'not_available' | 'list_failed';
|
|
310
|
+
message: string;
|
|
311
|
+
}
|
|
312
|
+
// This client's session is now another one; it re-reads what it shows. A host that binds each
|
|
313
|
+
// client to its own session sends it only to the client that moved.
|
|
314
|
+
| { type: 'session_switched'; event: ISessionSwitchedEvent }
|
|
315
|
+
// #3189: a new-session or switch-session was refused; `code` says why without parsing `message`.
|
|
316
|
+
| {
|
|
317
|
+
type: 'session_change_failed';
|
|
318
|
+
code: TSessionChangeRefusalCode;
|
|
319
|
+
message: string;
|
|
320
|
+
requestId?: string;
|
|
321
|
+
}
|
|
322
|
+
// #3289 §1: a `rename-session` succeeded (current session or not); the client refreshes its listing.
|
|
323
|
+
| { type: 'session_renamed_in_list'; requestId: string; sessionId: string; name: string }
|
|
324
|
+
| { type: 'session_rename_failed'; requestId: string; message: string }
|
|
325
|
+
// #3289 §1: a `delete-session` succeeded; the client refreshes its listing and, if it was showing
|
|
326
|
+
// the deleted session, re-reads what it now shows (the host has already switched it away).
|
|
327
|
+
| { type: 'session_deleted'; requestId: string; sessionId: string }
|
|
328
|
+
| {
|
|
329
|
+
type: 'session_delete_failed';
|
|
330
|
+
requestId: string;
|
|
331
|
+
code: TSessionDeleteRefusalCode;
|
|
332
|
+
message: string;
|
|
333
|
+
}
|
|
334
|
+
// SELFHOST-004 (P5, TC-08): carry the assembled trace/cost read-model (per-op span timeline +
|
|
335
|
+
// cost-by-source) across the sidecar boundary — no existing variant carries per-op `durationMs` or
|
|
336
|
+
// per-source `costUsd`. The GUI renders it renderer-side.
|
|
337
|
+
| { type: 'usage_report'; report: IUsageBySourceReport }
|
|
338
|
+
| { type: 'personal_usage_report'; requestId: string; report: IPersonalUsageReport }
|
|
339
|
+
| {
|
|
340
|
+
type: 'personal_usage_report_error';
|
|
341
|
+
requestId: string;
|
|
342
|
+
code: 'not_available' | 'report_failed';
|
|
343
|
+
message: string;
|
|
344
|
+
}
|
|
345
|
+
| {
|
|
346
|
+
type: 'stored_session_usage_report';
|
|
347
|
+
requestId: string;
|
|
348
|
+
sessionId: string;
|
|
349
|
+
report: IUsageBySourceReport;
|
|
350
|
+
}
|
|
351
|
+
| {
|
|
352
|
+
type: 'stored_session_usage_report_error';
|
|
353
|
+
requestId: string;
|
|
354
|
+
sessionId: string;
|
|
355
|
+
code: 'not_available' | 'report_failed';
|
|
356
|
+
message: string;
|
|
357
|
+
}
|
|
358
|
+
| { type: 'executing'; executing: boolean }
|
|
359
|
+
// The next queued prompt and how many wait. Sent in reply to `get-pending`, and to a `submit` once
|
|
360
|
+
// the host has taken the prompt (queued it behind a running turn, or run it).
|
|
361
|
+
| { type: 'pending'; pending: string | null; pendingCount?: number }
|
|
362
|
+
| { type: 'execution_workspace_event'; snapshot: IExecutionWorkspaceSnapshot }
|
|
363
|
+
| { type: 'execution_detail'; requestId: string; page: IExecutionDetailPage }
|
|
364
|
+
| { type: 'execution_detail_error'; requestId: string; message: string }
|
|
365
|
+
| { type: 'waiting_loop_stop'; requestId: string; outcome: TWaitingLoopStopOutcome }
|
|
366
|
+
// #3282 §4c: the Project panel's reads. Each result crosses the wire UNCHANGED as the session
|
|
367
|
+
// method's own return value (same convention as `waiting_loop_stop`'s `outcome` above) — the
|
|
368
|
+
// `kind` discriminant carries the non-repository / outside-workspace / unavailable / failed cases,
|
|
369
|
+
// so there is no separate `_error` sibling to keep in sync with these.
|
|
370
|
+
| { type: 'project_status'; requestId: string; result: TProjectStatusRead }
|
|
371
|
+
| { type: 'project_diff'; requestId: string; result: TProjectDiffRead }
|
|
372
|
+
| { type: 'project_memory'; requestId: string; result: TProjectMemoryRead }
|
|
373
|
+
// The outcome of a `call-app-tool`, correlated by `requestId`: the tool's own result, as the
|
|
374
|
+
// session returned it.
|
|
375
|
+
| {
|
|
376
|
+
type: 'app_tool_result';
|
|
377
|
+
requestId: string;
|
|
378
|
+
success: boolean;
|
|
379
|
+
data?: IToolExecutionResult['result'];
|
|
380
|
+
parts?: TUniversalMessagePart[];
|
|
381
|
+
error?: string;
|
|
382
|
+
}
|
|
383
|
+
// The answer to a `read-app-view`: the whole document, to the surface that asked and no other.
|
|
384
|
+
| { type: 'app_view'; requestId: string; view: IToolAppView }
|
|
385
|
+
| { type: 'background_task_event'; event: TBackgroundTaskEvent }
|
|
386
|
+
| { type: 'background_job_group_event'; event: TBackgroundJobGroupEvent }
|
|
387
|
+
| { type: 'plan_event'; event: IPlanApprovalEvent }
|
|
388
|
+
| { type: 'context_file_refreshed'; event: IContextFileRefreshedEvent }
|
|
389
|
+
| { type: 'branch_event'; event: IBranchEvent }
|
|
390
|
+
| { type: 'background_tasks'; tasks: IBackgroundTaskState[] }
|
|
391
|
+
| { type: 'background_task'; taskId: string; task: IBackgroundTaskState | null }
|
|
392
|
+
| { type: 'background_job_groups'; groups: IBackgroundJobGroupState[] }
|
|
393
|
+
| { type: 'background_job_group'; groupId: string; group: IBackgroundJobGroupState | null }
|
|
394
|
+
| { type: 'background_task_log'; taskId: string; page: IBackgroundTaskLogPage }
|
|
395
|
+
// REMOTE-007: forward the session's transport-neutral prompt events so a remote surface can render +
|
|
396
|
+
// answer the SAME prompt (permission/ask). `prompt_resolved` dismisses it when another surface won.
|
|
397
|
+
| { type: 'permission_request'; event: IPermissionRequestEvent }
|
|
398
|
+
| { type: 'ask_request'; event: IAskRequestEvent }
|
|
399
|
+
| { type: 'prompt_resolved'; event: IPromptResolvedEvent }
|
|
400
|
+
// CMD-004 Phase 2: forward command-issued UI intents (same pattern as `ask_request`). The event is
|
|
401
|
+
// requester-routed — a client renders it only when `event.requesterDriverId` is its own driver id;
|
|
402
|
+
// an unsupported intent yields an explicit "not available on this surface" notice, never a silent drop.
|
|
403
|
+
| { type: 'ui_intent'; event: IUiIntentEvent }
|
|
404
|
+
// CMD-004 Phase 2 Stage E: BROADCAST session events — every attached surface receives them
|
|
405
|
+
// (co-driving titles/transcripts follow the host-executed rename/clear; never requester-filtered).
|
|
406
|
+
| { type: 'session_renamed'; event: ISessionRenamedEvent }
|
|
407
|
+
| { type: 'history_cleared' }
|
|
408
|
+
| {
|
|
409
|
+
type: 'background_task_control_result';
|
|
410
|
+
action: TBackgroundControlAction;
|
|
411
|
+
taskId: string;
|
|
412
|
+
success: boolean;
|
|
413
|
+
message?: string;
|
|
414
|
+
}
|
|
415
|
+
// `requestId` names the `command` whose failure this reports; a refusal of anything else has none.
|
|
416
|
+
| { type: 'protocol_error'; message: string; requestId?: string }
|
|
417
|
+
// REMOTE-013 E4: sent instead of a replay when the client's `lastSeq` predates the host's retained buffer
|
|
418
|
+
// (overrun) — the client must do a full `get-messages` refresh rather than accept a silent gap.
|
|
419
|
+
| { type: 'resume_gap' }
|
|
420
|
+
// #3282 §4a: the Settings screen's snapshot, in reply to `get-settings` or `update-settings`. The
|
|
421
|
+
// same type answers both, the way `session_status` answers `get-status` and a status change alike.
|
|
422
|
+
| { type: 'settings'; requestId: string; settings: ISettingsSnapshot }
|
|
423
|
+
| {
|
|
424
|
+
type: 'settings_error';
|
|
425
|
+
requestId: string;
|
|
426
|
+
code: 'not_available' | 'invalid' | 'refused' | 'update_failed';
|
|
427
|
+
message: string;
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* REMOTE-013 E4: a server message stamped with its monotonic session sequence number (added by the
|
|
432
|
+
* {@link SessionResumeBridge} on the reconnectable WebRTC path). Intersecting over the union distributes the
|
|
433
|
+
* `seq` field onto every variant. The WS localhost path never stamps it (a `type`-dispatching client ignores
|
|
434
|
+
* an absent/extra `seq`).
|
|
435
|
+
*/
|
|
436
|
+
export type TSeqServerMessage = TServerMessage & { seq: number };
|