@ccmsg/protocol 1.14.0 → 1.16.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/attributes.ts +2 -2
- package/src/control/dump.ts +11 -6
- package/src/control/peers.ts +6 -5
- package/src/control/transcript.ts +9 -6
- package/src/errors.ts +9 -0
- package/src/fixtures/control.ts +2 -1
- package/src/fixtures/topics.ts +8 -0
package/package.json
CHANGED
package/src/attributes.ts
CHANGED
|
@@ -179,7 +179,7 @@ export const OP_ATTRIBUTES = {
|
|
|
179
179
|
roles: SESSION_ONLY,
|
|
180
180
|
needs_hello: true,
|
|
181
181
|
locality: "cluster",
|
|
182
|
-
errors: [],
|
|
182
|
+
errors: ["rate_limited"],
|
|
183
183
|
},
|
|
184
184
|
say_mark_read: {
|
|
185
185
|
plane: "messaging",
|
|
@@ -193,7 +193,7 @@ export const OP_ATTRIBUTES = {
|
|
|
193
193
|
roles: AGENT_AND_USER,
|
|
194
194
|
needs_hello: true,
|
|
195
195
|
locality: "cluster",
|
|
196
|
-
errors: [],
|
|
196
|
+
errors: ["rate_limited"],
|
|
197
197
|
},
|
|
198
198
|
|
|
199
199
|
// --- control: session observation and operation (10) ---
|
package/src/control/dump.ts
CHANGED
|
@@ -129,12 +129,21 @@ const USE_FIELDS = {
|
|
|
129
129
|
role: Type.Literal("use"),
|
|
130
130
|
/** The result's id, once there is one. */
|
|
131
131
|
result_item: Type.Optional(TranscriptItemId),
|
|
132
|
+
/** The harness's own key for this call, which the result names back. */
|
|
133
|
+
tool_use_id: Type.String(),
|
|
132
134
|
};
|
|
133
135
|
|
|
134
136
|
const RESULT_FIELDS = {
|
|
135
137
|
role: Type.Literal("result"),
|
|
136
|
-
/** The call this answers
|
|
137
|
-
|
|
138
|
+
/** The call this answers, when the reader saw it. A read that begins in the
|
|
139
|
+
* middle of a file — a topic's seed, a transcript resumed from another file —
|
|
140
|
+
* meets results whose call is behind where it started, and an id it never
|
|
141
|
+
* read is one it cannot name. */
|
|
142
|
+
parent_item: Type.Optional(TranscriptItemId),
|
|
143
|
+
/** The harness's key for the call this answers, which the record carries
|
|
144
|
+
* whether or not the call was read. A reader that has no `parent_item` joins
|
|
145
|
+
* on this against the `tool_use_id` of the calls it holds. */
|
|
146
|
+
parent_tool_use_id: Type.String(),
|
|
138
147
|
};
|
|
139
148
|
|
|
140
149
|
function item<T extends TSchema, F extends Record<string, TSchema>>(type: T, fields: F) {
|
|
@@ -259,7 +268,6 @@ const ToolType = Type.String({ pattern: "^tool:[A-Za-z0-9_.-]+$" });
|
|
|
259
268
|
function toolUse<N extends string, F extends Record<string, TSchema>>(name: N, fields: F) {
|
|
260
269
|
return item(Type.Literal(`tool:${name}` as const), {
|
|
261
270
|
...USE_FIELDS,
|
|
262
|
-
tool_use_id: Type.String(),
|
|
263
271
|
...fields,
|
|
264
272
|
});
|
|
265
273
|
}
|
|
@@ -267,7 +275,6 @@ function toolUse<N extends string, F extends Record<string, TSchema>>(name: N, f
|
|
|
267
275
|
function toolResult<N extends string, F extends Record<string, TSchema>>(name: N, fields: F) {
|
|
268
276
|
return item(Type.Literal(`tool:${name}` as const), {
|
|
269
277
|
...RESULT_FIELDS,
|
|
270
|
-
tool_use_id: Type.String(),
|
|
271
278
|
...fields,
|
|
272
279
|
});
|
|
273
280
|
}
|
|
@@ -280,12 +287,10 @@ const OptCount = Type.Optional(Type.Integer({ minimum: 0 }));
|
|
|
280
287
|
* to decide whether it is kept. */
|
|
281
288
|
const ToolUseGeneric = item(ToolType, {
|
|
282
289
|
...USE_FIELDS,
|
|
283
|
-
tool_use_id: Type.String(),
|
|
284
290
|
input: Type.Record(Type.String(), Type.Unknown()),
|
|
285
291
|
});
|
|
286
292
|
const ToolResultGeneric = item(ToolType, {
|
|
287
293
|
...RESULT_FIELDS,
|
|
288
|
-
tool_use_id: Type.String(),
|
|
289
294
|
result: Type.Record(Type.String(), Type.Unknown()),
|
|
290
295
|
});
|
|
291
296
|
|
package/src/control/peers.ts
CHANGED
|
@@ -57,7 +57,7 @@ export const StaleClientInfo = Type.Object(
|
|
|
57
57
|
);
|
|
58
58
|
export type StaleClientInfo = Static<typeof StaleClientInfo>;
|
|
59
59
|
|
|
60
|
-
/** One connected
|
|
60
|
+
/** One session an instance can call live (connected or not).
|
|
61
61
|
*
|
|
62
62
|
* The paths are the host's, so the entry names the instance holding them:
|
|
63
63
|
* `peers` carries every instance's sessions in one list, and two hosts' paths
|
|
@@ -122,10 +122,11 @@ export const PeerInfo = Type.Object(
|
|
|
122
122
|
send_message: Type.Optional(Type.Boolean()),
|
|
123
123
|
/** The build of the client that last greeted for this session. */
|
|
124
124
|
client_version: Type.Optional(Type.String()),
|
|
125
|
-
/** The generation
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
|
|
125
|
+
/** The generation the connected client speaks. Absent from a row that has
|
|
126
|
+
* no connection to read one from — the instance's state file names such a
|
|
127
|
+
* session live without any client ever having greeted it, so there is no
|
|
128
|
+
* generation to state. */
|
|
129
|
+
protocol_version: Type.Optional(Type.Integer({ minimum: 1 })),
|
|
129
130
|
/** Set while some client of this session is being refused. */
|
|
130
131
|
stale_client: Type.Optional(StaleClientInfo),
|
|
131
132
|
},
|
|
@@ -62,10 +62,13 @@ export const TranscriptReadResponse = response("transcript_read", TranscriptRead
|
|
|
62
62
|
*
|
|
63
63
|
* The range is cut the way a dump's is — an instant or a record on either side
|
|
64
64
|
* — and which end of it a limit keeps follows from which bound was given. A
|
|
65
|
-
* lower bound reads forward from it and `next` names the continuation;
|
|
66
|
-
*
|
|
67
|
-
* backwards, which is how a client that draws the newest items
|
|
68
|
-
* through a transcript it never has to read whole.
|
|
65
|
+
* lower bound reads forward from it and `next` names the continuation;
|
|
66
|
+
* otherwise the read answers the range's last items and `prev` names the
|
|
67
|
+
* continuation backwards, which is how a client that draws the newest items
|
|
68
|
+
* first walks back through a transcript it never has to read whole. Asking
|
|
69
|
+
* with no bound at all is the ordinary first read, and it answers the tail, as
|
|
70
|
+
* the raw read with no `before` does; a client that wants the transcript from
|
|
71
|
+
* its beginning says so with `since_at: 0`. The role decides how much is
|
|
69
72
|
* visible, as it does for the raw read. */
|
|
70
73
|
export const TranscriptItemsReadArgs = Type.Object({
|
|
71
74
|
sid: Sid,
|
|
@@ -90,8 +93,8 @@ export const TranscriptItemsReadArgs = Type.Object({
|
|
|
90
93
|
* but the attachments, as a dump's absent selection does. */
|
|
91
94
|
types: Type.Optional(Type.Array(TranscriptItemSelector)),
|
|
92
95
|
/** How many items to answer with, taken from the range's start when a lower
|
|
93
|
-
* bound was given and from its end
|
|
94
|
-
*
|
|
96
|
+
* bound was given and from its end otherwise; the instance narrows this to
|
|
97
|
+
* its own limit. */
|
|
95
98
|
limit: Type.Optional(Type.Integer({ minimum: 1 })),
|
|
96
99
|
});
|
|
97
100
|
export type TranscriptItemsReadArgs = Static<typeof TranscriptItemsReadArgs>;
|
package/src/errors.ts
CHANGED
|
@@ -18,6 +18,15 @@ export const ERROR_CODES = [
|
|
|
18
18
|
* arguments that were never the problem. Whether retrying helps is not stated;
|
|
19
19
|
* `msg` is the only thing that says more. */
|
|
20
20
|
"internal_error",
|
|
21
|
+
// --- backpressure ---
|
|
22
|
+
/** The call was well-formed and allowed, and the instance is not taking it
|
|
23
|
+
* just now: what it would be queued behind has reached the limit the sender
|
|
24
|
+
* keeps to. Apart from `internal_error` because nothing failed and the
|
|
25
|
+
* arguments are not what to re-read — the same call sent again once the
|
|
26
|
+
* reader has caught up is the one that goes through. Which ops answer it is
|
|
27
|
+
* in their `errors`, since only an op that queues for a reader has a queue to
|
|
28
|
+
* fill. */
|
|
29
|
+
"rate_limited",
|
|
21
30
|
// --- rule-derived (op attribute table §0) ---
|
|
22
31
|
/** The connection's role is outside the op's `roles`. Argument problems stay
|
|
23
32
|
* on `invalid_args` / `bad_request`. */
|
package/src/fixtures/control.ts
CHANGED
|
@@ -261,8 +261,8 @@ export const TRANSCRIPT_ITEMS: Static<typeof TranscriptItem>[] = [
|
|
|
261
261
|
type: "tool:Bash",
|
|
262
262
|
at: FIXTURE_NOW - 3_399_000,
|
|
263
263
|
role: "result",
|
|
264
|
-
tool_use_id: "toolu_01Ne9BDS",
|
|
265
264
|
parent_item: "f10b6d43:1",
|
|
265
|
+
parent_tool_use_id: "toolu_01Ne9BDS",
|
|
266
266
|
stdout: "1174 assistant\n753 user\n",
|
|
267
267
|
interrupted: false,
|
|
268
268
|
},
|
|
@@ -274,6 +274,7 @@ export const TRANSCRIPT_ITEMS: Static<typeof TranscriptItem>[] = [
|
|
|
274
274
|
at: FIXTURE_NOW - 3_300_000,
|
|
275
275
|
role: "use",
|
|
276
276
|
result_item: "c2d80f16:0",
|
|
277
|
+
tool_use_id: "toolu_01Rk4WQm",
|
|
277
278
|
prompt: "docs/design/dump-kinds.md を書き直す",
|
|
278
279
|
agent_id: "a471372f2",
|
|
279
280
|
subagent_type: "opus5-worker-high",
|
package/src/fixtures/topics.ts
CHANGED
|
@@ -88,6 +88,14 @@ export const PEERS_FRAME: Static<typeof PeersFrame> = {
|
|
|
88
88
|
protocol_version: 2,
|
|
89
89
|
},
|
|
90
90
|
},
|
|
91
|
+
{
|
|
92
|
+
sid: "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
|
|
93
|
+
instance,
|
|
94
|
+
repo: "ccmsg",
|
|
95
|
+
ws: "daemon-v2",
|
|
96
|
+
cwd: "/repos/kawaz/ccmsg/daemon-v2",
|
|
97
|
+
state: "live_unmanaged",
|
|
98
|
+
},
|
|
91
99
|
],
|
|
92
100
|
last_live: [
|
|
93
101
|
{
|