@ccmsg/protocol 1.17.0 → 1.19.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/package.json +1 -1
- package/src/control/dump.ts +49 -10
- package/src/fixtures/control.ts +71 -5
package/package.json
CHANGED
package/src/control/dump.ts
CHANGED
|
@@ -24,7 +24,17 @@ import { Sid, Timestamp } from "../identifiers.ts";
|
|
|
24
24
|
* Segments after the first carry the spelling of whatever named them, which is
|
|
25
25
|
* why they are not held to snake_case: `tool:Bash` and `hook:PreToolUse` are
|
|
26
26
|
* the harness's words, and rewriting them would leave the reader unable to
|
|
27
|
-
* match what it sees against what it ran.
|
|
27
|
+
* match what it sees against what it ran.
|
|
28
|
+
*
|
|
29
|
+
* Under `message`, the second segment is **a relation read from the subject**:
|
|
30
|
+
* `parent` is whoever started this agent, `sub` a throwaway agent it started,
|
|
31
|
+
* `team` a named counterpart that goes on standing, `session` another session
|
|
32
|
+
* over ccmsg. The one exception is `user` — a person is not a relation to
|
|
33
|
+
* anyone, but the user, standing alone. A harness's own name for a party is
|
|
34
|
+
* never a type: `message:main` would read as the main session's traffic being
|
|
35
|
+
* overheard wherever it happens, when what is meant is the party this subject
|
|
36
|
+
* answers to — which is what `parent` says. The literal names (`main`, a
|
|
37
|
+
* lead's, a teammate's) are kept in `harness_name` on the item. */
|
|
28
38
|
export const TranscriptItemType = Type.String({
|
|
29
39
|
pattern: "^[a-z]+(?::[A-Za-z0-9_.-]+)*$",
|
|
30
40
|
$id: "TranscriptItemType",
|
|
@@ -69,6 +79,27 @@ export const TranscriptItemSelector = Type.String({
|
|
|
69
79
|
});
|
|
70
80
|
export type TranscriptItemSelector = Static<typeof TranscriptItemSelector>;
|
|
71
81
|
|
|
82
|
+
/** Whose transcript an item was read from, said as a standing rather than a
|
|
83
|
+
* name: `main` is a session's own transcript, `sub` a throwaway agent's — one
|
|
84
|
+
* started to answer once — and `team` a teammate's, an agent that was named and
|
|
85
|
+
* goes on standing.
|
|
86
|
+
*
|
|
87
|
+
* It is what the relations are read from. `message:parent:in` under a `sub` is
|
|
88
|
+
* an errand's brief and under a `team` is what its lead wrote, and an item that
|
|
89
|
+
* does not say which of the two it stood in can only be placed by whoever
|
|
90
|
+
* remembers the request that fetched it. Carrying it on the item is what lets
|
|
91
|
+
* several transcripts be drawn as one, and what lets the table of relations be
|
|
92
|
+
* checked against items rather than against the request that asked for them.
|
|
93
|
+
*
|
|
94
|
+
* It is not `harness_name`: that is the other party's literal name, this is the
|
|
95
|
+
* subject's own standing, and a subject has one whether or not anything it
|
|
96
|
+
* talked to was named. */
|
|
97
|
+
export const TranscriptSubject = Type.Union(
|
|
98
|
+
[Type.Literal("main"), Type.Literal("team"), Type.Literal("sub")],
|
|
99
|
+
{ $id: "TranscriptSubject" },
|
|
100
|
+
);
|
|
101
|
+
export type TranscriptSubject = Static<typeof TranscriptSubject>;
|
|
102
|
+
|
|
72
103
|
/** Where in the transcript the record an item was read from begins, and how far
|
|
73
104
|
* it runs.
|
|
74
105
|
*
|
|
@@ -105,10 +136,16 @@ export type TranscriptItemId = Static<typeof TranscriptItemId>;
|
|
|
105
136
|
* `id` is what the links below point with — never a position in the array,
|
|
106
137
|
* since a selection or a range decides which items exist in a given read — and
|
|
107
138
|
* `uuid` stays beside it as the record the item came out of, which is what a
|
|
108
|
-
* reader groups by when it wants the whole of one line.
|
|
139
|
+
* reader groups by when it wants the whole of one line.
|
|
140
|
+
*
|
|
141
|
+
* `subject` is on every item because an item is read out of one transcript and
|
|
142
|
+
* ends up among items from others: a client draws a session beside the agents
|
|
143
|
+
* below it, and the standing it was read from is then the item's own to state
|
|
144
|
+
* and not something to be inferred from the call that fetched it. */
|
|
109
145
|
const BASE_FIELDS = {
|
|
110
146
|
id: TranscriptItemId,
|
|
111
147
|
uuid: Type.String({ minLength: 1 }),
|
|
148
|
+
subject: TranscriptSubject,
|
|
112
149
|
source: TranscriptItemSource,
|
|
113
150
|
/** The item's own instant. A call and its result each keep their own. */
|
|
114
151
|
at: Timestamp,
|
|
@@ -190,10 +227,10 @@ const MessageUserOut = item(Type.Literal("message:user:out"), { text: Text });
|
|
|
190
227
|
* unnameable. */
|
|
191
228
|
const MessageParentIn = item(Type.Literal("message:parent:in"), {
|
|
192
229
|
text: Text,
|
|
193
|
-
/** The
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
|
|
230
|
+
/** The harness's own name for the parent — `main`, a lead's name, the agent
|
|
231
|
+
* above. Left out when the record says only that it came from above, which is
|
|
232
|
+
* the case for the brief an agent opens with. */
|
|
233
|
+
harness_name: Type.Optional(Type.String()),
|
|
197
234
|
msg_id: Type.Optional(Type.String()),
|
|
198
235
|
});
|
|
199
236
|
|
|
@@ -202,8 +239,8 @@ const MessageParentIn = item(Type.Literal("message:parent:in"), {
|
|
|
202
239
|
const MessageParentOutSent = item(Type.Literal("message:parent:out"), {
|
|
203
240
|
...USE_FIELDS,
|
|
204
241
|
text: Text,
|
|
205
|
-
/** The parent as the subject addressed it
|
|
206
|
-
|
|
242
|
+
/** The harness's own name for the parent, as the subject addressed it. */
|
|
243
|
+
harness_name: Type.Optional(Type.String()),
|
|
207
244
|
summary: Type.Optional(Type.String()),
|
|
208
245
|
});
|
|
209
246
|
|
|
@@ -223,7 +260,7 @@ const MessageTeamOut = item(Type.Literal("message:team:out"), {
|
|
|
223
260
|
...USE_FIELDS,
|
|
224
261
|
text: Text,
|
|
225
262
|
/** The teammate addressed, by the name it stands under. */
|
|
226
|
-
|
|
263
|
+
harness_name: Type.Optional(Type.String()),
|
|
227
264
|
summary: Type.Optional(Type.String()),
|
|
228
265
|
agent_id: Type.Optional(Type.String()),
|
|
229
266
|
/** Present on the call that started the teammate, absent on the ones that
|
|
@@ -236,7 +273,8 @@ const MessageTeamOut = item(Type.Literal("message:team:out"), {
|
|
|
236
273
|
* was written. */
|
|
237
274
|
const MessageTeamInSaid = item(Type.Literal("message:team:in"), {
|
|
238
275
|
text: Text,
|
|
239
|
-
|
|
276
|
+
/** The name the teammate stands under. */
|
|
277
|
+
harness_name: Type.Optional(Type.String()),
|
|
240
278
|
msg_id: Type.Optional(Type.String()),
|
|
241
279
|
});
|
|
242
280
|
|
|
@@ -244,6 +282,7 @@ const MessageTeamInSaid = item(Type.Literal("message:team:in"), {
|
|
|
244
282
|
const MessageTeamInDone = item(Type.Literal("message:team:in"), {
|
|
245
283
|
...RESULT_FIELDS,
|
|
246
284
|
text: Text,
|
|
285
|
+
harness_name: Type.Optional(Type.String()),
|
|
247
286
|
agent_id: Type.Optional(Type.String()),
|
|
248
287
|
status: Type.Optional(Type.String()),
|
|
249
288
|
duration_ms: Type.Optional(Type.Integer({ minimum: 0 })),
|
package/src/fixtures/control.ts
CHANGED
|
@@ -230,6 +230,7 @@ export const TRANSCRIPT_ITEMS: Static<typeof TranscriptItem>[] = [
|
|
|
230
230
|
{
|
|
231
231
|
id: "3f9a21c4:0",
|
|
232
232
|
uuid: "3f9a21c4",
|
|
233
|
+
subject: "main",
|
|
233
234
|
source: { offset: 180_000, bytes: 420 },
|
|
234
235
|
type: "message:user:in",
|
|
235
236
|
at: FIXTURE_NOW - 3_600_000,
|
|
@@ -239,6 +240,7 @@ export const TRANSCRIPT_ITEMS: Static<typeof TranscriptItem>[] = [
|
|
|
239
240
|
{
|
|
240
241
|
id: "f10b6d43:0",
|
|
241
242
|
uuid: "f10b6d43",
|
|
243
|
+
subject: "main",
|
|
242
244
|
source: { offset: 180_420, bytes: 980 },
|
|
243
245
|
type: "thinking",
|
|
244
246
|
at: FIXTURE_NOW - 3_500_000,
|
|
@@ -247,6 +249,7 @@ export const TRANSCRIPT_ITEMS: Static<typeof TranscriptItem>[] = [
|
|
|
247
249
|
{
|
|
248
250
|
id: "f10b6d43:1",
|
|
249
251
|
uuid: "f10b6d43",
|
|
252
|
+
subject: "main",
|
|
250
253
|
source: { offset: 180_420, bytes: 980 },
|
|
251
254
|
type: "tool:Bash",
|
|
252
255
|
at: FIXTURE_NOW - 3_400_000,
|
|
@@ -259,6 +262,7 @@ export const TRANSCRIPT_ITEMS: Static<typeof TranscriptItem>[] = [
|
|
|
259
262
|
{
|
|
260
263
|
id: "18d6f2c9:0",
|
|
261
264
|
uuid: "18d6f2c9",
|
|
265
|
+
subject: "main",
|
|
262
266
|
source: { offset: 181_400, bytes: 260 },
|
|
263
267
|
type: "tool:Bash",
|
|
264
268
|
at: FIXTURE_NOW - 3_399_000,
|
|
@@ -271,6 +275,7 @@ export const TRANSCRIPT_ITEMS: Static<typeof TranscriptItem>[] = [
|
|
|
271
275
|
{
|
|
272
276
|
id: "b7e41d09:0",
|
|
273
277
|
uuid: "b7e41d09",
|
|
278
|
+
subject: "main",
|
|
274
279
|
source: { offset: 181_660, bytes: 640 },
|
|
275
280
|
type: "message:sub:out",
|
|
276
281
|
at: FIXTURE_NOW - 3_300_000,
|
|
@@ -284,6 +289,7 @@ export const TRANSCRIPT_ITEMS: Static<typeof TranscriptItem>[] = [
|
|
|
284
289
|
{
|
|
285
290
|
id: "92e6d4f5:0",
|
|
286
291
|
uuid: "92e6d4f5",
|
|
292
|
+
subject: "main",
|
|
287
293
|
source: { offset: 182_300, bytes: 310 },
|
|
288
294
|
type: "hook:PreToolUse",
|
|
289
295
|
at: FIXTURE_NOW - 3_200_000,
|
|
@@ -295,6 +301,7 @@ export const TRANSCRIPT_ITEMS: Static<typeof TranscriptItem>[] = [
|
|
|
295
301
|
{
|
|
296
302
|
id: "81d5c3e4:0",
|
|
297
303
|
uuid: "81d5c3e4",
|
|
304
|
+
subject: "main",
|
|
298
305
|
source: { offset: 182_610, bytes: 190 },
|
|
299
306
|
type: "system:attachment:queued_command",
|
|
300
307
|
at: FIXTURE_NOW - 3_100_000,
|
|
@@ -303,6 +310,7 @@ export const TRANSCRIPT_ITEMS: Static<typeof TranscriptItem>[] = [
|
|
|
303
310
|
{
|
|
304
311
|
id: "c8a2f371:0",
|
|
305
312
|
uuid: "c8a2f371",
|
|
313
|
+
subject: "main",
|
|
306
314
|
source: { offset: 182_800, bytes: 520 },
|
|
307
315
|
type: "message:team:out",
|
|
308
316
|
at: FIXTURE_NOW - 3_000_000,
|
|
@@ -310,22 +318,24 @@ export const TRANSCRIPT_ITEMS: Static<typeof TranscriptItem>[] = [
|
|
|
310
318
|
result_item: "d4c1a0b2:0",
|
|
311
319
|
tool_use_id: "toolu_01Tm5XYp",
|
|
312
320
|
text: "契約に message:parent と message:team を足して",
|
|
313
|
-
|
|
321
|
+
harness_name: "contract-dump-items",
|
|
314
322
|
agent_id: "b83e0f114",
|
|
315
323
|
subagent_type: "opus5-worker-high",
|
|
316
324
|
},
|
|
317
325
|
{
|
|
318
326
|
id: "e5b70c93:0",
|
|
319
327
|
uuid: "e5b70c93",
|
|
328
|
+
subject: "main",
|
|
320
329
|
source: { offset: 183_320, bytes: 300 },
|
|
321
330
|
type: "message:team:in",
|
|
322
331
|
at: FIXTURE_NOW - 2_900_000,
|
|
323
332
|
text: "fixtures まで通ったので ci を回す",
|
|
324
|
-
|
|
333
|
+
harness_name: "contract-dump-items",
|
|
325
334
|
},
|
|
326
335
|
{
|
|
327
336
|
id: "d4c1a0b2:0",
|
|
328
337
|
uuid: "d4c1a0b2",
|
|
338
|
+
subject: "main",
|
|
329
339
|
source: { offset: 183_620, bytes: 410 },
|
|
330
340
|
type: "message:team:in",
|
|
331
341
|
at: FIXTURE_NOW - 2_800_000,
|
|
@@ -339,15 +349,18 @@ export const TRANSCRIPT_ITEMS: Static<typeof TranscriptItem>[] = [
|
|
|
339
349
|
},
|
|
340
350
|
];
|
|
341
351
|
|
|
342
|
-
/** The same vocabulary read with
|
|
352
|
+
/** The same vocabulary read with a throwaway agent as the subject.
|
|
343
353
|
*
|
|
344
354
|
* Nothing here is a new type: the brief an agent opens with and the answer it
|
|
345
355
|
* closes with are what `message:parent` names from wherever it is read, and the
|
|
346
|
-
* answer comes as prose with no call behind it.
|
|
356
|
+
* answer comes as prose with no call behind it. What says these were read from
|
|
357
|
+
* an errand's transcript rather than a session's is `subject`, which every item
|
|
358
|
+
* carries. */
|
|
347
359
|
export const TRANSCRIPT_ITEMS_AGENT_SUBJECT: Static<typeof TranscriptItem>[] = [
|
|
348
360
|
{
|
|
349
361
|
id: "a9f30d15:0",
|
|
350
362
|
uuid: "a9f30d15",
|
|
363
|
+
subject: "sub",
|
|
351
364
|
source: { offset: 0, bytes: 1_240 },
|
|
352
365
|
type: "message:parent:in",
|
|
353
366
|
at: FIXTURE_NOW - 3_290_000,
|
|
@@ -357,18 +370,20 @@ export const TRANSCRIPT_ITEMS_AGENT_SUBJECT: Static<typeof TranscriptItem>[] = [
|
|
|
357
370
|
{
|
|
358
371
|
id: "b0e41c26:0",
|
|
359
372
|
uuid: "b0e41c26",
|
|
373
|
+
subject: "sub",
|
|
360
374
|
source: { offset: 1_240, bytes: 380 },
|
|
361
375
|
type: "message:parent:out",
|
|
362
376
|
at: FIXTURE_NOW - 3_260_000,
|
|
363
377
|
role: "use",
|
|
364
378
|
tool_use_id: "toolu_01Qz8Vbn",
|
|
365
379
|
text: "型一覧は 4 群に分けた。preset の例まで直してよいか",
|
|
366
|
-
|
|
380
|
+
harness_name: "main",
|
|
367
381
|
summary: "型一覧の分け方を確認",
|
|
368
382
|
},
|
|
369
383
|
{
|
|
370
384
|
id: "c1f52d37:0",
|
|
371
385
|
uuid: "c1f52d37",
|
|
386
|
+
subject: "sub",
|
|
372
387
|
source: { offset: 1_620, bytes: 690 },
|
|
373
388
|
type: "message:parent:out",
|
|
374
389
|
at: FIXTURE_NOW - 3_200_000,
|
|
@@ -376,6 +391,57 @@ export const TRANSCRIPT_ITEMS_AGENT_SUBJECT: Static<typeof TranscriptItem>[] = [
|
|
|
376
391
|
},
|
|
377
392
|
];
|
|
378
393
|
|
|
394
|
+
/** The same vocabulary again, read with a teammate as the subject.
|
|
395
|
+
*
|
|
396
|
+
* A teammate stands where neither of the other two does: it answers a lead, as
|
|
397
|
+
* an errand does, and a person can also type at it directly, as a session's own
|
|
398
|
+
* transcript has. The relations are the ones already spelled out — what tells
|
|
399
|
+
* these apart from the errand's above is `subject`, and it is what makes the
|
|
400
|
+
* three columns of the table checkable against items. */
|
|
401
|
+
export const TRANSCRIPT_ITEMS_TEAM_SUBJECT: Static<typeof TranscriptItem>[] = [
|
|
402
|
+
{
|
|
403
|
+
id: "d2a63e48:0",
|
|
404
|
+
uuid: "d2a63e48",
|
|
405
|
+
subject: "team",
|
|
406
|
+
source: { offset: 0, bytes: 1_480 },
|
|
407
|
+
type: "message:parent:in",
|
|
408
|
+
at: FIXTURE_NOW - 3_000_000,
|
|
409
|
+
turn: 1,
|
|
410
|
+
text: "契約に message:parent と message:team を足して",
|
|
411
|
+
harness_name: "main",
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
id: "e3b74f59:0",
|
|
415
|
+
uuid: "e3b74f59",
|
|
416
|
+
subject: "team",
|
|
417
|
+
source: { offset: 1_480, bytes: 260 },
|
|
418
|
+
type: "message:user:in",
|
|
419
|
+
at: FIXTURE_NOW - 2_950_000,
|
|
420
|
+
text: "fixtures も忘れずに",
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
id: "f4c8506a:0",
|
|
424
|
+
uuid: "f4c8506a",
|
|
425
|
+
subject: "team",
|
|
426
|
+
source: { offset: 1_740, bytes: 340 },
|
|
427
|
+
type: "message:team:out",
|
|
428
|
+
at: FIXTURE_NOW - 2_920_000,
|
|
429
|
+
role: "use",
|
|
430
|
+
tool_use_id: "toolu_01Wc7Zdq",
|
|
431
|
+
text: "daemon 側の分類はどこまで進んでいる",
|
|
432
|
+
harness_name: "daemon-dump-items",
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
id: "a5d9617b:0",
|
|
436
|
+
uuid: "a5d9617b",
|
|
437
|
+
subject: "team",
|
|
438
|
+
source: { offset: 2_080, bytes: 410 },
|
|
439
|
+
type: "message:parent:out",
|
|
440
|
+
at: FIXTURE_NOW - 2_800_000,
|
|
441
|
+
text: "4 型を足して 1.17.0 を切った",
|
|
442
|
+
},
|
|
443
|
+
];
|
|
444
|
+
|
|
379
445
|
export const TRANSCRIPT_READ_REQUEST: Static<typeof TranscriptReadRequest> = {
|
|
380
446
|
request_id,
|
|
381
447
|
op: "transcript_read",
|