@llm4ts/core 2.40.0 → 2.41.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.
@@ -2,6 +2,16 @@ import { type CliConnectorShape } from "../Connector.ts";
2
2
  import type { CliConnectorConfig } from "../ConnectorConfig.ts";
3
3
  import { LlmChunk } from "../Models.ts";
4
4
  import type { ProcessExecutorShape } from "../ProcessExecutor.ts";
5
+ /**
6
+ * The first pi whose `--tools` allowlist can be kept free of MCP tools: from
7
+ * 1.0.4 `--tools read` keeps every MCP tool the user configured in
8
+ * `~/.pi/agent/mcp.json` unless `--no-mcp` (new in that release) drops them,
9
+ * and MCP tools are built in since 0.99.0. Below this a read-only seat can
10
+ * reach any MCP write tool, so llm4ts refuses it (ADR 0010, ADR 0035).
11
+ */
12
+ export declare const piReadOnlyFloor = "1.0.4";
13
+ /** Why this pi cannot hold a read-only seat, or nothing when it can. */
14
+ export declare const piReadOnlyProblem: (versionText: string) => string | undefined;
5
15
  export declare const piExtraArgs: (config: CliConnectorConfig) => ReadonlyArray<string>;
6
16
  export declare const parsePiStreamLine: (line: string) => ReadonlyArray<LlmChunk>;
7
17
  export declare const makePiConnector: (config: CliConnectorConfig, executor: ProcessExecutorShape) => CliConnectorShape;
@@ -1 +1 @@
1
- {"version":3,"file":"PiConnector.d.ts","sourceRoot":"","sources":["../../src/providers/PiConnector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAE/D,OAAO,EAAuC,QAAQ,EAAc,MAAM,cAAc,CAAA;AACxF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAkBjE,eAAO,MAAM,WAAW,GAAI,QAAQ,kBAAkB,KAAG,aAAa,CAAC,MAAM,CAc5E,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,KAAG,aAAa,CAAC,QAAQ,CA2FtE,CAAA;AAED,eAAO,MAAM,eAAe,GAC1B,QAAQ,kBAAkB,EAC1B,UAAU,oBAAoB,KAC7B,iBAgEF,CAAA"}
1
+ {"version":3,"file":"PiConnector.d.ts","sourceRoot":"","sources":["../../src/providers/PiConnector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAE/D,OAAO,EAAuC,QAAQ,EAAc,MAAM,cAAc,CAAA;AACxF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAqBjE;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,UAAU,CAAA;AAEtC,wEAAwE;AACxE,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,KAAG,MAAM,GAAG,SAchE,CAAA;AAMD,eAAO,MAAM,WAAW,GAAI,QAAQ,kBAAkB,KAAG,aAAa,CAAC,MAAM,CAwB5E,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,KAAG,aAAa,CAAC,QAAQ,CAgHtE,CAAA;AAED,eAAO,MAAM,eAAe,GAC1B,QAAQ,kBAAkB,EAC1B,UAAU,oBAAoB,KAC7B,iBAwFF,CAAA"}
@@ -1,9 +1,33 @@
1
1
  import * as Effect from "effect/Effect";
2
2
  import * as Stream from "effect/Stream";
3
3
  import { makeCliConnector } from "../Connector.js";
4
- import { ProviderError } from "../Errors.js";
4
+ import { InvalidRequestError, ProviderError } from "../Errors.js";
5
5
  import { ConnectorCapabilities, ConnectorIds, LlmChunk, TokenUsage } from "../Models.js";
6
- import { effortWord, cumulativeUsage, failClassifiedCliError, jsonBooleanField, jsonField, jsonIntField, jsonStringField, optionalModelArgs, parseJsonLine, sortedFlagArgs, toolEventChunk, toolResultChunk, toolResultText, usageEventChunk } from "./CliSupport.js";
6
+ import { atLeastVersion, effortWord, cumulativeUsage, failClassifiedCliError, jsonBooleanField, jsonField, jsonIntField, jsonStringField, optionalModelArgs, parseJsonLine, sortedFlagArgs, toolEventChunk, toolResultChunk, toolResultText, usageEventChunk, versionTriple, statusChunk } from "./CliSupport.js";
7
+ /**
8
+ * The first pi whose `--tools` allowlist can be kept free of MCP tools: from
9
+ * 1.0.4 `--tools read` keeps every MCP tool the user configured in
10
+ * `~/.pi/agent/mcp.json` unless `--no-mcp` (new in that release) drops them,
11
+ * and MCP tools are built in since 0.99.0. Below this a read-only seat can
12
+ * reach any MCP write tool, so llm4ts refuses it (ADR 0010, ADR 0035).
13
+ */
14
+ export const piReadOnlyFloor = "1.0.4";
15
+ /** Why this pi cannot hold a read-only seat, or nothing when it can. */
16
+ export const piReadOnlyProblem = (versionText) => {
17
+ const version = versionTriple(versionText);
18
+ const floor = versionTriple(piReadOnlyFloor) ?? [];
19
+ if (version === undefined) {
20
+ return (`could not read the pi version from '${versionText.trim()}'; a read-only seat needs ` +
21
+ `pi >= ${piReadOnlyFloor}, whose --no-mcp keeps MCP tools out of the read allowlist`);
22
+ }
23
+ return atLeastVersion(version, floor)
24
+ ? undefined
25
+ : `pi ${version.join(".")} cannot enforce a read-only seat: --tools read keeps MCP tools ` +
26
+ `until --no-mcp arrived in ${piReadOnlyFloor}; upgrade pi, or give the judge and ` +
27
+ "reviewer seats to another harness";
28
+ };
29
+ /** The provider half of pi's `provider/model[:thinking]` model id. */
30
+ const providerOf = (model) => model === undefined ? undefined : model.split("/", 1)[0];
7
31
  export const piExtraArgs = (config) => [
8
32
  ...optionalModelArgs(config.model),
9
33
  // `noTools` takes precedence over `readOnly`: `--no-tools` disables tool
@@ -11,12 +35,22 @@ export const piExtraArgs = (config) => [
11
35
  // offers a read tool the model can invoke — fine for an interactive
12
36
  // session, unsafe for a one-shot complete() call with no tool-loop
13
37
  // continuation (see the field's doc comment on CliConnectorConfig).
14
- ...(config.noTools ? ["--no-tools"] : config.readOnly ? ["--tools", "read"] : []),
38
+ // `--no-tools` also drops MCP tools; `--tools read` keeps them (pi >= 1.0.4),
39
+ // so a read-only seat adds `--no-mcp` (ADR 0035).
40
+ ...(config.noTools ? ["--no-tools"] : config.readOnly ? ["--tools", "read", "--no-mcp"] : []),
15
41
  // `--thinking` is pi's effort flag (off, minimal, low, medium, high, xhigh).
16
42
  ...(config.effort === undefined ? [] : ["--thinking", effortWord(config.effort, "xhigh")]),
17
43
  // Isolation is partial (ADR 0029): project extensions and skills stay
18
44
  // out; pi still reads AGENTS.md from the working directory and its parents.
19
- ...(config.isolated ? ["--no-extensions", "--no-skills"] : []),
45
+ // `--no-extensions` also drops the built-in llama.cpp provider (pi >=
46
+ // 0.99.0), so a local model on it is re-enabled by name.
47
+ ...(config.isolated
48
+ ? [
49
+ "--no-extensions",
50
+ "--no-skills",
51
+ ...(providerOf(config.model) === "llama.cpp" ? ["-e", "builtin:llama.cpp"] : [])
52
+ ]
53
+ : []),
20
54
  ...sortedFlagArgs(config.flags)
21
55
  ];
22
56
  export const parsePiStreamLine = (line) => {
@@ -32,23 +66,35 @@ export const parsePiStreamLine = (line) => {
32
66
  : undefined;
33
67
  return delta === undefined || delta.length === 0 ? [] : [LlmChunk.make({ delta })];
34
68
  }
35
- case "tool_execution_start":
69
+ // A call nested in another (codemode) names its parent (ADR 0033).
70
+ case "tool_execution_start": {
71
+ const parent = jsonStringField(json, "parentToolCallId");
36
72
  return [
37
- toolEventChunk(jsonStringField(json, "toolName") ?? "", jsonField(json, "args"), jsonStringField(json, "toolCallId"))
73
+ toolEventChunk(jsonStringField(json, "toolName") ?? "", jsonField(json, "args"), jsonStringField(json, "toolCallId"), parent === undefined ? {} : { parent })
38
74
  ];
39
- case "tool_execution_end":
75
+ }
76
+ case "tool_execution_end": {
77
+ const parent = jsonStringField(json, "parentToolCallId");
78
+ const durationMs = jsonIntField(json, "durationMs");
40
79
  return [
41
80
  toolResultChunk(jsonStringField(json, "toolCallId"), {
42
81
  failed: jsonField(json, "isError") === true,
82
+ ...(parent === undefined ? {} : { parent }),
83
+ ...(durationMs === undefined ? {} : { durationMs }),
43
84
  ...(() => {
44
85
  const output = toolResultText(jsonField(jsonField(json, "result"), "content"));
45
86
  return output === undefined ? {} : { output };
46
87
  })()
47
88
  })
48
89
  ];
90
+ }
49
91
  case "message_end":
50
92
  case "agent_end": {
51
93
  const message = jsonField(json, "message");
94
+ // An aborted turn (a signal, a steer) is not a reply either.
95
+ if (jsonStringField(message, "stopReason") === "aborted") {
96
+ return [LlmChunk.make({ delta: "", metadata: { piError: "pi aborted the turn" } })];
97
+ }
52
98
  // pi reports a provider refusal (a usage limit, an auth failure) as an
53
99
  // assistant message that stopped with an error and exits 0; without
54
100
  // this it reads as an empty, successful reply.
@@ -78,6 +124,10 @@ export const parsePiStreamLine = (line) => {
78
124
  }))
79
125
  ];
80
126
  }
127
+ // A provider retry and a context compaction pause the turn: the lane
128
+ // says so instead of looking stuck (ADR 0033).
129
+ case "auto_retry_start":
130
+ return [statusChunk("retrying", "start", jsonStringField(json, "errorMessage"))];
81
131
  case "auto_retry_end":
82
132
  return jsonBooleanField(json, "success") === false
83
133
  ? [
@@ -88,7 +138,11 @@ export const parsePiStreamLine = (line) => {
88
138
  }
89
139
  })
90
140
  ]
91
- : [];
141
+ : [statusChunk("retrying", "end")];
142
+ case "compaction_start":
143
+ return [statusChunk("compacting", "start")];
144
+ case "compaction_end":
145
+ return [statusChunk("compacting", "end")];
92
146
  case "extension_error":
93
147
  return [
94
148
  LlmChunk.make({
@@ -105,7 +159,22 @@ export const parsePiStreamLine = (line) => {
105
159
  export const makePiConnector = (config, executor) => {
106
160
  const cwd = config.workingDir ?? ".";
107
161
  const extraArgs = piExtraArgs(config);
162
+ // A read-only seat is only taken on a pi whose read allowlist can exclude
163
+ // MCP tools (`piReadOnlyFloor`): the version answer decides before the
164
+ // first turn, once per connector; a failed probe is retried on the next.
165
+ let floorChecked = !config.readOnly;
166
+ const checkFloorOnce = Effect.suspend(() => floorChecked
167
+ ? Effect.void
168
+ : Effect.flatMap(executor.run(["pi", "--version"], cwd, config.envVars), (result) => {
169
+ const problem = piReadOnlyProblem([...result.stdout, ...result.stderr].join("\n"));
170
+ return problem === undefined
171
+ ? Effect.sync(() => {
172
+ floorChecked = true;
173
+ })
174
+ : Effect.fail(InvalidRequestError.make({ message: problem }));
175
+ }));
108
176
  const complete = Effect.fn("@llm4ts/core/providers/PiConnector.complete")(function* (prompt) {
177
+ yield* checkFloorOnce;
109
178
  const result = yield* executor.runWithStdin(["pi", "-p", ...extraArgs], cwd, config.envVars, prompt);
110
179
  if (result.exitCode !== 0) {
111
180
  // pi explains a refusal on stderr (a usage error, a missing model, an
@@ -119,9 +188,7 @@ export const makePiConnector = (config, executor) => {
119
188
  }
120
189
  return result.stdout.join("\n");
121
190
  });
122
- const completeStream = (prompt) => executor
123
- .runStreamingWithStdin(["pi", "-p", "--mode", "json", ...extraArgs], cwd, config.envVars, prompt)
124
- .pipe(Stream.flatMap((line) => Stream.fromIterable(parsePiStreamLine(line))),
191
+ const completeStream = (prompt) => Stream.fromEffect(checkFloorOnce).pipe(Stream.drain, Stream.concat(executor.runStreamingWithStdin(["pi", "-p", "--mode", "json", ...extraArgs], cwd, config.envVars, prompt)), Stream.flatMap((line) => Stream.fromIterable(parsePiStreamLine(line))),
125
192
  // pi reports usage per assistant message; a turn is all of them.
126
193
  cumulativeUsage, Stream.mapEffect((chunk) => {
127
194
  const message = chunk.metadata.piError;
@@ -135,13 +202,17 @@ export const makePiConnector = (config, executor) => {
135
202
  // `--tools read` is pi's documented comma-separated ALLOWLIST of tool
136
203
  // names: only `read` is enabled, so bash/edit/write are absent — a real
137
204
  // capability removal, the same mechanism class as claude's `--tools`.
205
+ // `--no-mcp` keeps MCP tools out of it, and `checkFloorOnce` refuses a
206
+ // read-only seat on a pi without that flag, so the grade holds.
138
207
  capabilities: ConnectorCapabilities.make({
139
208
  interactiveSessions: true,
140
209
  readOnlyEnforcement: "enforced",
141
210
  effort: "mapped",
142
211
  isolatedHeadless: "partial"
143
212
  }),
144
- buildArgv: (prompt, _context) => ["pi", "-p", ...extraArgs, prompt],
213
+ // `--` ends the options (pi >= 0.84.3): a prompt starting with a dash
214
+ // is a prompt, not a flag. Stdin paths need no separator.
215
+ buildArgv: (prompt, _context) => ["pi", "-p", ...extraArgs, "--", prompt],
145
216
  buildInteractiveArgv: (_context) => ["pi", ...extraArgs],
146
217
  complete,
147
218
  completeStream,
@@ -1 +1 @@
1
- {"version":3,"file":"PiConnector.js","sourceRoot":"","sources":["../../src/providers/PiConnector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PiConnector.js","sourceRoot":"","sources":["../../src/providers/PiConnector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAA0B,MAAM,iBAAiB,CAAA;AAE1E,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAiB,MAAM,cAAc,CAAA;AAChF,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAExF,OAAO,EACL,cAAc,EACd,UAAU,EACV,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,EACf,aAAa,EACb,WAAW,EACZ,MAAM,iBAAiB,CAAA;AAExB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAA;AAEtC,wEAAwE;AACxE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,WAAmB,EAAsB,EAAE;IAC3E,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,CAAC,CAAA;IAC1C,MAAM,KAAK,GAAG,aAAa,CAAC,eAAe,CAAC,IAAI,EAAE,CAAA;IAClD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,CACL,uCAAuC,WAAW,CAAC,IAAI,EAAE,4BAA4B;YACrF,SAAS,eAAe,4DAA4D,CACrF,CAAA;IACH,CAAC;IACD,OAAO,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC;QACnC,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,iEAAiE;YACtF,6BAA6B,eAAe,sCAAsC;YAClF,mCAAmC,CAAA;AAC3C,CAAC,CAAA;AAED,sEAAsE;AACtE,MAAM,UAAU,GAAG,CAAC,KAAyB,EAAsB,EAAE,CACnE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAE1D,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAA0B,EAAyB,EAAE,CAAC;IAChF,GAAG,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC;IAClC,yEAAyE;IACzE,uEAAuE;IACvE,oEAAoE;IACpE,mEAAmE;IACnE,oEAAoE;IACpE,8EAA8E;IAC9E,kDAAkD;IAClD,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7F,6EAA6E;IAC7E,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1F,sEAAsE;IACtE,4EAA4E;IAC5E,sEAAsE;IACtE,yDAAyD;IACzD,GAAG,CAAC,MAAM,CAAC,QAAQ;QACjB,CAAC,CAAC;YACE,iBAAiB;YACjB,aAAa;YACb,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SACjF;QACH,CAAC,CAAC,EAAE,CAAC;IACP,GAAG,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC;CAChC,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAA2B,EAAE;IACzE,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;IAChC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,CAAA;IACX,CAAC;IAED,QAAQ,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;QACtC,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAA;YACtD,MAAM,KAAK,GACT,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,YAAY;gBAC7C,CAAC,CAAC,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC;gBACjC,CAAC,CAAC,SAAS,CAAA;YACf,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;QACpF,CAAC;QACD,mEAAmE;QACnE,KAAK,sBAAsB,CAAC,CAAC,CAAC;YAC5B,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAA;YACxD,OAAO;gBACL,cAAc,CACZ,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,EACvC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,EACvB,eAAe,CAAC,IAAI,EAAE,YAAY,CAAC,EACnC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CACvC;aACF,CAAA;QACH,CAAC;QACD,KAAK,oBAAoB,CAAC,CAAC,CAAC;YAC1B,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAA;YACxD,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;YACnD,OAAO;gBACL,eAAe,CAAC,eAAe,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE;oBACnD,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,IAAI;oBAC3C,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;oBAC3C,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC;oBACnD,GAAG,CAAC,GAAG,EAAE;wBACP,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC,CAAA;wBAC9E,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAA;oBAC/C,CAAC,CAAC,EAAE;iBACL,CAAC;aACH,CAAA;QACH,CAAC;QACD,KAAK,aAAa,CAAC;QACnB,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;YAC1C,6DAA6D;YAC7D,IAAI,eAAe,CAAC,OAAO,EAAE,YAAY,CAAC,KAAK,SAAS,EAAE,CAAC;gBACzD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,qBAAqB,EAAE,EAAE,CAAC,CAAC,CAAA;YACrF,CAAC;YACD,uEAAuE;YACvE,oEAAoE;YACpE,+CAA+C;YAC/C,IAAI,eAAe,CAAC,OAAO,EAAE,YAAY,CAAC,KAAK,OAAO,EAAE,CAAC;gBACvD,OAAO;oBACL,QAAQ,CAAC,IAAI,CAAC;wBACZ,KAAK,EAAE,EAAE;wBACT,QAAQ,EAAE;4BACR,OAAO,EAAE,eAAe,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,0BAA0B;yBAChF;qBACF,CAAC;iBACH,CAAA;YACH,CAAC;YACD,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YACzC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,OAAO,EAAE,CAAA;YACX,CAAC;YACD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;YAChD,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;YACrD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;YAC/C,OAAO;gBACL,eAAe,CACb,SAAS,EACT,UAAU,CAAC,IAAI,CAAC;oBACd,MAAM;oBACN,UAAU;oBACV,KAAK,EAAE,MAAM,GAAG,UAAU;oBAC1B,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;iBAC5D,CAAC,CACH;aACF,CAAA;QACH,CAAC;QACD,qEAAqE;QACrE,+CAA+C;QAC/C,KAAK,kBAAkB;YACrB,OAAO,CAAC,WAAW,CAAC,UAAU,EAAE,OAAO,EAAE,eAAe,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,CAAA;QAClF,KAAK,gBAAgB;YACnB,OAAO,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,KAAK;gBAChD,CAAC,CAAC;oBACE,QAAQ,CAAC,IAAI,CAAC;wBACZ,KAAK,EAAE,EAAE;wBACT,QAAQ,EAAE;4BACR,OAAO,EAAE,eAAe,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,iBAAiB;yBAClE;qBACF,CAAC;iBACH;gBACH,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAA;QACtC,KAAK,kBAAkB;YACrB,OAAO,CAAC,WAAW,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAA;QAC7C,KAAK,gBAAgB;YACnB,OAAO,CAAC,WAAW,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAA;QAC3C,KAAK,iBAAiB;YACpB,OAAO;gBACL,QAAQ,CAAC,IAAI,CAAC;oBACZ,KAAK,EAAE,EAAE;oBACT,QAAQ,EAAE;wBACR,OAAO,EAAE,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,oBAAoB;qBAChE;iBACF,CAAC;aACH,CAAA;QACH;YACE,OAAO,EAAE,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,MAA0B,EAC1B,QAA8B,EACX,EAAE;IACrB,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,IAAI,GAAG,CAAA;IACpC,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;IAErC,0EAA0E;IAC1E,uEAAuE;IACvE,yEAAyE;IACzE,IAAI,YAAY,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAA;IACnC,MAAM,cAAc,GAAkC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CACxE,YAAY;QACV,CAAC,CAAC,MAAM,CAAC,IAAI;QACb,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE;YAChF,MAAM,OAAO,GAAG,iBAAiB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;YAClF,OAAO,OAAO,KAAK,SAAS;gBAC1B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;oBACf,YAAY,GAAG,IAAI,CAAA;gBACrB,CAAC,CAAC;gBACJ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;QACjE,CAAC,CAAC,CACP,CAAA;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC,6CAA6C,CAAC,CAAC,QAAQ,CAAC,EACjF,MAAc;QAEd,KAAK,CAAC,CAAC,cAAc,CAAA;QACrB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,YAAY,CACzC,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC,EAC1B,GAAG,EACH,MAAM,CAAC,OAAO,EACd,MAAM,CACP,CAAA;QACD,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,sEAAsE;YACtE,qEAAqE;YACrE,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA;YACrE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,KAAK,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,uBAAuB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;YACzF,CAAC;YACD,+EAA+E;YAC/E,OAAO,KAAK,CAAC,CAAC,sBAAsB,CAAC,IAAI,EAAE,uBAAuB,MAAM,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAA;QAC9F,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACjC,CAAC,CAAC,CAAA;IAEF,MAAM,cAAc,GAAG,CAAC,MAAc,EAAE,EAAE,CACxC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,IAAI,CACpC,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,MAAM,CACX,QAAQ,CAAC,qBAAqB,CAC5B,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,EAC5C,GAAG,EACH,MAAM,CAAC,OAAO,EACd,MAAM,CACP,CACF,EACD,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;IACtE,iEAAiE;IACjE,eAAe,EACf,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;QACzB,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAA;QACtC,OAAO,OAAO,KAAK,SAAS;YAC1B,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;YACvB,CAAC,CAAC,sBAAsB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;IACvD,CAAC,CAAC,CACH,CAAA;IAEH,OAAO,gBAAgB,CAAC;QACtB,EAAE,EAAE,YAAY,CAAC,EAAE;QACnB,kBAAkB,EAAE,kBAAkB;QACtC,sEAAsE;QACtE,wEAAwE;QACxE,sEAAsE;QACtE,uEAAuE;QACvE,gEAAgE;QAChE,YAAY,EAAE,qBAAqB,CAAC,IAAI,CAAC;YACvC,mBAAmB,EAAE,IAAI;YACzB,mBAAmB,EAAE,UAAU;YAC/B,MAAM,EAAE,QAAQ;YAChB,gBAAgB,EAAE,SAAS;SAC5B,CAAC;QACF,sEAAsE;QACtE,0DAA0D;QAC1D,SAAS,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC;QACzE,oBAAoB,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC;QACxD,QAAQ;QACR,cAAc;QACd,YAAY,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE;KAC9C,CAAC,CAAA;AACJ,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llm4ts/core",
3
- "version": "2.40.0",
3
+ "version": "2.41.0",
4
4
  "description": "Effect-native LLM contracts, providers, tools, evaluation, and observability",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -31,7 +31,8 @@ import {
31
31
  toolResultText,
32
32
  usageEventChunk,
33
33
  type JsonValue,
34
- effortWord
34
+ effortWord,
35
+ jsonObjectEntries
35
36
  } from "./CliSupport.ts"
36
37
 
37
38
  /**
@@ -93,6 +94,9 @@ export const parseClaudeCliStreamLine = (line: string): ReadonlyArray<LlmChunk>
93
94
  return []
94
95
  }
95
96
 
97
+ // A sub-agent's lines carry the id of the Agent call that spawned it (ADR 0033).
98
+ const parentId = jsonStringField(json, "parent_tool_use_id")
99
+ const parent = parentId === undefined || parentId.length === 0 ? {} : { parent: parentId }
96
100
  switch (jsonStringField(json, "type")) {
97
101
  case "assistant":
98
102
  return jsonArray(jsonField(jsonField(json, "message"), "content")).flatMap(
@@ -107,7 +111,8 @@ export const parseClaudeCliStreamLine = (line: string): ReadonlyArray<LlmChunk>
107
111
  toolEventChunk(
108
112
  jsonStringField(block, "name") ?? "",
109
113
  jsonField(block, "input"),
110
- jsonStringField(block, "id")
114
+ jsonStringField(block, "id"),
115
+ parent
111
116
  )
112
117
  ]
113
118
  default:
@@ -123,6 +128,7 @@ export const parseClaudeCliStreamLine = (line: string): ReadonlyArray<LlmChunk>
123
128
  ? [
124
129
  toolResultChunk(jsonStringField(block, "tool_use_id"), {
125
130
  failed: jsonField(block, "is_error") === true,
131
+ ...parent,
126
132
  ...outputOf(jsonField(block, "content"))
127
133
  })
128
134
  ]
@@ -133,21 +139,38 @@ export const parseClaudeCliStreamLine = (line: string): ReadonlyArray<LlmChunk>
133
139
  if (usage === undefined) {
134
140
  return []
135
141
  }
136
- const prompt = jsonIntField(usage, "input_tokens") ?? 0
137
- const completion = jsonIntField(usage, "output_tokens") ?? 0
138
- const cached = jsonIntField(usage, "cache_read_input_tokens")
139
142
  // The CLI reports its own exact cost on the result event; carry it so
140
143
  // trackers prefer it over pricing-table estimates. modelUsage's key is
141
- // a model-name fallback for when no init line was observed.
144
+ // a model-name fallback for when no init line was observed, and its
145
+ // per-model counts include the sub-agents' turns, which `usage` leaves
146
+ // out (ADR 0033): sum them when they are there.
142
147
  const costUsd = jsonNumberField(json, "total_cost_usd")
143
- const modelUsage = jsonField(json, "modelUsage")
144
- const modelNames =
145
- modelUsage !== undefined &&
146
- modelUsage !== null &&
147
- typeof modelUsage === "object" &&
148
- !Array.isArray(modelUsage)
149
- ? Object.keys(modelUsage)
150
- : []
148
+ const modelNames = jsonObjectEntries(jsonField(json, "modelUsage")).map(([name]) => name)
149
+ // Only entries that count tokens can replace `usage`; a key-only
150
+ // modelUsage (older CLIs, fixtures) still names the model.
151
+ const perModel = jsonObjectEntries(jsonField(json, "modelUsage")).filter(
152
+ ([, entry]) =>
153
+ jsonIntField(entry, "inputTokens") !== undefined ||
154
+ jsonIntField(entry, "outputTokens") !== undefined
155
+ )
156
+ const summed = perModel.reduce(
157
+ (sum, [, entry]) => ({
158
+ prompt: sum.prompt + (jsonIntField(entry, "inputTokens") ?? 0),
159
+ completion: sum.completion + (jsonIntField(entry, "outputTokens") ?? 0),
160
+ cached: sum.cached + (jsonIntField(entry, "cacheReadInputTokens") ?? 0)
161
+ }),
162
+ { prompt: 0, completion: 0, cached: 0 }
163
+ )
164
+ const prompt =
165
+ perModel.length === 0 ? (jsonIntField(usage, "input_tokens") ?? 0) : summed.prompt
166
+ const completion =
167
+ perModel.length === 0 ? (jsonIntField(usage, "output_tokens") ?? 0) : summed.completion
168
+ const cached =
169
+ perModel.length === 0
170
+ ? jsonIntField(usage, "cache_read_input_tokens")
171
+ : summed.cached === 0
172
+ ? undefined
173
+ : summed.cached
151
174
  return [
152
175
  usageEventChunk(
153
176
  modelNames.length === 1 ? modelNames[0] : undefined,
@@ -75,14 +75,25 @@ export const optionalModelArgs = (model: string | undefined): ReadonlyArray<stri
75
75
  export const effortWord = (effort: Effort, top: "max" | "xhigh" = "max"): string =>
76
76
  effort === "max" ? top : effort
77
77
 
78
- export const toolEventChunk = (name: string, input: JsonValue | undefined, id?: string): LlmChunk =>
78
+ export const toolEventChunk = (
79
+ name: string,
80
+ input: JsonValue | undefined,
81
+ id?: string,
82
+ options: {
83
+ /** The tool call this one runs inside, when a harness delegated it to a sub-agent (ADR 0033). */
84
+ readonly parent?: string
85
+ } = {}
86
+ ): LlmChunk =>
79
87
  LlmChunk.make({
80
88
  delta: "",
81
89
  metadata: {
82
90
  event: "tool_use",
83
91
  tool_name: name,
84
92
  tool_input: input === undefined ? "{}" : jsonText(input),
85
- ...(id === undefined || id.length === 0 ? {} : { tool_id: id })
93
+ ...(id === undefined || id.length === 0 ? {} : { tool_id: id }),
94
+ ...(options.parent === undefined || options.parent.length === 0
95
+ ? {}
96
+ : { parent: options.parent })
86
97
  }
87
98
  })
88
99
 
@@ -117,6 +128,10 @@ export const toolResultChunk = (
117
128
  readonly input?: JsonValue
118
129
  /** What the tool returned, for an opt-in transcript; never in the trace. */
119
130
  readonly output?: string
131
+ /** The tool call this one ran inside (ADR 0033). */
132
+ readonly parent?: string
133
+ /** How long the harness says the tool ran, when it reports that itself. */
134
+ readonly durationMs?: number
120
135
  } = {}
121
136
  ): LlmChunk =>
122
137
  LlmChunk.make({
@@ -125,6 +140,12 @@ export const toolResultChunk = (
125
140
  event: "tool_result",
126
141
  ...(id === undefined || id.length === 0 ? {} : { tool_id: id }),
127
142
  ...(options.failed === true ? { tool_failed: "true" } : {}),
143
+ ...(options.parent === undefined || options.parent.length === 0
144
+ ? {}
145
+ : { parent: options.parent }),
146
+ ...(options.durationMs === undefined || !Number.isFinite(options.durationMs)
147
+ ? {}
148
+ : { tool_duration_ms: String(Math.max(0, Math.round(options.durationMs))) }),
128
149
  ...(options.tool === undefined ? {} : { tool_name: options.tool }),
129
150
  ...(options.input === undefined ? {} : { tool_input: jsonText(options.input) }),
130
151
  ...(options.output === undefined ? {} : { tool_content: options.output })
@@ -221,3 +242,43 @@ export const failClassifiedCliError = Effect.fn(
221
242
  message: `${fallbackPrefix}: ${raw}`
222
243
  })
223
244
  })
245
+
246
+ /** The first `x.y.z` in a CLI's `--version` answer, if it holds one. */
247
+ export const versionTriple = (text: string): ReadonlyArray<number> | undefined => {
248
+ const match = /(\d+)\.(\d+)\.(\d+)/.exec(text)
249
+ return match === null ? undefined : match.slice(1, 4).map(Number)
250
+ }
251
+
252
+ /** Whether `version` is `floor` or newer, component by component. */
253
+ export const atLeastVersion = (
254
+ version: ReadonlyArray<number>,
255
+ floor: ReadonlyArray<number>
256
+ ): boolean => {
257
+ for (let index = 0; index < floor.length; index += 1) {
258
+ const have = version[index] ?? 0
259
+ const want = floor[index] ?? 0
260
+ if (have !== want) {
261
+ return have > want
262
+ }
263
+ }
264
+ return true
265
+ }
266
+
267
+ /**
268
+ * A harness pausing a turn on its own account — a provider retry, a context
269
+ * compaction — so the lane can say so instead of looking stuck (ADR 0033).
270
+ */
271
+ export const statusChunk = (
272
+ status: "retrying" | "compacting",
273
+ phase: "start" | "end",
274
+ detail?: string
275
+ ): LlmChunk =>
276
+ LlmChunk.make({
277
+ delta: "",
278
+ metadata: {
279
+ event: "status",
280
+ status,
281
+ phase,
282
+ ...(detail === undefined || detail.length === 0 ? {} : { status_detail: detail })
283
+ }
284
+ })
@@ -97,15 +97,31 @@ export const parseCodexStreamLine = (line: string): ReadonlyArray<LlmChunk> => {
97
97
  switch (jsonStringField(json, "type")) {
98
98
  case "item.started": {
99
99
  const item = jsonField(json, "item")
100
- return jsonStringField(item, "type") === "command_execution"
101
- ? [
100
+ switch (jsonStringField(item, "type")) {
101
+ case "command_execution":
102
+ return [
102
103
  toolEventChunk(
103
104
  "Bash",
104
105
  { command: jsonStringField(item, "command") ?? "" },
105
106
  jsonStringField(item, "id")
106
107
  )
107
108
  ]
108
- : []
109
+ // A sub-agent call (spawn_agent, wait, send_input, close_agent): the
110
+ // delegation shows as a tool, its threads as the arguments (ADR 0033).
111
+ case "collab_tool_call":
112
+ return [
113
+ toolEventChunk(
114
+ jsonStringField(item, "tool") ?? "collab",
115
+ {
116
+ prompt: jsonStringField(item, "prompt") ?? "",
117
+ receivers: jsonField(item, "receiver_thread_ids") ?? []
118
+ },
119
+ jsonStringField(item, "id")
120
+ )
121
+ ]
122
+ default:
123
+ return []
124
+ }
109
125
  }
110
126
  case "item.completed": {
111
127
  const item = jsonField(json, "item")
@@ -129,6 +145,13 @@ export const parseCodexStreamLine = (line: string): ReadonlyArray<LlmChunk> => {
129
145
  })
130
146
  ]
131
147
  }
148
+ case "collab_tool_call":
149
+ return [
150
+ toolResultChunk(jsonStringField(item, "id"), {
151
+ failed: jsonStringField(item, "status") === "failed",
152
+ tool: jsonStringField(item, "tool") ?? "collab"
153
+ })
154
+ ]
132
155
  default:
133
156
  return []
134
157
  }
@@ -27,6 +27,7 @@ import {
27
27
  import { collect } from "../Streaming.ts"
28
28
  import { jsonCandidates, parseFromText, withSchemaHint } from "../StructuredOutput.ts"
29
29
  import {
30
+ atLeastVersion,
30
31
  failClassifiedCliError,
31
32
  isLoopDetectedMessage,
32
33
  jsonField,
@@ -36,6 +37,7 @@ import {
36
37
  jsonStringField,
37
38
  jsonText,
38
39
  parseJsonLine,
40
+ versionTriple,
39
41
  type JsonValue
40
42
  } from "./CliSupport.ts"
41
43
 
@@ -271,25 +273,9 @@ export const geminiProcessEnv = (
271
273
  */
272
274
  export const geminiReadOnlyFloor = "0.37.0"
273
275
 
274
- const versionTriple = (text: string): ReadonlyArray<number> | undefined => {
275
- const match = /(\d+)\.(\d+)\.(\d+)/.exec(text)
276
- return match === null ? undefined : match.slice(1, 4).map(Number)
277
- }
278
-
279
276
  /** The `x.y.z` in a `gemini --version` answer, if it holds one. */
280
277
  export const geminiVersionOf = (text: string): string | undefined => versionTriple(text)?.join(".")
281
278
 
282
- const atLeast = (version: ReadonlyArray<number>, floor: ReadonlyArray<number>): boolean => {
283
- for (let index = 0; index < floor.length; index += 1) {
284
- const have = version[index] ?? 0
285
- const want = floor[index] ?? 0
286
- if (have !== want) {
287
- return have > want
288
- }
289
- }
290
- return true
291
- }
292
-
293
279
  /** Why this CLI cannot hold a read-only seat, or nothing when it can. */
294
280
  export const geminiReadOnlyProblem = (versionText: string): string | undefined => {
295
281
  const version = versionTriple(versionText)
@@ -300,7 +286,7 @@ export const geminiReadOnlyProblem = (versionText: string): string | undefined =
300
286
  `needs gemini >= ${geminiReadOnlyFloor}, whose plan mode is enforced by its policy engine`
301
287
  )
302
288
  }
303
- return atLeast(version, floor)
289
+ return atLeastVersion(version, floor)
304
290
  ? undefined
305
291
  : `Gemini CLI ${version.join(".")} cannot enforce a read-only seat: plan mode is a policy ` +
306
292
  `only from ${geminiReadOnlyFloor}; upgrade gemini, or give the judge and reviewer ` +