@ian-pascoe/pi-codemode 0.4.0 → 0.5.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/README.md +45 -7
- package/package.json +13 -3
- package/src/codemode-cell-transform.ts +1 -1
- package/src/codemode-known-output-schemas.ts +222 -0
- package/src/codemode-session-coordinator.ts +31 -6
- package/src/codemode-tool-catalog.ts +369 -51
- package/src/codemode-tool-contract.ts +77 -3
- package/src/codemode-tool-rendering.ts +171 -5
- package/src/pi-codemode-extension.ts +114 -19
package/README.md
CHANGED
|
@@ -154,14 +154,19 @@ parent kills the worker before it can reply.
|
|
|
154
154
|
|
|
155
155
|
## Transcript and Observer UI
|
|
156
156
|
|
|
157
|
-
The CodeMode Transcript gives all
|
|
158
|
-
rendering.
|
|
157
|
+
The CodeMode Transcript gives all five tools semantic collapsed and expanded
|
|
158
|
+
rendering. Session rows prioritize Cell lifecycle, a short Session ID, Cell
|
|
159
159
|
Ordinal, returned-value shape, Console-call count, nested-tool count, and elapsed
|
|
160
160
|
time. Expanded rows show the full Session ID, explicit call arguments,
|
|
161
161
|
TypeScript source, bounded Console output before structured returned data or the
|
|
162
162
|
error, and bounded nested-tool names, outcomes, and durations. Nested arguments
|
|
163
163
|
and raw nested outputs are never copied into the presentation.
|
|
164
164
|
|
|
165
|
+
Search rows show the query, result range, and next offset without exposing raw
|
|
166
|
+
JSON. Expanding a search shows each exact tool name, display group, highlighted
|
|
167
|
+
TypeScript declaration, and any declaration-size failure. Search declarations
|
|
168
|
+
are bounded only in the Transcript; the model-facing result remains unchanged.
|
|
169
|
+
|
|
165
170
|
Status always uses a symbol and text together:
|
|
166
171
|
|
|
167
172
|
```text
|
|
@@ -228,18 +233,50 @@ termination, or process failure destroys that session's heap.
|
|
|
228
233
|
|
|
229
234
|
## Registered tools
|
|
230
235
|
|
|
231
|
-
The `codemode_execute` description contains
|
|
232
|
-
for
|
|
236
|
+
The `codemode_execute` description contains a token-bounded catalogue of
|
|
237
|
+
complete generated TypeScript declarations for currently exposed registered
|
|
238
|
+
tools. It marks the catalogue `COMPLETE` or `PARTIAL`; a partial catalogue keeps
|
|
239
|
+
the remaining declarations available through:
|
|
233
240
|
|
|
234
241
|
```ts
|
|
235
|
-
|
|
242
|
+
const page = await tools.codemode_search({
|
|
243
|
+
query: "intent or exact registered name",
|
|
244
|
+
group: "optional display group",
|
|
245
|
+
limit: 10,
|
|
246
|
+
offset: 0,
|
|
247
|
+
});
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Search returns stable pages with `items`, `total`, `hasMore`, and `nextOffset`.
|
|
251
|
+
Each item contains its exact flat `name`, display-only `group`, bounded
|
|
252
|
+
`description`, and complete `declaration`. A pathological declaration above the
|
|
253
|
+
search response bound instead has an explicit `declarationError`, without
|
|
254
|
+
stalling pagination. Call a discovered tool with `tools[item.name](input)`;
|
|
255
|
+
every exposed name remains callable even when its declaration is omitted from
|
|
256
|
+
the inline catalogue.
|
|
257
|
+
|
|
258
|
+
`codemode_search` is also a direct Pi tool, so declarations can be discovered
|
|
259
|
+
before starting a Cell. Direct search reads the current exposure catalogue;
|
|
260
|
+
in-Cell search reads the Cell's frozen exposure snapshot. Both expose only
|
|
261
|
+
CodeMode-callable tools and use the same search implementation.
|
|
262
|
+
|
|
263
|
+
Ordinary guest tool calls resolve to:
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
type PiToolResult<Output = unknown> = {
|
|
236
267
|
content: Array<
|
|
237
268
|
{ type: "text"; text: string } | { type: "image"; data: string; mimeType: string }
|
|
238
269
|
>;
|
|
239
|
-
details?:
|
|
270
|
+
details?: Output;
|
|
240
271
|
};
|
|
241
272
|
```
|
|
242
273
|
|
|
274
|
+
Each declaration derives its input from `parameters` and its `details` type
|
|
275
|
+
from the registered definition's optional `outputSchema`. Source-gated fallback
|
|
276
|
+
schemas cover Pi's built-in tools and `@howaboua/pi-codex-conversion` 3.0.23;
|
|
277
|
+
tool-provided schemas take precedence. Other missing or unsupported output
|
|
278
|
+
schemas remain `unknown`.
|
|
279
|
+
|
|
243
280
|
Ordinary tool failures reject with a catchable `CodeModeToolError`. A Pi result
|
|
244
281
|
that requests termination stops the complete CodeMode Session and cannot be
|
|
245
282
|
caught by guest code.
|
|
@@ -268,7 +305,8 @@ last match wins. Project `tools` replaces the global array, while project
|
|
|
268
305
|
|
|
269
306
|
An unmatched active tool defaults to `direct-and-codemode`; an unmatched
|
|
270
307
|
inactive tool remains unavailable. An explicit rule may expose an inactive tool
|
|
271
|
-
or activate direct access. The
|
|
308
|
+
or activate direct access. The five registered `codemode_*` tools are always
|
|
309
|
+
direct-only.
|
|
272
310
|
Pi's global allowed/excluded registry remains authoritative. Invalid fields or
|
|
273
311
|
patterns disable CodeMode for that session without changing Pi's active tools.
|
|
274
312
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ian-pascoe/pi-codemode",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Process-isolated persistent TypeScript tool composition for Pi",
|
|
6
6
|
"keywords": [
|
|
@@ -35,16 +35,26 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"deno": "2.9.5",
|
|
38
|
-
"minimatch": "^10.2.
|
|
39
|
-
"typescript": "6.0.3"
|
|
38
|
+
"minimatch": "^10.2.6",
|
|
39
|
+
"runtime-typescript": "npm:typescript@6.0.3",
|
|
40
|
+
"typescript": "^7.0.2"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@howaboua/pi-codex-conversion": "3.0.23"
|
|
40
44
|
},
|
|
41
45
|
"peerDependencies": {
|
|
42
46
|
"@earendil-works/pi-agent-core": "*",
|
|
43
47
|
"@earendil-works/pi-ai": "*",
|
|
44
48
|
"@earendil-works/pi-coding-agent": "*",
|
|
45
49
|
"@earendil-works/pi-tui": "*",
|
|
50
|
+
"@howaboua/pi-codex-conversion": "3.0.23",
|
|
46
51
|
"typebox": "*"
|
|
47
52
|
},
|
|
53
|
+
"peerDependenciesMeta": {
|
|
54
|
+
"@howaboua/pi-codex-conversion": {
|
|
55
|
+
"optional": true
|
|
56
|
+
}
|
|
57
|
+
},
|
|
48
58
|
"engines": {
|
|
49
59
|
"node": ">=22.19.0"
|
|
50
60
|
},
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import type { ToolInfo } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { Type, type TSchema } from "typebox";
|
|
3
|
+
import type { CodeModeToolSchema } from "./codemode-tool-catalog.js";
|
|
4
|
+
|
|
5
|
+
const ClosedObject = { additionalProperties: false } as const;
|
|
6
|
+
const OptionalUndefinedString = Type.Optional(Type.Union([Type.String(), Type.Undefined()]));
|
|
7
|
+
const OptionalUndefinedNumber = Type.Optional(Type.Union([Type.Number(), Type.Undefined()]));
|
|
8
|
+
|
|
9
|
+
const TruncationResultSchema = Type.Object(
|
|
10
|
+
{
|
|
11
|
+
content: Type.String(),
|
|
12
|
+
truncated: Type.Boolean(),
|
|
13
|
+
truncatedBy: Type.Union([Type.Literal("lines"), Type.Literal("bytes"), Type.Null()]),
|
|
14
|
+
totalLines: Type.Number(),
|
|
15
|
+
totalBytes: Type.Number(),
|
|
16
|
+
outputLines: Type.Number(),
|
|
17
|
+
outputBytes: Type.Number(),
|
|
18
|
+
lastLinePartial: Type.Boolean(),
|
|
19
|
+
firstLineExceedsLimit: Type.Boolean(),
|
|
20
|
+
maxLines: Type.Number(),
|
|
21
|
+
maxBytes: Type.Number(),
|
|
22
|
+
},
|
|
23
|
+
ClosedObject,
|
|
24
|
+
);
|
|
25
|
+
const ShellOutputSchema = Type.Object(
|
|
26
|
+
{
|
|
27
|
+
truncation: Type.Optional(TruncationResultSchema),
|
|
28
|
+
fullOutputPath: Type.Optional(Type.String()),
|
|
29
|
+
},
|
|
30
|
+
ClosedObject,
|
|
31
|
+
);
|
|
32
|
+
const ReadOutputSchema = Type.Object(
|
|
33
|
+
{ truncation: Type.Optional(TruncationResultSchema) },
|
|
34
|
+
ClosedObject,
|
|
35
|
+
);
|
|
36
|
+
const EditOutputSchema = Type.Object(
|
|
37
|
+
{
|
|
38
|
+
diff: Type.String(),
|
|
39
|
+
patch: Type.String(),
|
|
40
|
+
firstChangedLine: Type.Optional(Type.Number()),
|
|
41
|
+
},
|
|
42
|
+
ClosedObject,
|
|
43
|
+
);
|
|
44
|
+
const GrepOutputSchema = Type.Object(
|
|
45
|
+
{
|
|
46
|
+
truncation: Type.Optional(TruncationResultSchema),
|
|
47
|
+
matchLimitReached: Type.Optional(Type.Number()),
|
|
48
|
+
linesTruncated: Type.Optional(Type.Boolean()),
|
|
49
|
+
},
|
|
50
|
+
ClosedObject,
|
|
51
|
+
);
|
|
52
|
+
const FindOutputSchema = Type.Object(
|
|
53
|
+
{
|
|
54
|
+
truncation: Type.Optional(TruncationResultSchema),
|
|
55
|
+
resultLimitReached: Type.Optional(Type.Number()),
|
|
56
|
+
},
|
|
57
|
+
ClosedObject,
|
|
58
|
+
);
|
|
59
|
+
const LsOutputSchema = Type.Object(
|
|
60
|
+
{
|
|
61
|
+
truncation: Type.Optional(TruncationResultSchema),
|
|
62
|
+
entryLimitReached: Type.Optional(Type.Number()),
|
|
63
|
+
},
|
|
64
|
+
ClosedObject,
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const ExecutePatchResultSchema = Type.Object(
|
|
68
|
+
{
|
|
69
|
+
changedFiles: Type.Array(Type.String()),
|
|
70
|
+
createdFiles: Type.Array(Type.String()),
|
|
71
|
+
deletedFiles: Type.Array(Type.String()),
|
|
72
|
+
movedFiles: Type.Array(Type.String()),
|
|
73
|
+
fuzz: Type.Number(),
|
|
74
|
+
},
|
|
75
|
+
ClosedObject,
|
|
76
|
+
);
|
|
77
|
+
const ApplyPatchOutputSchema = Type.Union([
|
|
78
|
+
Type.Object({ status: Type.Literal("success"), result: ExecutePatchResultSchema }, ClosedObject),
|
|
79
|
+
Type.Object(
|
|
80
|
+
{
|
|
81
|
+
status: Type.Literal("partial_failure"),
|
|
82
|
+
result: ExecutePatchResultSchema,
|
|
83
|
+
failedTargets: Type.Optional(Type.Union([Type.Array(Type.String()), Type.Undefined()])),
|
|
84
|
+
},
|
|
85
|
+
ClosedObject,
|
|
86
|
+
),
|
|
87
|
+
]);
|
|
88
|
+
const UnifiedExecOutputSchema = Type.Object(
|
|
89
|
+
{
|
|
90
|
+
chunk_id: Type.String(),
|
|
91
|
+
wall_time_seconds: Type.Number(),
|
|
92
|
+
output: Type.String(),
|
|
93
|
+
exit_code: OptionalUndefinedNumber,
|
|
94
|
+
session_id: OptionalUndefinedNumber,
|
|
95
|
+
original_token_count: OptionalUndefinedNumber,
|
|
96
|
+
},
|
|
97
|
+
ClosedObject,
|
|
98
|
+
);
|
|
99
|
+
const ImagegenOutputSchema = Type.Object(
|
|
100
|
+
{
|
|
101
|
+
path: Type.String(),
|
|
102
|
+
latest_path: Type.String(),
|
|
103
|
+
images: Type.Array(
|
|
104
|
+
Type.Object(
|
|
105
|
+
{
|
|
106
|
+
path: Type.String(),
|
|
107
|
+
absolute_path: Type.String(),
|
|
108
|
+
latest_path: Type.Optional(Type.String()),
|
|
109
|
+
latest_absolute_path: Type.Optional(Type.String()),
|
|
110
|
+
},
|
|
111
|
+
ClosedObject,
|
|
112
|
+
),
|
|
113
|
+
),
|
|
114
|
+
background: OptionalUndefinedString,
|
|
115
|
+
quality: OptionalUndefinedString,
|
|
116
|
+
size: OptionalUndefinedString,
|
|
117
|
+
},
|
|
118
|
+
ClosedObject,
|
|
119
|
+
);
|
|
120
|
+
// oxlint-disable-next-line anti-slop/no-unsafe-dictionary-type -- SAFETY: pi-codex-conversion intentionally exposes provider-defined web_run fields alongside these known text fields.
|
|
121
|
+
type CodexWebRunPayload = Record<string, unknown> & {
|
|
122
|
+
encrypted_output?: string | undefined;
|
|
123
|
+
output_text?: string | undefined;
|
|
124
|
+
output?: string | undefined;
|
|
125
|
+
text?: string | undefined;
|
|
126
|
+
};
|
|
127
|
+
const WebRunPayloadSchema = Type.Unsafe<CodexWebRunPayload>(
|
|
128
|
+
Type.Object(
|
|
129
|
+
{
|
|
130
|
+
encrypted_output: OptionalUndefinedString,
|
|
131
|
+
output_text: OptionalUndefinedString,
|
|
132
|
+
output: OptionalUndefinedString,
|
|
133
|
+
text: OptionalUndefinedString,
|
|
134
|
+
},
|
|
135
|
+
{ additionalProperties: true },
|
|
136
|
+
),
|
|
137
|
+
);
|
|
138
|
+
const WebRunOutputSchema = Type.Object({ webRun: WebRunPayloadSchema }, ClosedObject);
|
|
139
|
+
const ViewImageContentSchema = Type.Object(
|
|
140
|
+
{
|
|
141
|
+
type: Type.Literal("image"),
|
|
142
|
+
data: Type.String(),
|
|
143
|
+
mimeType: Type.String(),
|
|
144
|
+
detail: Type.Union([Type.Literal("high"), Type.Literal("original")]),
|
|
145
|
+
},
|
|
146
|
+
ClosedObject,
|
|
147
|
+
);
|
|
148
|
+
const ViewImageOutputSchema = Type.Union([
|
|
149
|
+
Type.Object({ viewImage: Type.Literal(true) }, ClosedObject),
|
|
150
|
+
Type.Object(
|
|
151
|
+
{
|
|
152
|
+
viewImageDescription: Type.Object(
|
|
153
|
+
{
|
|
154
|
+
image: ViewImageContentSchema,
|
|
155
|
+
path: Type.String(),
|
|
156
|
+
description: Type.String(),
|
|
157
|
+
},
|
|
158
|
+
ClosedObject,
|
|
159
|
+
),
|
|
160
|
+
},
|
|
161
|
+
ClosedObject,
|
|
162
|
+
),
|
|
163
|
+
]);
|
|
164
|
+
|
|
165
|
+
/** Source-gated fallback output schemas for Pi and pi-codex-conversion tool details. */
|
|
166
|
+
export const CodeModeKnownOutputSchemas = {
|
|
167
|
+
builtin: {
|
|
168
|
+
bash: ShellOutputSchema,
|
|
169
|
+
powershell: ShellOutputSchema,
|
|
170
|
+
read: ReadOutputSchema,
|
|
171
|
+
edit: EditOutputSchema,
|
|
172
|
+
write: Type.Undefined(),
|
|
173
|
+
grep: GrepOutputSchema,
|
|
174
|
+
find: FindOutputSchema,
|
|
175
|
+
ls: LsOutputSchema,
|
|
176
|
+
},
|
|
177
|
+
codexConversion: {
|
|
178
|
+
apply_patch: ApplyPatchOutputSchema,
|
|
179
|
+
exec_command: UnifiedExecOutputSchema,
|
|
180
|
+
write_stdin: UnifiedExecOutputSchema,
|
|
181
|
+
view_image: ViewImageOutputSchema,
|
|
182
|
+
web_run: WebRunOutputSchema,
|
|
183
|
+
imagegen: ImagegenOutputSchema,
|
|
184
|
+
},
|
|
185
|
+
} as const satisfies {
|
|
186
|
+
readonly builtin: Readonly<Record<string, TSchema>>;
|
|
187
|
+
readonly codexConversion: Readonly<Record<string, TSchema>>;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const CODEX_CONVERSION_SOURCE = "npm:@howaboua/pi-codex-conversion";
|
|
191
|
+
|
|
192
|
+
function schemaByName(
|
|
193
|
+
schemas: Readonly<Record<string, TSchema>>,
|
|
194
|
+
name: string,
|
|
195
|
+
): TSchema | undefined {
|
|
196
|
+
return schemas[name];
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function isCodexConversionSource(sourceInfo: ToolInfo["sourceInfo"]): boolean {
|
|
200
|
+
return (
|
|
201
|
+
sourceInfo.origin === "package" &&
|
|
202
|
+
(sourceInfo.source === CODEX_CONVERSION_SOURCE ||
|
|
203
|
+
sourceInfo.source.startsWith(`${CODEX_CONVERSION_SOURCE}@`))
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** Returns a known output schema only when both the registered tool name and owner match. */
|
|
208
|
+
export function resolveKnownToolOutputSchema(
|
|
209
|
+
tool: Pick<ToolInfo, "name" | "sourceInfo">,
|
|
210
|
+
): CodeModeToolSchema | undefined {
|
|
211
|
+
if (
|
|
212
|
+
tool.sourceInfo.source === "builtin" &&
|
|
213
|
+
tool.sourceInfo.path === `<builtin:${tool.name}>` &&
|
|
214
|
+
tool.sourceInfo.scope === "temporary" &&
|
|
215
|
+
tool.sourceInfo.origin === "top-level"
|
|
216
|
+
) {
|
|
217
|
+
return schemaByName(CodeModeKnownOutputSchemas.builtin, tool.name);
|
|
218
|
+
}
|
|
219
|
+
return isCodexConversionSource(tool.sourceInfo)
|
|
220
|
+
? schemaByName(CodeModeKnownOutputSchemas.codexConversion, tool.name)
|
|
221
|
+
: undefined;
|
|
222
|
+
}
|
|
@@ -7,7 +7,9 @@ import { CodeModeWorkerProcess } from "./codemode-deno-process.js";
|
|
|
7
7
|
import { formatCodeModePresentationData } from "./codemode-presentation-output.js";
|
|
8
8
|
import type { CodeModeRuntime, CodeModeTimerHandle } from "./codemode-runtime.js";
|
|
9
9
|
import type { CodeModeResultSpillWriter } from "./codemode-session-files.js";
|
|
10
|
+
import type { CodeModeToolSearchEntry } from "./codemode-tool-catalog.js";
|
|
10
11
|
import {
|
|
12
|
+
CODEMODE_SEARCH_TOOL_NAME,
|
|
11
13
|
createCodeModeFailure,
|
|
12
14
|
createCodeModePending,
|
|
13
15
|
createCodeModeSuccess,
|
|
@@ -123,6 +125,10 @@ export type CodeModeNestedToolBatch = {
|
|
|
123
125
|
readonly sessionId: string;
|
|
124
126
|
readonly batchId: string;
|
|
125
127
|
readonly calls: readonly CodeModeNestedToolCall[];
|
|
128
|
+
/** Exact guest-callable name snapshot installed for this Cell. */
|
|
129
|
+
readonly exposedToolNames: readonly string[];
|
|
130
|
+
/** Immutable searchable declaration snapshot installed with this Cell's names. */
|
|
131
|
+
readonly searchEntries: readonly CodeModeToolSearchEntry[];
|
|
126
132
|
readonly signal: AbortSignal;
|
|
127
133
|
readonly onUpdate?: (update: CodeModeNestedToolUpdate) => void;
|
|
128
134
|
};
|
|
@@ -159,7 +165,11 @@ export type CodeModeSessionOperationResult = {
|
|
|
159
165
|
/** Construction capabilities and limits for one CodeMode Session coordinator. */
|
|
160
166
|
export type CodeModeSessionCoordinatorOptions = {
|
|
161
167
|
readonly maxSessions: number;
|
|
162
|
-
|
|
168
|
+
/** Captures guest-callable names and searchable declarations atomically for each Cell. */
|
|
169
|
+
readonly getToolSnapshot: () => {
|
|
170
|
+
readonly names: readonly string[];
|
|
171
|
+
readonly searchEntries: readonly CodeModeToolSearchEntry[];
|
|
172
|
+
};
|
|
163
173
|
readonly executeToolBatch: ExecuteCodeModeNestedToolBatch;
|
|
164
174
|
/** Private Result Spill storage for complete oversized presentation data. */
|
|
165
175
|
readonly resultSpillWriter: CodeModeResultSpillWriter;
|
|
@@ -198,6 +208,8 @@ type ActiveCodeModeCell = {
|
|
|
198
208
|
readonly resolveCompletion: (result: CodeModeResult) => void;
|
|
199
209
|
readonly metadata: CodeModeMetadataAccumulator;
|
|
200
210
|
readonly nestedTools: CodeModePresentationSnapshot["nested_tools"];
|
|
211
|
+
exposedToolNames: readonly string[];
|
|
212
|
+
searchEntries: readonly CodeModeToolSearchEntry[];
|
|
201
213
|
activeToolNames: readonly string[];
|
|
202
214
|
activeToolCount: number;
|
|
203
215
|
failedNestedToolCount: number;
|
|
@@ -739,6 +751,8 @@ export class CodeModeSessionCoordinator {
|
|
|
739
751
|
resolveCompletion: completion.resolve,
|
|
740
752
|
metadata: emptyMetadataAccumulator(),
|
|
741
753
|
nestedTools: [],
|
|
754
|
+
exposedToolNames: [],
|
|
755
|
+
searchEntries: [],
|
|
742
756
|
activeToolNames: [],
|
|
743
757
|
activeToolCount: 0,
|
|
744
758
|
failedNestedToolCount: 0,
|
|
@@ -789,7 +803,13 @@ export class CodeModeSessionCoordinator {
|
|
|
789
803
|
}, input.timeoutMs + CODEMODE_WATCHDOG_GRACE_MS);
|
|
790
804
|
}
|
|
791
805
|
try {
|
|
792
|
-
const
|
|
806
|
+
const toolSnapshot = this.options.getToolSnapshot();
|
|
807
|
+
const toolNames = [...new Set(toolSnapshot.names)];
|
|
808
|
+
cell.exposedToolNames = toolNames;
|
|
809
|
+
const exposedNames = new Set(toolNames);
|
|
810
|
+
cell.searchEntries = toolSnapshot.searchEntries.filter((entry) =>
|
|
811
|
+
exposedNames.has(entry.name),
|
|
812
|
+
);
|
|
793
813
|
const requestBase = {
|
|
794
814
|
version: 1,
|
|
795
815
|
type: "execute",
|
|
@@ -900,9 +920,12 @@ export class CodeModeSessionCoordinator {
|
|
|
900
920
|
cell: ActiveCodeModeCell,
|
|
901
921
|
response: Extract<CodeModeWorkerResponse, { readonly type: "tool-batch" }>,
|
|
902
922
|
): Promise<void> {
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
923
|
+
const piToolCalls = response.calls.filter(
|
|
924
|
+
(call) => call.toolName !== CODEMODE_SEARCH_TOOL_NAME,
|
|
925
|
+
);
|
|
926
|
+
cell.activeToolNames = [...new Set(piToolCalls.map((call) => call.toolName))];
|
|
927
|
+
cell.activeToolCount = piToolCalls.length;
|
|
928
|
+
cell.nestedToolCount += piToolCalls.length;
|
|
906
929
|
record.lastActivityAtMs = this.runtime.now();
|
|
907
930
|
this.publishObserverSnapshot();
|
|
908
931
|
|
|
@@ -927,6 +950,8 @@ export class CodeModeSessionCoordinator {
|
|
|
927
950
|
sessionId: record.sessionId,
|
|
928
951
|
batchId: response.batchId,
|
|
929
952
|
calls: parsedCalls,
|
|
953
|
+
exposedToolNames: cell.exposedToolNames,
|
|
954
|
+
searchEntries: cell.searchEntries,
|
|
930
955
|
signal: cell.abortController.signal,
|
|
931
956
|
} as const;
|
|
932
957
|
const onUpdate = (_update: CodeModeNestedToolUpdate): void => {
|
|
@@ -951,7 +976,7 @@ export class CodeModeSessionCoordinator {
|
|
|
951
976
|
};
|
|
952
977
|
}
|
|
953
978
|
if (!this.isCurrentCell(record, cell)) return;
|
|
954
|
-
this.recordNestedToolPresentation(cell,
|
|
979
|
+
this.recordNestedToolPresentation(cell, piToolCalls, batchResult);
|
|
955
980
|
cell.activeToolNames = [];
|
|
956
981
|
cell.activeToolCount = 0;
|
|
957
982
|
record.lastActivityAtMs = this.runtime.now();
|