@dshremote/protocol 0.1.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.
@@ -0,0 +1,652 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://dshremote.dev/schemas/dshremote-protocol-v1.schema.json",
4
+ "title": "DshRemote C2C Protocol v1",
5
+ "description": "Connector ↔ Control Plane 通信协议 v1:WSS 出站连接上的消息信封与全部消息类型。对应《DshRemote 技术方案 v0.1》§4。",
6
+ "type": "object",
7
+ "oneOf": [
8
+ { "$ref": "#/$defs/helloMessage" },
9
+ { "$ref": "#/$defs/helloAckMessage" },
10
+ { "$ref": "#/$defs/pairingConsumeMessage" },
11
+ { "$ref": "#/$defs/pairingAckMessage" },
12
+ { "$ref": "#/$defs/credentialRotateMessage" },
13
+ { "$ref": "#/$defs/connectionRevokeMessage" },
14
+ { "$ref": "#/$defs/projectSyncMessage" },
15
+ { "$ref": "#/$defs/sessionEventMessage" },
16
+ { "$ref": "#/$defs/sessionReconcileMessage" },
17
+ { "$ref": "#/$defs/sessionGapMessage" },
18
+ { "$ref": "#/$defs/gapUnrecoverableMessage" },
19
+ { "$ref": "#/$defs/sessionSettingsMessage" },
20
+ { "$ref": "#/$defs/sessionSettingsResultMessage" },
21
+ { "$ref": "#/$defs/sessionCommandMessage" },
22
+ { "$ref": "#/$defs/sessionCommandResultMessage" },
23
+ { "$ref": "#/$defs/taskDispatchMessage" },
24
+ { "$ref": "#/$defs/taskSyncMessage" },
25
+ { "$ref": "#/$defs/runAckMessage" },
26
+ { "$ref": "#/$defs/runControlMessage" },
27
+ { "$ref": "#/$defs/runStatusMessage" },
28
+ { "$ref": "#/$defs/approvalRequestMessage" },
29
+ { "$ref": "#/$defs/approvalAnswerMessage" },
30
+ { "$ref": "#/$defs/artifactRegisterMessage" },
31
+ { "$ref": "#/$defs/artifactFetchMessage" },
32
+ { "$ref": "#/$defs/artifactContentMessage" },
33
+ { "$ref": "#/$defs/pingMessage" },
34
+ { "$ref": "#/$defs/pongMessage" }
35
+ ],
36
+ "$defs": {
37
+ "id": { "type": "string", "minLength": 1, "maxLength": 128 },
38
+ "messageBase": {
39
+ "type": "object",
40
+ "additionalProperties": false,
41
+ "required": ["v", "msgId", "type"],
42
+ "properties": {
43
+ "v": { "const": 1 },
44
+ "msgId": { "type": "string", "minLength": 1, "maxLength": 128 },
45
+ "ackId": { "type": "string", "maxLength": 128 }
46
+ }
47
+ },
48
+ "helloMessage": {
49
+ "allOf": [
50
+ { "$ref": "#/$defs/messageBase" },
51
+ {
52
+ "properties": {
53
+ "type": { "const": "hello" },
54
+ "payload": {
55
+ "type": "object",
56
+ "additionalProperties": false,
57
+ "required": ["protocolVersion", "schemaVersion", "connectionId", "nonce", "signature", "capabilities"],
58
+ "properties": {
59
+ "protocolVersion": { "const": 1 },
60
+ "schemaVersion": { "const": 1 },
61
+ "connectionId": { "$ref": "#/$defs/id" },
62
+ "nonce": { "type": "string" },
63
+ "signature": { "type": "string", "description": "签名原文 = connectionId + ':' + nonce,Ed25519 私钥签名,base64" },
64
+ "capabilities": {
65
+ "type": "object",
66
+ "additionalProperties": false,
67
+ "required": ["harnessVersion", "pluginVersion", "profile", "providers"],
68
+ "properties": {
69
+ "harnessVersion": { "type": "string" },
70
+ "pluginVersion": { "type": "string" },
71
+ "profile": { "type": "string" },
72
+ "providers": { "type": "array", "items": { "type": "string" } }
73
+ }
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+ ]
80
+ },
81
+ "helloAckMessage": {
82
+ "allOf": [
83
+ { "$ref": "#/$defs/messageBase" },
84
+ {
85
+ "properties": {
86
+ "type": { "const": "helloAck" },
87
+ "payload": {
88
+ "type": "object",
89
+ "additionalProperties": false,
90
+ "required": ["accepted", "protocolVersion", "schemaVersion"],
91
+ "properties": {
92
+ "accepted": { "type": "boolean" },
93
+ "protocolVersion": { "const": 1 },
94
+ "schemaVersion": { "const": 1 },
95
+ "reason": { "type": "string" }
96
+ }
97
+ }
98
+ }
99
+ }
100
+ ]
101
+ },
102
+ "pairingConsumeMessage": {
103
+ "allOf": [
104
+ { "$ref": "#/$defs/messageBase" },
105
+ {
106
+ "properties": {
107
+ "type": { "const": "pairing.consume" },
108
+ "payload": {
109
+ "type": "object",
110
+ "additionalProperties": false,
111
+ "required": ["ticket", "publicKey"],
112
+ "properties": {
113
+ "ticket": { "type": "string" },
114
+ "publicKey": { "type": "string", "description": "Ed25519 公钥,base64" }
115
+ }
116
+ }
117
+ }
118
+ }
119
+ ]
120
+ },
121
+ "pairingAckMessage": {
122
+ "allOf": [
123
+ { "$ref": "#/$defs/messageBase" },
124
+ {
125
+ "properties": {
126
+ "type": { "const": "pairing.ack" },
127
+ "payload": {
128
+ "type": "object",
129
+ "additionalProperties": false,
130
+ "required": ["connectionId", "accepted"],
131
+ "properties": {
132
+ "connectionId": { "$ref": "#/$defs/id" },
133
+ "accepted": { "type": "boolean" },
134
+ "reason": { "type": "string" }
135
+ }
136
+ }
137
+ }
138
+ }
139
+ ]
140
+ },
141
+ "credentialRotateMessage": {
142
+ "allOf": [
143
+ { "$ref": "#/$defs/messageBase" },
144
+ {
145
+ "properties": {
146
+ "type": { "const": "credential.rotate" },
147
+ "payload": {
148
+ "type": "object",
149
+ "additionalProperties": false,
150
+ "required": ["requestId"],
151
+ "properties": {
152
+ "requestId": { "type": "string" },
153
+ "publicKey": { "type": "string", "description": "P→C 触发时省略;C→P 应答时携带新公钥" }
154
+ }
155
+ }
156
+ }
157
+ }
158
+ ]
159
+ },
160
+ "connectionRevokeMessage": {
161
+ "allOf": [
162
+ { "$ref": "#/$defs/messageBase" },
163
+ {
164
+ "properties": {
165
+ "type": { "const": "connection.revoke" },
166
+ "payload": {
167
+ "type": "object",
168
+ "additionalProperties": false,
169
+ "properties": {
170
+ "reason": { "type": "string" }
171
+ }
172
+ }
173
+ }
174
+ }
175
+ ]
176
+ },
177
+ "projectSyncMessage": {
178
+ "allOf": [
179
+ { "$ref": "#/$defs/messageBase" },
180
+ {
181
+ "properties": {
182
+ "type": { "const": "project.sync" },
183
+ "payload": {
184
+ "type": "object",
185
+ "additionalProperties": false,
186
+ "required": ["projects", "removed"],
187
+ "properties": {
188
+ "projects": {
189
+ "type": "array",
190
+ "items": {
191
+ "type": "object",
192
+ "additionalProperties": false,
193
+ "required": ["projectId", "displayName", "available", "lastSyncedAt"],
194
+ "properties": {
195
+ "projectId": { "$ref": "#/$defs/id" },
196
+ "displayName": { "type": "string" },
197
+ "repoSummary": { "type": "string" },
198
+ "branchSummary": { "type": "string" },
199
+ "available": { "type": "boolean" },
200
+ "lastSyncedAt": { "type": "integer", "minimum": 0 }
201
+ }
202
+ }
203
+ },
204
+ "removed": { "type": "array", "items": { "$ref": "#/$defs/id" } }
205
+ }
206
+ }
207
+ }
208
+ }
209
+ ]
210
+ },
211
+ "sessionEventMessage": {
212
+ "allOf": [
213
+ { "$ref": "#/$defs/messageBase" },
214
+ {
215
+ "properties": {
216
+ "type": { "const": "session.event" },
217
+ "payload": {
218
+ "type": "object",
219
+ "additionalProperties": false,
220
+ "required": ["event"],
221
+ "properties": {
222
+ "event": { "$ref": "dshremote-event-v1.schema.json" }
223
+ }
224
+ }
225
+ }
226
+ }
227
+ ]
228
+ },
229
+ "sessionReconcileMessage": {
230
+ "allOf": [
231
+ { "$ref": "#/$defs/messageBase" },
232
+ {
233
+ "properties": {
234
+ "type": { "const": "session.reconcile" },
235
+ "payload": {
236
+ "type": "object",
237
+ "additionalProperties": false,
238
+ "required": ["sessions"],
239
+ "properties": {
240
+ "sessions": {
241
+ "type": "array",
242
+ "items": {
243
+ "type": "object",
244
+ "additionalProperties": false,
245
+ "required": ["sessionId", "lastSyncedSeq", "status"],
246
+ "properties": {
247
+ "sessionId": { "$ref": "#/$defs/id" },
248
+ "lastSyncedSeq": { "type": "integer", "minimum": -1 },
249
+ "status": { "enum": ["active", "ended", "unknown"] }
250
+ }
251
+ }
252
+ }
253
+ }
254
+ }
255
+ }
256
+ }
257
+ ]
258
+ },
259
+ "sessionGapMessage": {
260
+ "allOf": [
261
+ { "$ref": "#/$defs/messageBase" },
262
+ {
263
+ "properties": {
264
+ "type": { "const": "session.gap" },
265
+ "payload": {
266
+ "type": "object",
267
+ "additionalProperties": false,
268
+ "required": ["sessionId", "fromSeq", "toSeq"],
269
+ "properties": {
270
+ "sessionId": { "$ref": "#/$defs/id" },
271
+ "fromSeq": { "type": "integer", "minimum": 0, "description": "本端已持有的最大 seq(不含)" },
272
+ "toSeq": { "type": "integer", "minimum": 0, "description": "需要补到的最小 seq(含)" }
273
+ }
274
+ }
275
+ }
276
+ }
277
+ ]
278
+ },
279
+ "gapUnrecoverableMessage": {
280
+ "allOf": [
281
+ { "$ref": "#/$defs/messageBase" },
282
+ {
283
+ "properties": {
284
+ "type": { "const": "gap.unrecoverable" },
285
+ "payload": {
286
+ "type": "object",
287
+ "additionalProperties": false,
288
+ "required": ["sessionId", "fromSeq", "oldestSeq", "toSeq"],
289
+ "properties": {
290
+ "sessionId": { "$ref": "#/$defs/id" },
291
+ "fromSeq": { "type": "integer", "minimum": -1, "description": "云端请求的 fromSeq(不含);-1 表示云端尚无该 session 事件" },
292
+ "oldestSeq": { "type": "integer", "minimum": 0, "description": "本地保留的最早 seq(含)" },
293
+ "toSeq": { "type": "integer", "minimum": 0, "description": "云端请求的 toSeq(含)" }
294
+ }
295
+ }
296
+ }
297
+ }
298
+ ]
299
+ },
300
+ "sessionSettingsMessage": {
301
+ "allOf": [
302
+ { "$ref": "#/$defs/messageBase" },
303
+ {
304
+ "properties": {
305
+ "type": { "const": "session.settings" },
306
+ "payload": {
307
+ "type": "object",
308
+ "additionalProperties": false,
309
+ "required": ["sessionId"],
310
+ "properties": {
311
+ "sessionId": { "$ref": "#/$defs/id" },
312
+ "provider": { "type": "string" },
313
+ "model": { "type": "string" },
314
+ "reasoningEffort": { "type": "string" },
315
+ "preset": { "type": "string", "description": "仅空白会话可设置;否则 Harness 抛 agent-preset-locked" }
316
+ }
317
+ }
318
+ }
319
+ }
320
+ ]
321
+ },
322
+ "sessionSettingsResultMessage": {
323
+ "allOf": [
324
+ { "$ref": "#/$defs/messageBase" },
325
+ {
326
+ "properties": {
327
+ "type": { "const": "session.settingsResult" },
328
+ "payload": {
329
+ "type": "object",
330
+ "additionalProperties": false,
331
+ "required": ["sessionId", "ok"],
332
+ "properties": {
333
+ "sessionId": { "$ref": "#/$defs/id" },
334
+ "ok": { "type": "boolean" },
335
+ "reason": { "type": "string" }
336
+ }
337
+ }
338
+ }
339
+ }
340
+ ]
341
+ },
342
+ "sessionCommandMessage": {
343
+ "allOf": [
344
+ { "$ref": "#/$defs/messageBase" },
345
+ {
346
+ "properties": {
347
+ "type": { "const": "session.command" },
348
+ "payload": {
349
+ "type": "object",
350
+ "additionalProperties": false,
351
+ "required": ["sessionId", "command"],
352
+ "properties": {
353
+ "sessionId": { "$ref": "#/$defs/id" },
354
+ "command": { "enum": ["plan", "goal"], "description": "plan:切换/设定规划模式;goal:为长任务设定目标" },
355
+ "active": { "type": "boolean", "description": "plan:目标状态(缺省则切换当前)" },
356
+ "objective": { "type": "string", "description": "goal:目标文本(objective 必填)" }
357
+ }
358
+ }
359
+ }
360
+ }
361
+ ]
362
+ },
363
+ "sessionCommandResultMessage": {
364
+ "allOf": [
365
+ { "$ref": "#/$defs/messageBase" },
366
+ {
367
+ "properties": {
368
+ "type": { "const": "session.commandResult" },
369
+ "payload": {
370
+ "type": "object",
371
+ "additionalProperties": false,
372
+ "required": ["sessionId", "command", "ok"],
373
+ "properties": {
374
+ "sessionId": { "$ref": "#/$defs/id" },
375
+ "command": { "enum": ["plan", "goal"] },
376
+ "ok": { "type": "boolean" },
377
+ "reason": { "type": "string" },
378
+ "detail": { "type": "string", "description": "结果摘要(plan 目标状态 / goal 目标摘要)" }
379
+ }
380
+ }
381
+ }
382
+ }
383
+ ]
384
+ },
385
+ "taskDispatchMessage": {
386
+ "allOf": [
387
+ { "$ref": "#/$defs/messageBase" },
388
+ {
389
+ "properties": {
390
+ "type": { "const": "task.dispatch" },
391
+ "payload": {
392
+ "type": "object",
393
+ "additionalProperties": false,
394
+ "required": ["deliveryId", "runId", "taskId", "projectId", "prompt", "offlinePolicy", "attempt"],
395
+ "properties": {
396
+ "deliveryId": { "type": "string" },
397
+ "runId": { "$ref": "#/$defs/id", "description": "Control Plane 派发时创建的 Run 记录 id" },
398
+ "taskId": { "type": "string" },
399
+ "projectId": { "$ref": "#/$defs/id" },
400
+ "prompt": { "type": "string" },
401
+ "policyOverrides": { "type": "object" },
402
+ "offlinePolicy": { "enum": ["skip", "deliver_later", "queue"] },
403
+ "attempt": { "type": "integer", "minimum": 1 }
404
+ }
405
+ }
406
+ }
407
+ }
408
+ ]
409
+ },
410
+ "runAckMessage": {
411
+ "allOf": [
412
+ { "$ref": "#/$defs/messageBase" },
413
+ {
414
+ "properties": {
415
+ "type": { "const": "run.ack" },
416
+ "payload": {
417
+ "type": "object",
418
+ "additionalProperties": false,
419
+ "required": ["deliveryId", "accepted"],
420
+ "properties": {
421
+ "deliveryId": { "type": "string" },
422
+ "accepted": { "type": "boolean" },
423
+ "reason": { "type": "string" },
424
+ "runId": { "$ref": "#/$defs/id" },
425
+ "sessionId": { "$ref": "#/$defs/id" }
426
+ }
427
+ }
428
+ }
429
+ }
430
+ ]
431
+ },
432
+ "taskSyncMessage": {
433
+ "allOf": [
434
+ { "$ref": "#/$defs/messageBase" },
435
+ {
436
+ "properties": {
437
+ "type": { "const": "task.sync" },
438
+ "payload": {
439
+ "type": "object",
440
+ "additionalProperties": false,
441
+ "required": ["tasks"],
442
+ "properties": {
443
+ "tasks": {
444
+ "type": "array",
445
+ "items": {
446
+ "type": "object",
447
+ "additionalProperties": false,
448
+ "required": ["localTaskId", "sessionId", "name", "prompt", "kind", "updatedAt"],
449
+ "properties": {
450
+ "localTaskId": { "type": "string" },
451
+ "sessionId": { "$ref": "#/$defs/id" },
452
+ "name": { "type": "string" },
453
+ "prompt": { "type": "string" },
454
+ "kind": { "enum": ["after", "at", "every"] },
455
+ "scheduleSummary": { "type": "string" },
456
+ "updatedAt": { "type": "integer", "minimum": 0 }
457
+ }
458
+ }
459
+ }
460
+ }
461
+ }
462
+ }
463
+ }
464
+ ]
465
+ },
466
+ "runControlMessage": {
467
+ "allOf": [
468
+ { "$ref": "#/$defs/messageBase" },
469
+ {
470
+ "properties": {
471
+ "type": { "const": "run.control" },
472
+ "payload": {
473
+ "type": "object",
474
+ "additionalProperties": false,
475
+ "required": ["runId", "action"],
476
+ "properties": {
477
+ "runId": { "$ref": "#/$defs/id" },
478
+ "sessionId": { "$ref": "#/$defs/id" },
479
+ "action": { "enum": ["stop", "resume", "retry"] },
480
+ "message": { "type": "string" }
481
+ }
482
+ }
483
+ }
484
+ }
485
+ ]
486
+ },
487
+ "runStatusMessage": {
488
+ "allOf": [
489
+ { "$ref": "#/$defs/messageBase" },
490
+ {
491
+ "properties": {
492
+ "type": { "const": "run.status" },
493
+ "payload": {
494
+ "type": "object",
495
+ "additionalProperties": false,
496
+ "required": ["runId", "status"],
497
+ "properties": {
498
+ "runId": { "$ref": "#/$defs/id" },
499
+ "status": { "enum": ["Queued", "Running", "WaitingForApproval", "Completed", "Failed", "Stopped", "ConnectionLost", "TimedOut", "LimitReached"] },
500
+ "reason": { "type": "string" }
501
+ }
502
+ }
503
+ }
504
+ }
505
+ ]
506
+ },
507
+ "approvalRequestMessage": {
508
+ "allOf": [
509
+ { "$ref": "#/$defs/messageBase" },
510
+ {
511
+ "properties": {
512
+ "type": { "const": "approval.request" },
513
+ "payload": {
514
+ "type": "object",
515
+ "additionalProperties": false,
516
+ "required": ["requestId", "toolName", "expiresAt"],
517
+ "properties": {
518
+ "requestId": { "type": "string" },
519
+ "agentId": { "type": "string" },
520
+ "sessionId": { "$ref": "#/$defs/id" },
521
+ "runId": { "$ref": "#/$defs/id" },
522
+ "toolName": { "type": "string" },
523
+ "callId": { "type": "string" },
524
+ "reason": { "type": "string" },
525
+ "expiresAt": { "type": "integer", "minimum": 0 }
526
+ }
527
+ }
528
+ }
529
+ }
530
+ ]
531
+ },
532
+ "approvalAnswerMessage": {
533
+ "allOf": [
534
+ { "$ref": "#/$defs/messageBase" },
535
+ {
536
+ "properties": {
537
+ "type": { "const": "approval.answer" },
538
+ "payload": {
539
+ "type": "object",
540
+ "additionalProperties": false,
541
+ "required": ["requestId", "outcome"],
542
+ "properties": {
543
+ "requestId": { "type": "string" },
544
+ "outcome": { "enum": ["allowed-once", "rejected", "cancelled", "unavailable"] }
545
+ }
546
+ }
547
+ }
548
+ }
549
+ ]
550
+ },
551
+ "artifactRegisterMessage": {
552
+ "allOf": [
553
+ { "$ref": "#/$defs/messageBase" },
554
+ {
555
+ "properties": {
556
+ "type": { "const": "artifact.register" },
557
+ "payload": {
558
+ "type": "object",
559
+ "additionalProperties": false,
560
+ "required": ["artifactId", "runId", "name", "size", "type"],
561
+ "properties": {
562
+ "artifactId": { "type": "string" },
563
+ "runId": { "$ref": "#/$defs/id" },
564
+ "name": { "type": "string" },
565
+ "size": { "type": "integer", "minimum": 0 },
566
+ "type": { "type": "string" },
567
+ "retentionMs": { "type": "integer", "minimum": 0 }
568
+ }
569
+ }
570
+ }
571
+ }
572
+ ]
573
+ },
574
+ "artifactFetchMessage": {
575
+ "allOf": [
576
+ { "$ref": "#/$defs/messageBase" },
577
+ {
578
+ "properties": {
579
+ "type": { "const": "artifact.fetch" },
580
+ "payload": {
581
+ "type": "object",
582
+ "additionalProperties": false,
583
+ "required": ["requestId", "artifactId", "runId"],
584
+ "properties": {
585
+ "requestId": { "type": "string" },
586
+ "artifactId": { "type": "string" },
587
+ "runId": { "$ref": "#/$defs/id" },
588
+ "maxBytes": { "type": "integer", "minimum": 1 }
589
+ }
590
+ }
591
+ }
592
+ }
593
+ ]
594
+ },
595
+ "artifactContentMessage": {
596
+ "allOf": [
597
+ { "$ref": "#/$defs/messageBase" },
598
+ {
599
+ "properties": {
600
+ "type": { "const": "artifact.content" },
601
+ "payload": {
602
+ "type": "object",
603
+ "additionalProperties": false,
604
+ "required": ["requestId", "ok"],
605
+ "properties": {
606
+ "requestId": { "type": "string" },
607
+ "ok": { "type": "boolean" },
608
+ "error": { "type": "string" },
609
+ "name": { "type": "string" },
610
+ "type": { "type": "string" },
611
+ "size": { "type": "integer", "minimum": 0 },
612
+ "contentBase64": { "type": "string" }
613
+ }
614
+ }
615
+ }
616
+ }
617
+ ]
618
+ },
619
+ "pingMessage": {
620
+ "allOf": [
621
+ { "$ref": "#/$defs/messageBase" },
622
+ {
623
+ "properties": {
624
+ "type": { "const": "ping" },
625
+ "payload": {
626
+ "type": "object",
627
+ "additionalProperties": false,
628
+ "required": ["t"],
629
+ "properties": { "t": { "type": "integer", "minimum": 0 } }
630
+ }
631
+ }
632
+ }
633
+ ]
634
+ },
635
+ "pongMessage": {
636
+ "allOf": [
637
+ { "$ref": "#/$defs/messageBase" },
638
+ {
639
+ "properties": {
640
+ "type": { "const": "pong" },
641
+ "payload": {
642
+ "type": "object",
643
+ "additionalProperties": false,
644
+ "required": ["t"],
645
+ "properties": { "t": { "type": "integer", "minimum": 0 } }
646
+ }
647
+ }
648
+ }
649
+ ]
650
+ }
651
+ }
652
+ }