@agentuity/coder 2.0.0-beta.1 → 2.0.0
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/dist/client.d.ts.map +1 -1
- package/dist/client.js +1 -0
- package/dist/client.js.map +1 -1
- package/dist/hub-overlay.d.ts.map +1 -1
- package/dist/hub-overlay.js +12 -4
- package/dist/hub-overlay.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/protocol.d.ts +345 -36
- package/dist/protocol.d.ts.map +1 -1
- package/dist/remote-session.d.ts.map +1 -1
- package/dist/remote-session.js +27 -7
- package/dist/remote-session.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +1 -0
- package/src/hub-overlay.ts +32 -155
- package/src/index.ts +9 -2
- package/src/protocol.ts +417 -36
- package/src/remote-session.ts +26 -6
package/src/protocol.ts
CHANGED
|
@@ -94,7 +94,13 @@ export interface HubConfig {
|
|
|
94
94
|
|
|
95
95
|
export interface InitMessage {
|
|
96
96
|
type: 'init';
|
|
97
|
+
role: 'lead' | 'sub_agent' | 'controller';
|
|
97
98
|
sessionId?: string;
|
|
99
|
+
resume?: {
|
|
100
|
+
sessionFile: string;
|
|
101
|
+
piSessionId?: string;
|
|
102
|
+
cwd?: string;
|
|
103
|
+
};
|
|
98
104
|
tools?: HubToolDefinition[];
|
|
99
105
|
commands?: HubCommandDefinition[];
|
|
100
106
|
agents?: AgentDefinition[];
|
|
@@ -105,6 +111,7 @@ export interface InitMessage {
|
|
|
105
111
|
};
|
|
106
112
|
thinkingLevel?: string;
|
|
107
113
|
task?: string;
|
|
114
|
+
agentRole?: string;
|
|
108
115
|
}
|
|
109
116
|
|
|
110
117
|
export interface EventRequest {
|
|
@@ -159,10 +166,15 @@ export interface PingMessage {
|
|
|
159
166
|
timestamp: number;
|
|
160
167
|
}
|
|
161
168
|
|
|
169
|
+
export interface BootstrapReadyMessage {
|
|
170
|
+
type: 'bootstrap_ready';
|
|
171
|
+
}
|
|
172
|
+
|
|
162
173
|
export type HubClientMessage =
|
|
163
174
|
| HubRequest
|
|
164
175
|
| SessionEntryMessage
|
|
165
176
|
| SessionWriteMessage
|
|
177
|
+
| BootstrapReadyMessage
|
|
166
178
|
| RpcCommandMessage
|
|
167
179
|
| RpcUiResponseMessage
|
|
168
180
|
| PingMessage;
|
|
@@ -195,6 +207,14 @@ export interface ConnectionRejectedMessage {
|
|
|
195
207
|
timestamp: number;
|
|
196
208
|
}
|
|
197
209
|
|
|
210
|
+
export interface ProtocolErrorMessage {
|
|
211
|
+
type: 'protocol_error';
|
|
212
|
+
code: string;
|
|
213
|
+
message: string;
|
|
214
|
+
sessionId?: string;
|
|
215
|
+
timestamp: number;
|
|
216
|
+
}
|
|
217
|
+
|
|
198
218
|
export interface ConversationEntry {
|
|
199
219
|
type:
|
|
200
220
|
| 'message'
|
|
@@ -202,6 +222,9 @@ export interface ConversationEntry {
|
|
|
202
222
|
| 'tool_call'
|
|
203
223
|
| 'tool_result'
|
|
204
224
|
| 'task_result'
|
|
225
|
+
| 'runtime_status'
|
|
226
|
+
| 'runtime_output'
|
|
227
|
+
| 'runtime_preview'
|
|
205
228
|
| 'turn'
|
|
206
229
|
| 'user_prompt';
|
|
207
230
|
agent?: string;
|
|
@@ -210,6 +233,29 @@ export interface ConversationEntry {
|
|
|
210
233
|
toolName?: string;
|
|
211
234
|
toolArgs?: Record<string, unknown>;
|
|
212
235
|
toolCallId?: string;
|
|
236
|
+
runtime?:
|
|
237
|
+
| {
|
|
238
|
+
id?: string;
|
|
239
|
+
command?: string;
|
|
240
|
+
status?: string;
|
|
241
|
+
stream?: string;
|
|
242
|
+
exitCode?: number;
|
|
243
|
+
}
|
|
244
|
+
| undefined;
|
|
245
|
+
preview?:
|
|
246
|
+
| {
|
|
247
|
+
id?: string;
|
|
248
|
+
url?: string;
|
|
249
|
+
status?: string;
|
|
250
|
+
label?: string;
|
|
251
|
+
}
|
|
252
|
+
| undefined;
|
|
253
|
+
attachments?: Array<{
|
|
254
|
+
id?: string;
|
|
255
|
+
filename?: string;
|
|
256
|
+
mime?: string;
|
|
257
|
+
size?: number;
|
|
258
|
+
}>;
|
|
213
259
|
isError?: boolean;
|
|
214
260
|
taskId?: string;
|
|
215
261
|
turnId?: string;
|
|
@@ -219,16 +265,28 @@ export interface ConversationEntry {
|
|
|
219
265
|
timestamp: number;
|
|
220
266
|
}
|
|
221
267
|
|
|
222
|
-
export interface
|
|
268
|
+
export interface SessionTaskState {
|
|
223
269
|
taskId: string;
|
|
224
270
|
agent: string;
|
|
225
271
|
status: 'running' | 'completed' | 'failed';
|
|
226
272
|
prompt: string;
|
|
273
|
+
startedAt?: string;
|
|
274
|
+
completedAt?: string;
|
|
227
275
|
duration?: number;
|
|
228
276
|
result?: string;
|
|
229
277
|
error?: string;
|
|
230
278
|
}
|
|
231
279
|
|
|
280
|
+
export type HydrationTaskState = SessionTaskState;
|
|
281
|
+
|
|
282
|
+
export interface SessionTaskProjection<TTaskState = SessionTaskState> {
|
|
283
|
+
tasks: TTaskState[];
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export interface SessionStreamWorkExtension {
|
|
287
|
+
stream?: SessionStreamProjection;
|
|
288
|
+
}
|
|
289
|
+
|
|
232
290
|
export interface SessionParticipant {
|
|
233
291
|
id: string;
|
|
234
292
|
role: 'lead' | 'observer' | 'controller';
|
|
@@ -247,59 +305,252 @@ export interface SessionStreamProjection extends SessionStreamBlock {
|
|
|
247
305
|
tasks: Record<string, SessionStreamBlock>;
|
|
248
306
|
}
|
|
249
307
|
|
|
250
|
-
export
|
|
308
|
+
export type WorkflowMode = 'standard' | 'loop';
|
|
309
|
+
export type LoopStatus =
|
|
310
|
+
| 'idle'
|
|
311
|
+
| 'starting'
|
|
312
|
+
| 'running'
|
|
313
|
+
| 'paused'
|
|
314
|
+
| 'awaiting_input'
|
|
315
|
+
| 'blocked'
|
|
316
|
+
| 'completed'
|
|
317
|
+
| 'failed'
|
|
318
|
+
| 'cancelled';
|
|
319
|
+
|
|
320
|
+
export interface SessionLoopState {
|
|
321
|
+
workflowMode: WorkflowMode;
|
|
322
|
+
loopId?: string;
|
|
323
|
+
status: LoopStatus;
|
|
324
|
+
goal?: string;
|
|
325
|
+
summary?: string;
|
|
326
|
+
nextAction?: string;
|
|
327
|
+
blockers: string[];
|
|
328
|
+
iteration: number;
|
|
329
|
+
maxIterations: number;
|
|
330
|
+
autoContinue: boolean;
|
|
331
|
+
allowDetached: boolean;
|
|
332
|
+
recoveryAttempts: number;
|
|
333
|
+
awaitingUser: boolean;
|
|
334
|
+
activePrdKey?: string;
|
|
335
|
+
activePrdTaskId?: string;
|
|
336
|
+
coordinationJobId?: string;
|
|
337
|
+
currentWaveId?: string;
|
|
338
|
+
currentWaveLabel?: string;
|
|
339
|
+
lastCheckpointSummary?: string;
|
|
340
|
+
startedAt?: number;
|
|
341
|
+
updatedAt?: number;
|
|
342
|
+
lastCheckpointAt?: number;
|
|
343
|
+
completedAt?: number;
|
|
344
|
+
lastError?: string;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export type SessionBucket = 'running' | 'paused' | 'provisioning' | 'history';
|
|
348
|
+
|
|
349
|
+
export interface SessionSkillRef {
|
|
350
|
+
skillId: string;
|
|
351
|
+
repo: string;
|
|
352
|
+
name?: string;
|
|
353
|
+
url?: string;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export interface SessionListDiagnostics {
|
|
357
|
+
inactiveRunningTasks: Array<{
|
|
358
|
+
taskId: string;
|
|
359
|
+
agent: string;
|
|
360
|
+
inactivityMs: number;
|
|
361
|
+
startedAt: string;
|
|
362
|
+
lastActivityAt?: string;
|
|
363
|
+
}>;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export interface SessionListItem {
|
|
251
367
|
sessionId: string;
|
|
252
368
|
label: string;
|
|
253
|
-
status:
|
|
369
|
+
status: string;
|
|
370
|
+
mode: 'sandbox' | 'tui';
|
|
371
|
+
sessionKind?: string;
|
|
372
|
+
parentSessionId?: string;
|
|
373
|
+
coordinationJobId?: string;
|
|
374
|
+
workflowMode: WorkflowMode;
|
|
375
|
+
loopStatus?: SessionLoopState['status'];
|
|
376
|
+
loopIteration?: number;
|
|
377
|
+
createdAt: string;
|
|
378
|
+
taskCount: number;
|
|
379
|
+
subAgentCount: number;
|
|
380
|
+
observerCount: number;
|
|
381
|
+
participantCount: number;
|
|
382
|
+
tags: string[];
|
|
383
|
+
skills: SessionSkillRef[];
|
|
384
|
+
defaultAgent?: string;
|
|
385
|
+
bucket: SessionBucket;
|
|
386
|
+
runtimeAvailable: boolean;
|
|
387
|
+
controlAvailable: boolean;
|
|
388
|
+
historyOnly: boolean;
|
|
389
|
+
diagnostics?: SessionListDiagnostics;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
export interface SandboxSessionListItem {
|
|
393
|
+
sessionId: string;
|
|
394
|
+
sandboxId: string;
|
|
395
|
+
status: string;
|
|
396
|
+
task?: string;
|
|
397
|
+
metadata?: Record<string, unknown>;
|
|
398
|
+
wsConnected: boolean;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
export interface SessionListResponse {
|
|
402
|
+
sessions: {
|
|
403
|
+
websocket: SessionListItem[];
|
|
404
|
+
sandbox: SandboxSessionListItem[];
|
|
405
|
+
};
|
|
406
|
+
total: number;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export interface SessionDetailParticipant {
|
|
410
|
+
id: string;
|
|
411
|
+
role: string;
|
|
412
|
+
transport: string;
|
|
413
|
+
connectedAt: string;
|
|
414
|
+
idle?: boolean;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
export interface SessionAgentActivity {
|
|
418
|
+
name?: string;
|
|
419
|
+
status: string;
|
|
420
|
+
currentTool?: string;
|
|
421
|
+
currentToolArgs?: string;
|
|
422
|
+
toolCallCount: number;
|
|
423
|
+
lastActivity: number;
|
|
424
|
+
totalElapsed?: number;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
export interface SessionObservedProjection {
|
|
428
|
+
turnCount: number;
|
|
429
|
+
lastAgentModel?: string;
|
|
430
|
+
compactionCount: number;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
export interface SessionDeckGenerationState {
|
|
434
|
+
state: string;
|
|
435
|
+
requestedAt?: number;
|
|
436
|
+
startedAt?: number;
|
|
437
|
+
completedAt?: number;
|
|
438
|
+
title?: string;
|
|
439
|
+
deckType?: string;
|
|
440
|
+
prdKey?: string;
|
|
441
|
+
prdTaskId?: string;
|
|
442
|
+
todoId?: string;
|
|
443
|
+
error?: string;
|
|
444
|
+
url?: string;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
export interface SessionProductProjection {
|
|
448
|
+
activePrdKey?: string;
|
|
449
|
+
activePrdTaskId?: string;
|
|
450
|
+
deckGeneration?: SessionDeckGenerationState;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
export interface SessionActivityWorkExtensions {
|
|
454
|
+
agentActivity?: Record<string, SessionAgentActivity>;
|
|
455
|
+
diagnostics?: SessionListDiagnostics;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
export interface SessionWorkProjection<TTaskState = SessionTaskState>
|
|
459
|
+
extends SessionTaskProjection<TTaskState>,
|
|
460
|
+
SessionStreamWorkExtension,
|
|
461
|
+
SessionActivityWorkExtensions {
|
|
462
|
+
workflowMode: WorkflowMode;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
export interface SessionWorkflowProjection {
|
|
466
|
+
workflowMode: WorkflowMode;
|
|
467
|
+
loop?: SessionLoopState;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
export interface SessionLoopResponse extends Omit<SessionWorkflowProjection, 'loop'> {
|
|
471
|
+
sessionId: string;
|
|
472
|
+
loop: SessionLoopState | null;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
export interface SessionUsageAgentSummary {
|
|
476
|
+
inputTokens: number;
|
|
477
|
+
outputTokens: number;
|
|
478
|
+
reasoningTokens: number;
|
|
479
|
+
costUsd: number;
|
|
480
|
+
updatedAt: number;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
export interface SessionUsageSummary {
|
|
484
|
+
inputTokens: number;
|
|
485
|
+
outputTokens: number;
|
|
486
|
+
reasoningTokens: number;
|
|
487
|
+
costUsd: number;
|
|
488
|
+
updatedAt: number;
|
|
489
|
+
byAgent?: Record<string, SessionUsageAgentSummary>;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
export interface SessionSnapshotCore extends SessionTaskProjection {
|
|
493
|
+
sessionId: string;
|
|
494
|
+
label: string;
|
|
495
|
+
status: string;
|
|
254
496
|
createdAt: string;
|
|
255
497
|
mode: 'sandbox' | 'tui';
|
|
498
|
+
workflowMode: WorkflowMode;
|
|
499
|
+
participants: SessionDetailParticipant[];
|
|
256
500
|
task?: string;
|
|
257
501
|
error?: string;
|
|
258
|
-
|
|
259
|
-
|
|
502
|
+
bucket: SessionBucket;
|
|
503
|
+
runtimeAvailable: boolean;
|
|
504
|
+
controlAvailable: boolean;
|
|
505
|
+
historyOnly: boolean;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
export interface SessionSnapshotHistoryExtensions {
|
|
509
|
+
streamId: string | null;
|
|
510
|
+
streamUrl: string | null;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
export interface SessionSnapshotWorkExtensions
|
|
514
|
+
extends SessionStreamWorkExtension,
|
|
515
|
+
SessionActivityWorkExtensions {
|
|
516
|
+
agentActivity: Record<string, SessionAgentActivity>;
|
|
517
|
+
usage: SessionUsageSummary;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
export interface SessionSnapshotWorkflowExtensions
|
|
521
|
+
extends Pick<SessionWorkflowProjection, 'loop'> {}
|
|
522
|
+
|
|
523
|
+
export interface SessionSnapshotMetadataExtensions {
|
|
260
524
|
context: {
|
|
261
525
|
branch?: string;
|
|
262
526
|
workingDirectory?: string;
|
|
263
527
|
};
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
status: 'running' | 'completed' | 'failed';
|
|
269
|
-
prompt: string;
|
|
270
|
-
duration?: number;
|
|
271
|
-
startedAt?: string;
|
|
272
|
-
completedAt?: string;
|
|
273
|
-
}>;
|
|
274
|
-
agentActivity: Record<
|
|
275
|
-
string,
|
|
276
|
-
{
|
|
277
|
-
name?: string;
|
|
278
|
-
status: string;
|
|
279
|
-
currentTool?: string;
|
|
280
|
-
currentToolArgs?: string;
|
|
281
|
-
toolCallCount: number;
|
|
282
|
-
lastActivity: number;
|
|
283
|
-
totalElapsed?: number;
|
|
284
|
-
}
|
|
285
|
-
>;
|
|
286
|
-
stream?: SessionStreamProjection;
|
|
287
|
-
tags?: string[];
|
|
528
|
+
observed?: SessionObservedProjection;
|
|
529
|
+
product?: SessionProductProjection;
|
|
530
|
+
tags: string[];
|
|
531
|
+
skills: SessionSkillRef[];
|
|
288
532
|
defaultAgent?: string;
|
|
289
|
-
|
|
290
|
-
runtimeAvailable?: boolean;
|
|
291
|
-
controlAvailable?: boolean;
|
|
292
|
-
historyOnly?: boolean;
|
|
533
|
+
workers?: SessionListItem[];
|
|
293
534
|
}
|
|
294
535
|
|
|
295
|
-
export interface
|
|
536
|
+
export interface SessionSnapshotExtensions
|
|
537
|
+
extends SessionSnapshotHistoryExtensions,
|
|
538
|
+
SessionSnapshotWorkExtensions,
|
|
539
|
+
SessionSnapshotWorkflowExtensions,
|
|
540
|
+
SessionSnapshotMetadataExtensions {}
|
|
541
|
+
|
|
542
|
+
export interface SessionSnapshot extends SessionSnapshotCore, SessionSnapshotExtensions {}
|
|
543
|
+
|
|
544
|
+
export interface CoderHubHydrationMessage
|
|
545
|
+
extends SessionTaskProjection<HydrationTaskState>,
|
|
546
|
+
SessionStreamWorkExtension {
|
|
296
547
|
type: 'session_hydration';
|
|
297
548
|
sessionId: string;
|
|
549
|
+
label?: string;
|
|
298
550
|
resumedAt: number;
|
|
299
551
|
entries: ConversationEntry[];
|
|
300
|
-
tasks: HydrationTaskState[];
|
|
301
|
-
stream?: SessionStreamProjection;
|
|
302
552
|
task?: string;
|
|
553
|
+
leadConnected?: boolean;
|
|
303
554
|
streamingState?: {
|
|
304
555
|
isStreaming?: boolean;
|
|
305
556
|
activeTasks?: Array<{
|
|
@@ -327,6 +578,133 @@ export interface BroadcastEventMessage {
|
|
|
327
578
|
timestamp?: number;
|
|
328
579
|
}
|
|
329
580
|
|
|
581
|
+
export type ReplayEntry = ConversationEntry;
|
|
582
|
+
|
|
583
|
+
export interface ReplayHistoryResponse {
|
|
584
|
+
sessionId: string;
|
|
585
|
+
entriesSource: 'durable_stream' | 'session_entries' | 'event_history' | 'none';
|
|
586
|
+
sourceCounts?: {
|
|
587
|
+
durableStream: number;
|
|
588
|
+
sessionEntries: number;
|
|
589
|
+
eventHistory: number;
|
|
590
|
+
};
|
|
591
|
+
entries: ReplayEntry[];
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
export interface SessionEventHistoryItem {
|
|
595
|
+
id: number;
|
|
596
|
+
event: string;
|
|
597
|
+
category: string;
|
|
598
|
+
agent?: string;
|
|
599
|
+
taskId?: string;
|
|
600
|
+
payload: Record<string, unknown>;
|
|
601
|
+
occurredAt: string;
|
|
602
|
+
ingestedAt: string;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
export interface SessionEventHistoryResponse {
|
|
606
|
+
sessionId: string;
|
|
607
|
+
events: SessionEventHistoryItem[];
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
export interface SessionParticipantHistoryItem {
|
|
611
|
+
id: string;
|
|
612
|
+
role: string;
|
|
613
|
+
transport: string;
|
|
614
|
+
agentRole?: string;
|
|
615
|
+
connectedAt: string;
|
|
616
|
+
disconnectedAt?: string;
|
|
617
|
+
lastActivityAt: string;
|
|
618
|
+
metadata?: Record<string, unknown>;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
export interface SessionParticipantsResponse {
|
|
622
|
+
sessionId: string;
|
|
623
|
+
participants: SessionParticipantHistoryItem[];
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
export interface SessionTodoSummary {
|
|
627
|
+
open: number;
|
|
628
|
+
in_progress: number;
|
|
629
|
+
done: number;
|
|
630
|
+
closed: number;
|
|
631
|
+
cancelled: number;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
export interface SessionTodoAssignee {
|
|
635
|
+
id: string;
|
|
636
|
+
name: string;
|
|
637
|
+
type?: string;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
export interface SessionTodoItem {
|
|
641
|
+
id: string;
|
|
642
|
+
title: string;
|
|
643
|
+
status: 'open' | 'in_progress' | 'done' | 'closed' | 'cancelled';
|
|
644
|
+
type?: string | null;
|
|
645
|
+
priority?: string | null;
|
|
646
|
+
parentTaskId?: string | null;
|
|
647
|
+
prdKey?: string | null;
|
|
648
|
+
externalRef?: string | null;
|
|
649
|
+
taskKey?: string | null;
|
|
650
|
+
origin?: string | null;
|
|
651
|
+
kind?: string | null;
|
|
652
|
+
assignee?: SessionTodoAssignee | null;
|
|
653
|
+
lastSessionId?: string | null;
|
|
654
|
+
sessionIds: string[];
|
|
655
|
+
tags: string[];
|
|
656
|
+
memoryKeys: string[];
|
|
657
|
+
memoryIds: string[];
|
|
658
|
+
touchedByAgents: string[];
|
|
659
|
+
lastTouchedByAgent?: string | null;
|
|
660
|
+
attachments: Array<Record<string, unknown>>;
|
|
661
|
+
attachmentCount: number;
|
|
662
|
+
createdAt: string;
|
|
663
|
+
updatedAt: string;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
export interface SessionTodoListResponse {
|
|
667
|
+
sessionId: string;
|
|
668
|
+
ok: boolean;
|
|
669
|
+
op: 'session_todo_list';
|
|
670
|
+
count: number;
|
|
671
|
+
summary: SessionTodoSummary;
|
|
672
|
+
todos: SessionTodoItem[];
|
|
673
|
+
unavailable?: boolean;
|
|
674
|
+
message?: string;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
export type SseSessionSnapshotParticipant = SessionDetailParticipant;
|
|
678
|
+
|
|
679
|
+
export interface SseHydrationTaskState {
|
|
680
|
+
taskId: string;
|
|
681
|
+
agent: string;
|
|
682
|
+
status: SessionTaskState['status'];
|
|
683
|
+
prompt: string;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
export interface SseSessionSnapshotMessage {
|
|
687
|
+
type: 'snapshot';
|
|
688
|
+
sessionId: string;
|
|
689
|
+
label: string;
|
|
690
|
+
status: string;
|
|
691
|
+
createdAt: string;
|
|
692
|
+
mode: 'sandbox' | 'tui';
|
|
693
|
+
participants: SseSessionSnapshotParticipant[];
|
|
694
|
+
taskCount: number;
|
|
695
|
+
agentActivity: Record<string, SessionAgentActivity>;
|
|
696
|
+
stream?: SessionStreamProjection;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
export interface SseHydrationMessage
|
|
700
|
+
extends SessionTaskProjection<SseHydrationTaskState>,
|
|
701
|
+
SessionStreamWorkExtension {
|
|
702
|
+
type: 'hydration';
|
|
703
|
+
sessionId: string;
|
|
704
|
+
entries: ConversationEntry[];
|
|
705
|
+
task?: string;
|
|
706
|
+
}
|
|
707
|
+
|
|
330
708
|
export interface RpcEventMessage {
|
|
331
709
|
type: 'rpc_event';
|
|
332
710
|
event: Record<string, unknown>;
|
|
@@ -352,6 +730,9 @@ export type ServerMessage =
|
|
|
352
730
|
| CoderHubStreamReadyMessage
|
|
353
731
|
| CoderHubSessionResumeMessage
|
|
354
732
|
| ConnectionRejectedMessage
|
|
733
|
+
| ProtocolErrorMessage
|
|
734
|
+
| SseSessionSnapshotMessage
|
|
735
|
+
| SseHydrationMessage
|
|
355
736
|
| PresenceEventMessage
|
|
356
737
|
| BroadcastEventMessage
|
|
357
738
|
| RpcEventMessage
|
package/src/remote-session.ts
CHANGED
|
@@ -265,11 +265,6 @@ export class RemoteSession {
|
|
|
265
265
|
|
|
266
266
|
this.ws.onopen = () => {
|
|
267
267
|
log('WebSocket connected');
|
|
268
|
-
try {
|
|
269
|
-
this.ws?.send(JSON.stringify({ type: 'controller_ready' }));
|
|
270
|
-
} catch {
|
|
271
|
-
// Let the normal init timeout surface if bootstrap cannot start.
|
|
272
|
-
}
|
|
273
268
|
};
|
|
274
269
|
|
|
275
270
|
this.ws.onmessage = (event: MessageEvent) => {
|
|
@@ -292,11 +287,17 @@ export class RemoteSession {
|
|
|
292
287
|
this.connected = true;
|
|
293
288
|
this.reconnectAttempts = 0;
|
|
294
289
|
if (data.sessionId) this.sessionId = data.sessionId as string;
|
|
290
|
+
if (typeof data.label === 'string') this.label = data.label;
|
|
295
291
|
this.applyLifecycle({
|
|
296
292
|
type: 'init',
|
|
297
293
|
sessionId: typeof data.sessionId === 'string' ? data.sessionId : undefined,
|
|
298
294
|
label: typeof data.label === 'string' ? data.label : undefined,
|
|
299
295
|
});
|
|
296
|
+
try {
|
|
297
|
+
this.ws?.send(JSON.stringify({ type: 'bootstrap_ready' }));
|
|
298
|
+
} catch {
|
|
299
|
+
// Let the close/error path surface bootstrap failure.
|
|
300
|
+
}
|
|
300
301
|
log(`Connected to session ${this.sessionId}`);
|
|
301
302
|
this.notifyConnectionChange('connected');
|
|
302
303
|
resolve();
|
|
@@ -316,6 +317,25 @@ export class RemoteSession {
|
|
|
316
317
|
return;
|
|
317
318
|
}
|
|
318
319
|
|
|
320
|
+
if (type === 'protocol_error') {
|
|
321
|
+
clearTimeout(connectTimeout);
|
|
322
|
+
const msg = (data.message as string) || 'Hub protocol error';
|
|
323
|
+
this.applyLifecycle({
|
|
324
|
+
type: 'rpc_command_error',
|
|
325
|
+
error: msg,
|
|
326
|
+
paused: false,
|
|
327
|
+
});
|
|
328
|
+
this.dispatchEvent({
|
|
329
|
+
type: 'protocol_error',
|
|
330
|
+
...data,
|
|
331
|
+
_source: 'hub',
|
|
332
|
+
} as RpcEvent);
|
|
333
|
+
if (!this.connected) {
|
|
334
|
+
reject(new Error(msg));
|
|
335
|
+
}
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
|
|
319
339
|
if (type === 'session_resume') {
|
|
320
340
|
this.applyLifecycle({
|
|
321
341
|
type: 'session_resume',
|
|
@@ -405,7 +425,7 @@ export class RemoteSession {
|
|
|
405
425
|
return;
|
|
406
426
|
}
|
|
407
427
|
|
|
408
|
-
//
|
|
428
|
+
// Legacy/raw RPC messages — tolerated but not expected on the controller path.
|
|
409
429
|
if (type === 'rpc_event') {
|
|
410
430
|
const rpcEvent = data.event as RpcEvent;
|
|
411
431
|
if (rpcEvent) {
|