@yolk-sdk/codemode 0.1.0-canary.123 → 0.1.0-canary.125
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 +2 -2
- package/dist/catalog.d.mts +46 -38
- package/dist/catalog.d.mts.map +1 -1
- package/dist/catalog.mjs +6 -4
- package/dist/catalog.mjs.map +1 -1
- package/dist/classifier-tool.d.mts +15 -15
- package/dist/classifier-tool.d.mts.map +1 -1
- package/dist/classifier-tool.mjs +4 -4
- package/dist/classifier-tool.mjs.map +1 -1
- package/dist/executor.d.mts +29 -24
- package/dist/executor.d.mts.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +2 -2
- package/dist/node.d.mts +5 -8
- package/dist/node.d.mts.map +1 -1
- package/dist/node.mjs +3 -3
- package/dist/node.mjs.map +1 -1
- package/dist/output.d.mts +8 -12
- package/dist/output.d.mts.map +1 -1
- package/dist/output.mjs +2 -3
- package/dist/output.mjs.map +1 -1
- package/dist/search.d.mts +10 -11
- package/dist/search.d.mts.map +1 -1
- package/dist/search.mjs +1 -2
- package/dist/search.mjs.map +1 -1
- package/dist/store.d.mts +15 -16
- package/dist/store.d.mts.map +1 -1
- package/dist/store.mjs +3 -4
- package/dist/store.mjs.map +1 -1
- package/dist/tool.d.mts +23 -20
- package/dist/tool.d.mts.map +1 -1
- package/dist/tool.mjs +5 -5
- package/dist/tool.mjs.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -6,11 +6,11 @@ resolved tools, filters and aggregates their results, and returns only what matt
|
|
|
6
6
|
## Install
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
|
-
pnpm add @yolk-sdk/codemode@canary @yolk-sdk/agent@canary effect@4.
|
|
9
|
+
pnpm add @yolk-sdk/codemode@canary @yolk-sdk/agent@canary effect@4.1.2
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
Canary APIs are unstable. Keep all `@yolk-sdk/*` packages on the same version.
|
|
13
|
-
Use the SDK's matching Effect version (`4.
|
|
13
|
+
Use the SDK's matching Effect version (`4.1.2`) in host code.
|
|
14
14
|
Requires Node.js 22.19+ (the pi engine's minimum). `@yolk-sdk/codemode/node` is server-only.
|
|
15
15
|
|
|
16
16
|
## Subpaths
|
package/dist/catalog.d.mts
CHANGED
|
@@ -2,28 +2,32 @@ import { CodeModeJsonSchema } from "./executor.mjs";
|
|
|
2
2
|
import * as Schema from "effect/Schema";
|
|
3
3
|
import { NestedTool } from "@yolk-sdk/agent/tools";
|
|
4
4
|
import { RunInstruction } from "@yolk-sdk/agent/loop";
|
|
5
|
-
|
|
6
|
-
//#region src/catalog.d.ts
|
|
7
5
|
/** How a nested tool reaches scripts: `all` tools are also direct model tools; `listed` and
|
|
8
6
|
* `search` are the two discovery modes of `codemode`-only tools; `stage` marks a stageable tool
|
|
9
7
|
* (approval-gated, ADR 0007): found by search, never callable, only passed to `stage()`.
|
|
10
8
|
*/
|
|
11
|
-
type CodeModeToolExposure = 'all' | 'listed' | 'search' | 'pinned' | 'stage';
|
|
9
|
+
export type CodeModeToolExposure = 'all' | 'listed' | 'search' | 'pinned' | 'stage';
|
|
12
10
|
/** One nested tool as scripts see it. */
|
|
13
|
-
type CodeModeCatalogTool = {
|
|
14
|
-
/** Raw tool name; scripts may call `tools["<name>"](args)`. */
|
|
11
|
+
export type CodeModeCatalogTool = {
|
|
12
|
+
/** Raw tool name; scripts may call `tools["<name>"](args)`. */
|
|
13
|
+
readonly name: string;
|
|
14
|
+
/** Identifier for `tools.<identifier>(args)` (invalid identifier characters become `_`). */
|
|
15
15
|
readonly identifier: string;
|
|
16
16
|
/**
|
|
17
17
|
* How scripts call this tool, used to prefix its rejections: `tools.<identifier>`, or
|
|
18
18
|
* `tools["<name>"]` when an earlier tool already has the identifier (see `codeModeCallLabels`;
|
|
19
19
|
* when the name is taken too, the tool is unreachable and the label only names it).
|
|
20
20
|
*/
|
|
21
|
-
readonly callLabel: string;
|
|
22
|
-
|
|
21
|
+
readonly callLabel: string;
|
|
22
|
+
/** The tool's `ToolModule.id`. */
|
|
23
|
+
readonly namespace: string;
|
|
24
|
+
/** The module's `ToolModule.description`, when set. */
|
|
23
25
|
readonly namespaceDescription?: string;
|
|
24
26
|
readonly description: string;
|
|
25
|
-
readonly inputSchema: CodeModeJsonSchema;
|
|
26
|
-
|
|
27
|
+
readonly inputSchema: CodeModeJsonSchema;
|
|
28
|
+
/** The declared output schema, or `{ type: 'string' }` for text results. */
|
|
29
|
+
readonly outputSchema: CodeModeJsonSchema;
|
|
30
|
+
/** True when the tool declares an output schema (calls resolve to `structuredContent`). */
|
|
27
31
|
readonly structured: boolean;
|
|
28
32
|
readonly exposure: CodeModeToolExposure;
|
|
29
33
|
};
|
|
@@ -34,25 +38,26 @@ type CodeModeCatalogTool = {
|
|
|
34
38
|
* identifier, otherwise `tools["<name>"]`. The executor guard and the host rejection prefix share
|
|
35
39
|
* it, so both name a call the same way.
|
|
36
40
|
*/
|
|
37
|
-
declare const codeModeCallLabels: (names: ReadonlyArray<string>) => ReadonlyArray<string>;
|
|
41
|
+
export declare const codeModeCallLabels: (names: ReadonlyArray<string>) => ReadonlyArray<string>;
|
|
38
42
|
/** Catalog of nested tools in resolution order. */
|
|
39
|
-
declare const codeModeCatalog: (tools: ReadonlyArray<NestedTool>) => ReadonlyArray<CodeModeCatalogTool>;
|
|
43
|
+
export declare const codeModeCatalog: (tools: ReadonlyArray<NestedTool>) => ReadonlyArray<CodeModeCatalogTool>;
|
|
40
44
|
/**
|
|
41
45
|
* Catalog entries of the stageable tools (ADR 0007). Stageable tools are approval-gated, so scripts
|
|
42
46
|
* can only `stage()` them whatever their `callableBy` (stage-only `codemode` ones are also never
|
|
43
47
|
* declared to the model): searchable and describable, never callable (no `tools` binding), so
|
|
44
48
|
* their call label is the `stage()` call that records them.
|
|
45
49
|
*/
|
|
46
|
-
declare const codeModeStageOnlyCatalog: (stageable: ReadonlyArray<NestedTool>) => ReadonlyArray<CodeModeCatalogTool>;
|
|
50
|
+
export declare const codeModeStageOnlyCatalog: (stageable: ReadonlyArray<NestedTool>) => ReadonlyArray<CodeModeCatalogTool>;
|
|
47
51
|
/** Default inline budget of the nested tool listing, in estimated tokens. */
|
|
48
|
-
declare const defaultCodeModeInlineBudget = 3000;
|
|
52
|
+
export declare const defaultCodeModeInlineBudget = 3000;
|
|
49
53
|
/** Estimated tokens of a text: four characters per token, rounded up. */
|
|
50
|
-
declare const estimateCodeModeTokens: (text: string) => number;
|
|
51
|
-
type CodeModeListing = {
|
|
54
|
+
export declare const estimateCodeModeTokens: (text: string) => number;
|
|
55
|
+
export type CodeModeListing = {
|
|
52
56
|
/** Tools placed in the description, in catalog order: every `all` tool, and the `listed` tools
|
|
53
57
|
* that fit the budget.
|
|
54
58
|
*/
|
|
55
|
-
readonly listed: ReadonlyArray<CodeModeCatalogTool>;
|
|
59
|
+
readonly listed: ReadonlyArray<CodeModeCatalogTool>;
|
|
60
|
+
/** Namespaces (catalog order) with callable tools the description does not list. */
|
|
56
61
|
readonly unlistedNamespaces: ReadonlyArray<string>;
|
|
57
62
|
};
|
|
58
63
|
/**
|
|
@@ -62,16 +67,18 @@ type CodeModeListing = {
|
|
|
62
67
|
* places its cheapest remaining tool; a namespace whose next tool does not fit drops out. `search`
|
|
63
68
|
* tools are never candidates.
|
|
64
69
|
*/
|
|
65
|
-
declare const selectCodeModeListing: (catalog: ReadonlyArray<CodeModeCatalogTool>, budget: number) => CodeModeListing;
|
|
70
|
+
export declare const selectCodeModeListing: (catalog: ReadonlyArray<CodeModeCatalogTool>, budget: number) => CodeModeListing;
|
|
66
71
|
/** Staged tool plans as the description shows them (`NestedToolStagingDescription`). */
|
|
67
|
-
type CodeModeStagingDescription = {
|
|
72
|
+
export type CodeModeStagingDescription = {
|
|
68
73
|
readonly tools: ReadonlyArray<NestedTool>;
|
|
69
74
|
readonly reviewToolName: string;
|
|
70
75
|
};
|
|
71
|
-
type CodeModeDescriptionInput = {
|
|
76
|
+
export type CodeModeDescriptionInput = {
|
|
72
77
|
readonly tools: ReadonlyArray<NestedTool>;
|
|
73
|
-
readonly inlineBudget?: number;
|
|
74
|
-
|
|
78
|
+
readonly inlineBudget?: number;
|
|
79
|
+
/** Mention `store()`/`load()` persistence. */
|
|
80
|
+
readonly store?: boolean;
|
|
81
|
+
/** Document `stage()` and list the stageable tools that are neither `search` nor deferred. */
|
|
75
82
|
readonly staging?: CodeModeStagingDescription;
|
|
76
83
|
};
|
|
77
84
|
/**
|
|
@@ -84,35 +91,38 @@ type CodeModeDescriptionInput = {
|
|
|
84
91
|
* stageable tools are never named, so they leave the text byte-identical too once any stageable
|
|
85
92
|
* tool exists.
|
|
86
93
|
*/
|
|
87
|
-
declare const renderCodeModeDescription: (input: CodeModeDescriptionInput) => string;
|
|
94
|
+
export declare const renderCodeModeDescription: (input: CodeModeDescriptionInput) => string;
|
|
88
95
|
/** Longest `searchTools` signature, cut marker included (`describeTool` has the whole declaration). */
|
|
89
|
-
declare const maxCodeModeSearchSignatureChars = 800;
|
|
96
|
+
export declare const maxCodeModeSearchSignatureChars = 800;
|
|
90
97
|
/**
|
|
91
98
|
* The call a `searchTools` hit shows, enough to call the tool without `describeTool`:
|
|
92
99
|
* `tools.<id>(args): Promise<result>`, or `stage("<name>", args)` for a stageable tool. Bounded:
|
|
93
100
|
* a long one ends with a pointer to `describeTool`.
|
|
94
101
|
*/
|
|
95
|
-
declare const codeModeToolSignature: (tool: CodeModeCatalogTool) => string;
|
|
102
|
+
export declare const codeModeToolSignature: (tool: CodeModeCatalogTool) => string;
|
|
96
103
|
/**
|
|
97
104
|
* `describeTool` text: the description and TypeScript declaration of one tool. A stage-only tool
|
|
98
105
|
* has no `tools` binding, so it is described as the `stage()` call that records it.
|
|
99
106
|
*/
|
|
100
|
-
declare const describeCodeModeTool: (tool: CodeModeCatalogTool) => string;
|
|
107
|
+
export declare const describeCodeModeTool: (tool: CodeModeCatalogTool) => string;
|
|
101
108
|
/**
|
|
102
109
|
* Finds a tool by identifier or raw name. A stageable tool's exact raw name wins first: it has no
|
|
103
110
|
* binding, so a callable tool sharing its identifier (`archive-resource` vs `archive_resource`)
|
|
104
111
|
* must not answer for it; callable lookups keep identifier precedence, as their bindings do.
|
|
105
112
|
*/
|
|
106
|
-
declare const findCodeModeTool: (catalog: ReadonlyArray<CodeModeCatalogTool>, name: string) => CodeModeCatalogTool | undefined;
|
|
113
|
+
export declare const findCodeModeTool: (catalog: ReadonlyArray<CodeModeCatalogTool>, name: string) => CodeModeCatalogTool | undefined;
|
|
107
114
|
/** The instruction key of the code mode catalog (`catalog: 'instructions'`, ADR 0007). */
|
|
108
|
-
declare const codeModeCatalogInstructionKey = "yolk.codemode.catalog";
|
|
115
|
+
export declare const codeModeCatalogInstructionKey = "yolk.codemode.catalog";
|
|
109
116
|
/** The catalog an instruction message records as its state (JSON, never model-visible). */
|
|
110
|
-
declare const CodeModeCatalogSummary: Schema.Struct<{
|
|
117
|
+
export declare const CodeModeCatalogSummary: Schema.Struct<{
|
|
111
118
|
readonly namespaces: Schema.$Array<Schema.Struct<{
|
|
112
119
|
readonly name: Schema.String;
|
|
113
|
-
readonly description: Schema.optional<Schema.String>;
|
|
114
|
-
|
|
115
|
-
readonly
|
|
120
|
+
readonly description: Schema.optional<Schema.String>;
|
|
121
|
+
/** Every tool scripts reach in the namespace: callable and stage-only. */
|
|
122
|
+
readonly count: Schema.Number;
|
|
123
|
+
/** Tools the listing shows. */
|
|
124
|
+
readonly shown: Schema.Number;
|
|
125
|
+
/** The rendered declarations and direct tool lines of the shown tools. */
|
|
116
126
|
readonly listing: Schema.String;
|
|
117
127
|
}>>;
|
|
118
128
|
/** Stageable tool names the catalog lists: `pinned` ones, then the others (never `search` or
|
|
@@ -122,24 +132,24 @@ declare const CodeModeCatalogSummary: Schema.Struct<{
|
|
|
122
132
|
readonly listed: Schema.$Array<Schema.String>;
|
|
123
133
|
}>;
|
|
124
134
|
}>;
|
|
125
|
-
type CodeModeCatalogSummary = typeof CodeModeCatalogSummary.Type;
|
|
135
|
+
export type CodeModeCatalogSummary = typeof CodeModeCatalogSummary.Type;
|
|
126
136
|
/**
|
|
127
137
|
* The catalog of one resolution: every namespace with its tool count and description, and the
|
|
128
138
|
* listing of the tools the inline budget (or `pinned`) places. `search` and stage-only tools are
|
|
129
139
|
* counted, never listed.
|
|
130
140
|
*/
|
|
131
|
-
declare const summarizeCodeModeCatalog: (input: {
|
|
141
|
+
export declare const summarizeCodeModeCatalog: (input: {
|
|
132
142
|
readonly tools: ReadonlyArray<NestedTool>;
|
|
133
143
|
readonly staging?: CodeModeStagingDescription;
|
|
134
144
|
readonly inlineBudget?: number;
|
|
135
145
|
}) => CodeModeCatalogSummary;
|
|
136
146
|
/** The full catalog text of an instruction message. */
|
|
137
|
-
declare const renderCodeModeCatalog: (summary: CodeModeCatalogSummary) => string;
|
|
147
|
+
export declare const renderCodeModeCatalog: (summary: CodeModeCatalogSummary) => string;
|
|
138
148
|
/**
|
|
139
149
|
* The host instruction of the code mode catalog: its state is the encoded summary, and its render
|
|
140
150
|
* the full catalog (every change renders it whole, see `RunInstruction.render`) or a removal notice.
|
|
141
151
|
*/
|
|
142
|
-
declare const codeModeCatalogInstruction: (input: {
|
|
152
|
+
export declare const codeModeCatalogInstruction: (input: {
|
|
143
153
|
readonly tools: ReadonlyArray<NestedTool>;
|
|
144
154
|
readonly staging?: CodeModeStagingDescription;
|
|
145
155
|
readonly inlineBudget?: number;
|
|
@@ -148,10 +158,8 @@ declare const codeModeCatalogInstruction: (input: {
|
|
|
148
158
|
* The code mode description when the catalog is delivered as an instruction: invariant across
|
|
149
159
|
* catalog changes (only staging availability adds the `stage()` line).
|
|
150
160
|
*/
|
|
151
|
-
declare const renderCodeModeInstructedDescription: (input: {
|
|
161
|
+
export declare const renderCodeModeInstructedDescription: (input: {
|
|
152
162
|
readonly store?: boolean;
|
|
153
163
|
readonly staging?: CodeModeStagingDescription;
|
|
154
164
|
}) => string;
|
|
155
|
-
//#endregion
|
|
156
|
-
export { CodeModeCatalogSummary, CodeModeCatalogTool, CodeModeDescriptionInput, CodeModeListing, CodeModeStagingDescription, CodeModeToolExposure, codeModeCallLabels, codeModeCatalog, codeModeCatalogInstruction, codeModeCatalogInstructionKey, codeModeStageOnlyCatalog, codeModeToolSignature, defaultCodeModeInlineBudget, describeCodeModeTool, estimateCodeModeTokens, findCodeModeTool, maxCodeModeSearchSignatureChars, renderCodeModeCatalog, renderCodeModeDescription, renderCodeModeInstructedDescription, selectCodeModeListing, summarizeCodeModeCatalog };
|
|
157
165
|
//# sourceMappingURL=catalog.d.mts.map
|
package/dist/catalog.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.d.mts","names":[],"sources":["../src/catalog.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"catalog.d.mts","names":[],"sources":["../src/catalog.ts"],"mappings":";;;;;;;;YAkBY;;YAGA;;WAED;;WAEA;;;;;;WAMA;;WAEA;;WAEA;WACA;WACA,aAAa;;WAEb,cAAc;;WAEd;WACA,UAAU;;;;;;;;;qBAYR,qBAAkB,OAAW,0BAAwB;;qBAerD,kBAAe,OACnB,cAAc,gBACpB,cAAc;;;;;;;qBA8BJ,2BAAwB,WACxB,cAAc,gBACxB,cAAc;;qBAoBJ;;qBAGA,yBAAsB;YA4DvB;;;;WAID,QAAQ,cAAc;;WAEtB,oBAAoB;;;;;;;;;qBAUlB,wBAAqB,SACvB,cAAc,sBAAoB,mBAE1C;;YAqIS;WACD,OAAO,cAAc;WACrB;;YAGC;WACD,OAAO,cAAc;WACrB;;WAEA;;WAEA,UAAU;;;;;;;;;;;;qBAaR,4BAAyB,OAAW;;qBAmCpC;;;;;;qBAkCA,wBAAqB,MAAU;;;;;qBAa/B,uBAAoB,MAAU;;;;;;qBAc9B,mBAAgB,SAClB,cAAc,sBAAoB,iBAE1C;;qBAMU;;qBAcA,wBAAsB,OAAA;;;;;;;;;;;;;;;;;;YAUvB,gCAAgC,uBAAuB;;;;;;qBAqBtD,2BAAwB;WAC1B,OAAO,cAAc;WACrB,UAAU;WACV;MACP;;qBA6CS,wBAAqB,SAAa;;;;;qBAelC,6BAA0B;WAC5B,OAAO,cAAc;WACrB,UAAU;WACV;MACP;;;;;qBAuBS,sCAAmC;WACrC;WACA,UAAU"}
|
package/dist/catalog.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { Option, Predicate } from "effect";
|
|
|
2
2
|
import * as Schema from "effect/Schema";
|
|
3
3
|
import { renderDeclarations, renderToolOutputType, renderToolSample, schemaToType, toCodemodeIdentifier } from "@earendil-works/pi-codemode/declarations";
|
|
4
4
|
import { isDeferredTool, toolDiscovery } from "@yolk-sdk/agent/protocol";
|
|
5
|
-
|
|
5
|
+
// src/catalog.ts
|
|
6
6
|
const textOutputSchema = { type: "string" };
|
|
7
7
|
/**
|
|
8
8
|
* The call label of each tool name, in order, as pi binds `tools`: each tool takes
|
|
@@ -197,7 +197,9 @@ const unlistedToolsLine = "More tools may be callable than are listed here: find
|
|
|
197
197
|
* tool exists.
|
|
198
198
|
*/
|
|
199
199
|
const renderCodeModeDescription = (input) => {
|
|
200
|
-
const
|
|
200
|
+
const catalog = codeModeCatalog(input.tools);
|
|
201
|
+
const listing = selectCodeModeListing(catalog, input.inlineBudget ?? 3e3);
|
|
202
|
+
const sections = [...groupByNamespace(listing.listed.map((tool) => ({ tool })))].map(([namespace, items]) => namespaceSection(namespace, items.map((item) => item.tool)));
|
|
201
203
|
const staging = input.staging !== void 0 && input.staging.tools.length > 0 ? input.staging : void 0;
|
|
202
204
|
const stageableNames = staging === void 0 ? {
|
|
203
205
|
pinned: [],
|
|
@@ -293,7 +295,8 @@ const namespaceListing = (tools) => {
|
|
|
293
295
|
const summarizeCodeModeCatalog = (input) => {
|
|
294
296
|
const catalog = codeModeCatalog(input.tools);
|
|
295
297
|
const stageOnly = input.staging === void 0 ? [] : codeModeStageOnlyCatalog(input.staging.tools);
|
|
296
|
-
const
|
|
298
|
+
const listing = selectCodeModeListing(catalog, input.inlineBudget ?? 3e3);
|
|
299
|
+
const listedByNamespace = groupByNamespace(listing.listed.map((tool) => ({ tool })));
|
|
297
300
|
return {
|
|
298
301
|
namespaces: [...groupByNamespace([...catalog, ...stageOnly].map((tool) => ({ tool })))].map(([name, items]) => {
|
|
299
302
|
const shown = (listedByNamespace.get(name) ?? []).map((item) => item.tool);
|
|
@@ -356,7 +359,6 @@ const renderCodeModeInstructedDescription = (input) => [
|
|
|
356
359
|
].join("\n"),
|
|
357
360
|
"The tools scripts can call are in the \"Code mode catalog\" (namespaces, tool counts and listed tools; the latest one applies). Find the others with `await searchTools(query, { namespace? })` (each hit has its call signature); call the tool you choose in your next script, and call a tool whose exact name you already know directly, without searching."
|
|
358
361
|
].join("\n\n");
|
|
359
|
-
//#endregion
|
|
360
362
|
export { CodeModeCatalogSummary, codeModeCallLabels, codeModeCatalog, codeModeCatalogInstruction, codeModeCatalogInstructionKey, codeModeStageOnlyCatalog, codeModeToolSignature, defaultCodeModeInlineBudget, describeCodeModeTool, estimateCodeModeTokens, findCodeModeTool, maxCodeModeSearchSignatureChars, renderCodeModeCatalog, renderCodeModeDescription, renderCodeModeInstructedDescription, selectCodeModeListing, summarizeCodeModeCatalog };
|
|
361
363
|
|
|
362
364
|
//# sourceMappingURL=catalog.mjs.map
|
package/dist/catalog.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.mjs","names":[],"sources":["../src/catalog.ts"],"sourcesContent":["import { Option, Predicate } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport {\n renderDeclarations,\n renderToolOutputType,\n renderToolSample,\n schemaToType,\n toCodemodeIdentifier\n} from '@earendil-works/pi-codemode/declarations'\nimport { isDeferredTool, toolDiscovery } from '@yolk-sdk/agent/protocol'\nimport type { RunInstruction } from '@yolk-sdk/agent/loop'\nimport type { NestedTool } from '@yolk-sdk/agent/tools'\nimport type { CodeModeJsonSchema } from './executor.ts'\n\n/** How a nested tool reaches scripts: `all` tools are also direct model tools; `listed` and\n * `search` are the two discovery modes of `codemode`-only tools; `stage` marks a stageable tool\n * (approval-gated, ADR 0007): found by search, never callable, only passed to `stage()`.\n */\nexport type CodeModeToolExposure = 'all' | 'listed' | 'search' | 'pinned' | 'stage'\n\n/** One nested tool as scripts see it. */\nexport type CodeModeCatalogTool = {\n /** Raw tool name; scripts may call `tools[\"<name>\"](args)`. */\n readonly name: string\n /** Identifier for `tools.<identifier>(args)` (invalid identifier characters become `_`). */\n readonly identifier: string\n /**\n * How scripts call this tool, used to prefix its rejections: `tools.<identifier>`, or\n * `tools[\"<name>\"]` when an earlier tool already has the identifier (see `codeModeCallLabels`;\n * when the name is taken too, the tool is unreachable and the label only names it).\n */\n readonly callLabel: string\n /** The tool's `ToolModule.id`. */\n readonly namespace: string\n /** The module's `ToolModule.description`, when set. */\n readonly namespaceDescription?: string\n readonly description: string\n readonly inputSchema: CodeModeJsonSchema\n /** The declared output schema, or `{ type: 'string' }` for text results. */\n readonly outputSchema: CodeModeJsonSchema\n /** True when the tool declares an output schema (calls resolve to `structuredContent`). */\n readonly structured: boolean\n readonly exposure: CodeModeToolExposure\n}\n\nconst textOutputSchema: CodeModeJsonSchema = { type: 'string' }\n\n/**\n * The call label of each tool name, in order, as pi binds `tools`: each tool takes\n * `tools[<identifier>]` unless an earlier tool holds that key (first tool wins), then\n * `tools[<name>]` if still free. The label is `tools.<identifier>` for the tool that holds its\n * identifier, otherwise `tools[\"<name>\"]`. The executor guard and the host rejection prefix share\n * it, so both name a call the same way.\n */\nexport const codeModeCallLabels = (names: ReadonlyArray<string>): ReadonlyArray<string> => {\n const bound = new Set<string>()\n\n return names.map(name => {\n const identifier = toCodemodeIdentifier(name)\n const ownsIdentifier = !bound.has(identifier)\n\n bound.add(identifier)\n bound.add(name)\n\n return ownsIdentifier ? `tools.${identifier}` : `tools[${JSON.stringify(name)}]`\n })\n}\n\n/** Catalog of nested tools in resolution order. */\nexport const codeModeCatalog = (\n tools: ReadonlyArray<NestedTool>\n): ReadonlyArray<CodeModeCatalogTool> => {\n const labels = codeModeCallLabels(tools.map(({ def }) => def.name))\n\n return tools.map(({ def, moduleId, moduleDescription }, index) => {\n const tool: CodeModeCatalogTool = {\n name: def.name,\n identifier: toCodemodeIdentifier(def.name),\n callLabel: labels[index] ?? `tools[${JSON.stringify(def.name)}]`,\n namespace: moduleId,\n description: def.description,\n inputSchema: def.parameters,\n outputSchema: def.outputSchema ?? textOutputSchema,\n structured: def.outputSchema !== undefined,\n // A deferred tool's declaration is not in model context until activated: scripts find it\n // by search like a codemode-only `search` tool (ADR 0007).\n exposure: toolDiscovery(def) ?? (isDeferredTool(def) ? 'search' : 'all')\n }\n\n return moduleDescription === undefined\n ? tool\n : { ...tool, namespaceDescription: moduleDescription }\n })\n}\n\n/**\n * Catalog entries of the stageable tools (ADR 0007). Stageable tools are approval-gated, so scripts\n * can only `stage()` them whatever their `callableBy` (stage-only `codemode` ones are also never\n * declared to the model): searchable and describable, never callable (no `tools` binding), so\n * their call label is the `stage()` call that records them.\n */\nexport const codeModeStageOnlyCatalog = (\n stageable: ReadonlyArray<NestedTool>\n): ReadonlyArray<CodeModeCatalogTool> =>\n stageable.map(({ def, moduleId, moduleDescription }) => {\n const tool: CodeModeCatalogTool = {\n name: def.name,\n identifier: toCodemodeIdentifier(def.name),\n callLabel: `stage(${JSON.stringify(def.name)})`,\n namespace: moduleId,\n description: def.description,\n inputSchema: def.parameters,\n outputSchema: def.outputSchema ?? textOutputSchema,\n structured: def.outputSchema !== undefined,\n exposure: 'stage'\n }\n\n return moduleDescription === undefined\n ? tool\n : { ...tool, namespaceDescription: moduleDescription }\n })\n\n/** Default inline budget of the nested tool listing, in estimated tokens. */\nexport const defaultCodeModeInlineBudget = 3000\n\n/** Estimated tokens of a text: four characters per token, rounded up. */\nexport const estimateCodeModeTokens = (text: string): number => Math.ceil(text.length / 4)\n\nconst maxShortTypeChars = 60\n\nconst shortType = (schema: CodeModeJsonSchema): string => {\n const rendered = renderToolOutputType(schema)\n\n if (rendered.length <= maxShortTypeChars) return rendered\n\n if (!Predicate.isBoolean(schema)) {\n if (schema.type === 'array') return 'Array<unknown>'\n\n if (schema.type === 'object') return 'object'\n }\n\n return 'unknown'\n}\n\n// Declarations only read names, descriptions, and schemas; `execute` is never called.\nconst declarationTool = (tool: CodeModeCatalogTool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n outputSchema: tool.outputSchema,\n execute: () => undefined\n})\n\nconst directToolLine = (tool: CodeModeCatalogTool) =>\n `- \\`tools.${tool.identifier}(args)\\` takes the arguments of the \\`${tool.name}\\` tool and resolves to \\`${shortType(tool.outputSchema)}\\`.`\n\nconst declarationMembers = (tools: ReadonlyArray<CodeModeCatalogTool>) =>\n renderDeclarations({ tools: tools.map(declarationTool) })\n\ntype Candidate = {\n readonly tool: CodeModeCatalogTool\n readonly index: number\n readonly cost: number\n}\n\nconst candidateCost = (tool: CodeModeCatalogTool) =>\n estimateCodeModeTokens(declarationMembers([tool]))\n\nconst groupByNamespace = <A extends { readonly tool: CodeModeCatalogTool }>(\n items: ReadonlyArray<A>\n): ReadonlyMap<string, ReadonlyArray<A>> => {\n const groups = new Map<string, Array<A>>()\n\n for (const item of items) {\n const group = groups.get(item.tool.namespace)\n\n if (group === undefined) {\n groups.set(item.tool.namespace, [item])\n } else {\n group.push(item)\n }\n }\n\n return groups\n}\n\nexport type CodeModeListing = {\n /** Tools placed in the description, in catalog order: every `all` tool, and the `listed` tools\n * that fit the budget.\n */\n readonly listed: ReadonlyArray<CodeModeCatalogTool>\n /** Namespaces (catalog order) with callable tools the description does not list. */\n readonly unlistedNamespaces: ReadonlyArray<string>\n}\n\n/**\n * Chooses the tools the description lists. `all` tools are always placed, outside the budget\n * (the model already has their declarations), and so are `pinned` tools. `listed` tools fill\n * `budget` estimated tokens fairly across namespaces: each round, every namespace still in play\n * places its cheapest remaining tool; a namespace whose next tool does not fit drops out. `search`\n * tools are never candidates.\n */\nexport const selectCodeModeListing = (\n catalog: ReadonlyArray<CodeModeCatalogTool>,\n budget: number\n): CodeModeListing => {\n const candidates = catalog.flatMap((tool, index): ReadonlyArray<Candidate> =>\n tool.exposure === 'listed' ? [{ tool, index, cost: candidateCost(tool) }] : []\n )\n\n const queues = new Map(\n [...groupByNamespace(candidates)].map(([namespace, group]) => [\n namespace,\n [...group].sort((left, right) => left.cost - right.cost || left.index - right.index)\n ])\n )\n\n const placed = new Set(\n catalog.flatMap((tool, index) =>\n tool.exposure === 'all' || tool.exposure === 'pinned' ? [index] : []\n )\n )\n\n const inPlay = new Set(queues.keys())\n let remaining = budget\n\n while (inPlay.size > 0) {\n for (const [namespace, queue] of queues) {\n if (!inPlay.has(namespace)) continue\n\n const next = queue.shift()\n\n if (next === undefined || next.cost > remaining) {\n inPlay.delete(namespace)\n continue\n }\n\n placed.add(next.index)\n remaining -= next.cost\n }\n }\n\n const unlisted = new Set(\n catalog.flatMap((tool, index) => (placed.has(index) ? [] : [tool.namespace]))\n )\n\n return {\n listed: catalog.filter((_, index) => placed.has(index)),\n unlistedNamespaces: [...new Set(catalog.map(tool => tool.namespace))].filter(namespace =>\n unlisted.has(namespace)\n )\n }\n}\n\nconst intro = [\n 'Run a JavaScript script that calls tools and returns only what matters.',\n '`code` is the body of an async function: top-level `await` and `return` work. Write plain JavaScript; simple TypeScript annotations are stripped. There is no Node.js, network, filesystem, `require`, `fetch`, or timers.',\n 'Call tools as `await tools.<id>(args)`. Arguments must be plain JSON (no `NaN`, `undefined` array items, `Map`, or functions). A call resolves to the declared result type and rejects with an Error whose message starts with `tools.<id>:` when the tool fails. Calls still running when the script ends are cancelled, so await every call (use `Promise.all` for parallel calls).',\n 'A call that yields files also resolves `files: [{ fileId, name, mimeType, size }]`, added to an object result or as `{ text, files }`. Pass `fileId`s to other tools; file bytes never enter the script.',\n 'Only the script output and its return value come back to you: filter and aggregate inside the script and return a small JSON value.'\n].join('\\n')\n\nconst stageLine = (reviewToolName: string) =>\n `- \\`await stage(name, args)\\`: record a call of a stageable tool for review instead of running it; resolves to \\`{ staged: true, key, index }\\`. Nothing runs until a person approves the plan through the \\`${reviewToolName}\\` tool, which the result tells you how to call. Once a script stages, it may only run read tools; a script that already ran a write tool cannot stage. \\`searchTools\\` marks approval-gated tools \\`stageOnly: true\\`: they have no \\`tools\\` binding, only \\`stage()\\` them.`\n\n/** Stageable tool names listed in the description; the rest are summarized with a count. */\nconst maxListedStageableTools = 20\n\n/**\n * Stageable tools the description names: `pinned` ones first, never `search` or deferred ones\n * (whose declaration is not in model context; scripts find them by search, ADR 0007).\n */\ntype StageableNames = {\n readonly pinned: ReadonlyArray<string>\n readonly listed: ReadonlyArray<string>\n}\n\nconst listedStageableNames = (staging: CodeModeStagingDescription): StageableNames => ({\n pinned: staging.tools.flatMap(({ def }) => (toolDiscovery(def) === 'pinned' ? [def.name] : [])),\n listed: staging.tools.flatMap(({ def }) => {\n const discovery = toolDiscovery(def)\n\n return discovery === 'search' || discovery === 'pinned' || isDeferredTool(def) ? [] : [def.name]\n })\n})\n\nconst hasStageableNames = (names: StageableNames) =>\n names.pinned.length > 0 || names.listed.length > 0\n\n/** `pinned` names are always shown; the cap applies to the others. */\nconst stageableSection = (names: StageableNames) => {\n const room = Math.max(0, maxListedStageableTools - names.pinned.length)\n const hidden = names.listed.length - room\n\n return [\n '## Stageable tools',\n 'Approval-gated tools a script cannot call through `tools`, only stage with `await stage(\"<name>\", args)` (arguments as for the tool of the same name):',\n ...[...names.pinned, ...names.listed.slice(0, room)].map(name => `- \\`${name}\\``),\n ...(hidden > 0 ? [`- … and ${hidden} more (find them with \\`searchTools\\`).`] : [])\n ].join('\\n')\n}\n\nconst globalLines = (store: boolean) => [\n '- `text(value)` and `console.log(...values)`: append text to the output.',\n '- `image(dataUrl)`: append a base64 image (a `data:` URL or `{ type: \"image\", data, mimeType }`).',\n '- `exit()`: end the script successfully.',\n '- `ALL_TOOLS`: `{ name, description }` of every callable tool.',\n '- `await searchTools(query, { limit?, namespace? })`: find tools by topic; resolves to `Array<{ name: string; description: string; signature: string }>` (default limit 8). `signature` is the call with its argument and result types. When you already know the exact name of a tool (listed in this description or the catalog, returned by an earlier `searchTools`, or called earlier in this conversation), call it as `tools.<id>(args)` without searching. Otherwise search, return the hits, and call the tool you choose in your next script. Never call a tool in the same script that found it. If a call fails on its arguments, read its `signature` (or `describeTool`) and retry.',\n '- `await describeTool(name)`: the full description and documented TypeScript declaration of a tool, or `undefined`; needed only when a signature is cut or unclear.',\n '- `await describeNamespace(name)`: `{ name, description?, tools: Array<{ name, description }> }` for a namespace, or `undefined`.',\n ...(store\n ? [\n '- `store(key, value)` and `load(key)`: keep JSON values (up to 256 KiB each) for later scripts; writes are saved only when the script succeeds. When fetched data is large, store it and return a summary, then filter it with `load()` in a later script instead of calling the tools again.'\n ]\n : [])\n]\n\nconst namespaceSection = (namespace: string, tools: ReadonlyArray<CodeModeCatalogTool>) => {\n const declared = tools.filter(tool => tool.exposure !== 'all')\n const direct = tools.filter(tool => tool.exposure === 'all')\n\n const description = tools.find(\n tool => tool.namespaceDescription !== undefined\n )?.namespaceDescription\n\n return [\n `### ${namespace}`,\n ...(description === undefined ? [] : [description]),\n ...(declared.length > 0 ? ['```ts', declarationMembers(declared), '```'] : []),\n ...direct.map(directToolLine)\n ].join('\\n')\n}\n\n// Fixed text: never derived from `search` tools or from which tools did not fit the budget.\nconst unlistedToolsLine =\n 'More tools may be callable than are listed here: find them with `await searchTools(query, { namespace? })` (each hit has its call signature) or `await describeNamespace(name)`; call the tool you choose in your next script, and call a tool whose exact name you already know directly, without searching.'\n\n/** Staged tool plans as the description shows them (`NestedToolStagingDescription`). */\nexport type CodeModeStagingDescription = {\n readonly tools: ReadonlyArray<NestedTool>\n readonly reviewToolName: string\n}\n\nexport type CodeModeDescriptionInput = {\n readonly tools: ReadonlyArray<NestedTool>\n readonly inlineBudget?: number\n /** Mention `store()`/`load()` persistence. */\n readonly store?: boolean\n /** Document `stage()` and list the stageable tools that are neither `search` nor deferred. */\n readonly staging?: CodeModeStagingDescription\n}\n\n/**\n * The code mode tool description: intro, globals one per line, then nested tools grouped by\n * namespace, then one fixed line pointing to `searchTools` and `describeNamespace`.\n * `all` tools get one line each outside the budget; `listed` tools are declared within the inline\n * budget; `search` tools never contribute, so adding or removing them (even whole namespaces of\n * them) leaves the text byte-identical. With `staging` (and stageable tools), `stage()` is listed\n * with the globals and the stageable tool names follow the nested tools; `search` and deferred\n * stageable tools are never named, so they leave the text byte-identical too once any stageable\n * tool exists.\n */\nexport const renderCodeModeDescription = (input: CodeModeDescriptionInput): string => {\n const catalog = codeModeCatalog(input.tools)\n\n const listing = selectCodeModeListing(catalog, input.inlineBudget ?? defaultCodeModeInlineBudget)\n\n const sections = [...groupByNamespace(listing.listed.map(tool => ({ tool })))].map(\n ([namespace, items]) =>\n namespaceSection(\n namespace,\n items.map(item => item.tool)\n )\n )\n\n const staging =\n input.staging !== undefined && input.staging.tools.length > 0 ? input.staging : undefined\n\n const stageableNames =\n staging === undefined ? { pinned: [], listed: [] } : listedStageableNames(staging)\n\n return [\n intro,\n [\n 'Globals:',\n ...globalLines(input.store === true),\n ...(staging === undefined ? [] : [stageLine(staging.reviewToolName)])\n ].join('\\n'),\n sections.length === 0\n ? 'Nested tools: none are listed here.'\n : ['## Nested tools by namespace', ...sections].join('\\n\\n'),\n ...(hasStageableNames(stageableNames) ? [stageableSection(stageableNames)] : []),\n unlistedToolsLine\n ].join('\\n\\n')\n}\n\n/** Longest `searchTools` signature, cut marker included (`describeTool` has the whole declaration). */\nexport const maxCodeModeSearchSignatureChars = 800\n\nconst signatureCutMarker = '… (describeTool for the full declaration)'\n\n// A rendered type on one line, without its description comments (`describeTool` keeps them). pi\n// puts every description line on its own `//` line and JSON-quotes keys and literals, so no other\n// line starts with `//`.\nconst compactText = (rendered: string) =>\n rendered\n .split('\\n')\n .map(line => line.trim())\n .filter(line => !line.startsWith('//'))\n .join(' ')\n\nconst compactResultType = (schema: CodeModeJsonSchema) => {\n const rendered = compactText(renderToolOutputType(schema))\n\n return rendered.length <= maxShortTypeChars ? rendered : shortType(schema)\n}\n\n// Cuts at a code point boundary: never leaves half of a surrogate pair.\nconst cutSignature = (signature: string) => {\n const end = maxCodeModeSearchSignatureChars - signatureCutMarker.length\n const kept = signature.slice(0, end)\n const last = kept.charCodeAt(kept.length - 1)\n\n return `${last >= 0xd800 && last <= 0xdbff ? kept.slice(0, -1) : kept}${signatureCutMarker}`\n}\n\n/**\n * The call a `searchTools` hit shows, enough to call the tool without `describeTool`:\n * `tools.<id>(args): Promise<result>`, or `stage(\"<name>\", args)` for a stageable tool. Bounded:\n * a long one ends with a pointer to `describeTool`.\n */\nexport const codeModeToolSignature = (tool: CodeModeCatalogTool): string => {\n const signature =\n tool.exposure === 'stage'\n ? `stage(${JSON.stringify(tool.name)}, ${compactText(schemaToType(tool.inputSchema))})`\n : `${tool.callLabel}(${compactText(schemaToType(tool.inputSchema))}): Promise<${compactResultType(tool.outputSchema)}>`\n\n return signature.length <= maxCodeModeSearchSignatureChars ? signature : cutSignature(signature)\n}\n\n/**\n * `describeTool` text: the description and TypeScript declaration of one tool. A stage-only tool\n * has no `tools` binding, so it is described as the `stage()` call that records it.\n */\nexport const describeCodeModeTool = (tool: CodeModeCatalogTool): string =>\n tool.exposure === 'stage'\n ? [\n tool.description,\n `Stage-only (approval-gated): record a call with \\`await stage(${JSON.stringify(tool.name)}, args)\\`; it runs only after a person approves the plan.`,\n `args: ${schemaToType(tool.inputSchema)}`\n ].join('\\n\\n')\n : renderToolSample(declarationTool(tool))\n\n/**\n * Finds a tool by identifier or raw name. A stageable tool's exact raw name wins first: it has no\n * binding, so a callable tool sharing its identifier (`archive-resource` vs `archive_resource`)\n * must not answer for it; callable lookups keep identifier precedence, as their bindings do.\n */\nexport const findCodeModeTool = (\n catalog: ReadonlyArray<CodeModeCatalogTool>,\n name: string\n): CodeModeCatalogTool | undefined =>\n catalog.find(tool => tool.exposure === 'stage' && tool.name === name) ??\n catalog.find(tool => tool.identifier === name) ??\n catalog.find(tool => tool.name === name)\n\n/** The instruction key of the code mode catalog (`catalog: 'instructions'`, ADR 0007). */\nexport const codeModeCatalogInstructionKey = 'yolk.codemode.catalog'\n\nconst CodeModeCatalogNamespace = Schema.Struct({\n name: Schema.String,\n description: Schema.optional(Schema.String),\n /** Every tool scripts reach in the namespace: callable and stage-only. */\n count: Schema.Number,\n /** Tools the listing shows. */\n shown: Schema.Number,\n /** The rendered declarations and direct tool lines of the shown tools. */\n listing: Schema.String\n})\n\n/** The catalog an instruction message records as its state (JSON, never model-visible). */\nexport const CodeModeCatalogSummary = Schema.Struct({\n namespaces: Schema.Array(CodeModeCatalogNamespace),\n /** Stageable tool names the catalog lists: `pinned` ones, then the others (never `search` or\n * deferred ones). */\n stageable: Schema.Struct({\n pinned: Schema.Array(Schema.String),\n listed: Schema.Array(Schema.String)\n })\n})\n\nexport type CodeModeCatalogSummary = typeof CodeModeCatalogSummary.Type\n\nconst decodeCatalogSummary = Schema.decodeUnknownOption(CodeModeCatalogSummary)\n\nconst encodeCatalogSummary = Schema.encodeOption(CodeModeCatalogSummary)\n\nconst namespaceListing = (tools: ReadonlyArray<CodeModeCatalogTool>) => {\n const declared = tools.filter(tool => tool.exposure !== 'all')\n const direct = tools.filter(tool => tool.exposure === 'all')\n\n return [\n ...(declared.length > 0 ? ['```ts', declarationMembers(declared), '```'] : []),\n ...direct.map(directToolLine)\n ].join('\\n')\n}\n\n/**\n * The catalog of one resolution: every namespace with its tool count and description, and the\n * listing of the tools the inline budget (or `pinned`) places. `search` and stage-only tools are\n * counted, never listed.\n */\nexport const summarizeCodeModeCatalog = (input: {\n readonly tools: ReadonlyArray<NestedTool>\n readonly staging?: CodeModeStagingDescription\n readonly inlineBudget?: number\n}): CodeModeCatalogSummary => {\n const catalog = codeModeCatalog(input.tools)\n const stageOnly = input.staging === undefined ? [] : codeModeStageOnlyCatalog(input.staging.tools)\n const listing = selectCodeModeListing(catalog, input.inlineBudget ?? defaultCodeModeInlineBudget)\n const listedByNamespace = groupByNamespace(listing.listed.map(tool => ({ tool })))\n\n const namespaces = [...groupByNamespace([...catalog, ...stageOnly].map(tool => ({ tool })))].map(\n ([name, items]) => {\n const shown = (listedByNamespace.get(name) ?? []).map(item => item.tool)\n\n const description = items.find(item => item.tool.namespaceDescription !== undefined)?.tool\n .namespaceDescription\n\n const namespace = {\n name,\n count: items.length,\n shown: shown.length,\n listing: namespaceListing(shown)\n }\n\n return description === undefined ? namespace : { ...namespace, description }\n }\n )\n\n return {\n namespaces,\n stageable:\n input.staging === undefined ? { pinned: [], listed: [] } : listedStageableNames(input.staging)\n }\n}\n\nconst namespaceLine = (namespace: CodeModeCatalogSummary['namespaces'][number]) => {\n const count = namespace.count === 1 ? '1 tool' : `${namespace.count} tools`\n\n const label =\n namespace.shown === namespace.count\n ? count\n : namespace.shown === 0\n ? `${count}, none listed`\n : `${count}, ${namespace.shown} listed`\n\n return `- \\`${namespace.name}\\` (${label})${namespace.description === undefined ? '' : `: ${namespace.description}`}`\n}\n\n/** The full catalog text of an instruction message. */\nexport const renderCodeModeCatalog = (summary: CodeModeCatalogSummary): string =>\n [\n '# Code mode catalog',\n 'Tools `codemode` scripts can call, by namespace; the latest catalog in the conversation replaces any earlier one. Call a listed tool as `await tools.<id>(args)`; find the others with `await searchTools(query, { namespace })` (each hit has its call signature); call the tool you choose in your next script, and call a tool whose exact name you already know directly, without searching.',\n ['## Namespaces', ...summary.namespaces.map(namespaceLine)].join('\\n'),\n ...summary.namespaces.flatMap(namespace =>\n namespace.listing.length === 0 ? [] : [`### ${namespace.name}\\n${namespace.listing}`]\n ),\n ...(hasStageableNames(summary.stageable) ? [stageableSection(summary.stageable)] : [])\n ].join('\\n\\n')\n\n/**\n * The host instruction of the code mode catalog: its state is the encoded summary, and its render\n * the full catalog (every change renders it whole, see `RunInstruction.render`) or a removal notice.\n */\nexport const codeModeCatalogInstruction = (input: {\n readonly tools: ReadonlyArray<NestedTool>\n readonly staging?: CodeModeStagingDescription\n readonly inlineBudget?: number\n}): RunInstruction => {\n const summary = summarizeCodeModeCatalog(input)\n\n return {\n key: codeModeCatalogInstructionKey,\n state:\n summary.namespaces.length === 0\n ? undefined\n : Option.getOrUndefined(encodeCatalogSummary(summary)),\n render: current => {\n const decoded = current === undefined ? Option.none() : decodeCatalogSummary(current)\n\n return Option.isNone(decoded)\n ? 'Code mode tools are no longer available: do not call previously listed code mode tools.'\n : renderCodeModeCatalog(decoded.value)\n }\n }\n}\n\n/**\n * The code mode description when the catalog is delivered as an instruction: invariant across\n * catalog changes (only staging availability adds the `stage()` line).\n */\nexport const renderCodeModeInstructedDescription = (input: {\n readonly store?: boolean\n readonly staging?: CodeModeStagingDescription\n}): string =>\n [\n intro,\n [\n 'Globals:',\n ...globalLines(input.store === true),\n ...(input.staging === undefined ? [] : [stageLine(input.staging.reviewToolName)])\n ].join('\\n'),\n 'The tools scripts can call are in the \"Code mode catalog\" (namespaces, tool counts and listed tools; the latest one applies). Find the others with `await searchTools(query, { namespace? })` (each hit has its call signature); call the tool you choose in your next script, and call a tool whose exact name you already know directly, without searching.'\n ].join('\\n\\n')\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"catalog.mjs","names":[],"sources":["../src/catalog.ts"],"sourcesContent":["import { Option, Predicate } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport {\n renderDeclarations,\n renderToolOutputType,\n renderToolSample,\n schemaToType,\n toCodemodeIdentifier\n} from '@earendil-works/pi-codemode/declarations'\nimport { isDeferredTool, toolDiscovery } from '@yolk-sdk/agent/protocol'\nimport type { RunInstruction } from '@yolk-sdk/agent/loop'\nimport type { NestedTool } from '@yolk-sdk/agent/tools'\nimport type { CodeModeJsonSchema } from './executor.ts'\n\n/** How a nested tool reaches scripts: `all` tools are also direct model tools; `listed` and\n * `search` are the two discovery modes of `codemode`-only tools; `stage` marks a stageable tool\n * (approval-gated, ADR 0007): found by search, never callable, only passed to `stage()`.\n */\nexport type CodeModeToolExposure = 'all' | 'listed' | 'search' | 'pinned' | 'stage'\n\n/** One nested tool as scripts see it. */\nexport type CodeModeCatalogTool = {\n /** Raw tool name; scripts may call `tools[\"<name>\"](args)`. */\n readonly name: string\n /** Identifier for `tools.<identifier>(args)` (invalid identifier characters become `_`). */\n readonly identifier: string\n /**\n * How scripts call this tool, used to prefix its rejections: `tools.<identifier>`, or\n * `tools[\"<name>\"]` when an earlier tool already has the identifier (see `codeModeCallLabels`;\n * when the name is taken too, the tool is unreachable and the label only names it).\n */\n readonly callLabel: string\n /** The tool's `ToolModule.id`. */\n readonly namespace: string\n /** The module's `ToolModule.description`, when set. */\n readonly namespaceDescription?: string\n readonly description: string\n readonly inputSchema: CodeModeJsonSchema\n /** The declared output schema, or `{ type: 'string' }` for text results. */\n readonly outputSchema: CodeModeJsonSchema\n /** True when the tool declares an output schema (calls resolve to `structuredContent`). */\n readonly structured: boolean\n readonly exposure: CodeModeToolExposure\n}\n\nconst textOutputSchema: CodeModeJsonSchema = { type: 'string' }\n\n/**\n * The call label of each tool name, in order, as pi binds `tools`: each tool takes\n * `tools[<identifier>]` unless an earlier tool holds that key (first tool wins), then\n * `tools[<name>]` if still free. The label is `tools.<identifier>` for the tool that holds its\n * identifier, otherwise `tools[\"<name>\"]`. The executor guard and the host rejection prefix share\n * it, so both name a call the same way.\n */\nexport const codeModeCallLabels = (names: ReadonlyArray<string>): ReadonlyArray<string> => {\n const bound = new Set<string>()\n\n return names.map(name => {\n const identifier = toCodemodeIdentifier(name)\n const ownsIdentifier = !bound.has(identifier)\n\n bound.add(identifier)\n bound.add(name)\n\n return ownsIdentifier ? `tools.${identifier}` : `tools[${JSON.stringify(name)}]`\n })\n}\n\n/** Catalog of nested tools in resolution order. */\nexport const codeModeCatalog = (\n tools: ReadonlyArray<NestedTool>\n): ReadonlyArray<CodeModeCatalogTool> => {\n const labels = codeModeCallLabels(tools.map(({ def }) => def.name))\n\n return tools.map(({ def, moduleId, moduleDescription }, index) => {\n const tool: CodeModeCatalogTool = {\n name: def.name,\n identifier: toCodemodeIdentifier(def.name),\n callLabel: labels[index] ?? `tools[${JSON.stringify(def.name)}]`,\n namespace: moduleId,\n description: def.description,\n inputSchema: def.parameters,\n outputSchema: def.outputSchema ?? textOutputSchema,\n structured: def.outputSchema !== undefined,\n // A deferred tool's declaration is not in model context until activated: scripts find it\n // by search like a codemode-only `search` tool (ADR 0007).\n exposure: toolDiscovery(def) ?? (isDeferredTool(def) ? 'search' : 'all')\n }\n\n return moduleDescription === undefined\n ? tool\n : { ...tool, namespaceDescription: moduleDescription }\n })\n}\n\n/**\n * Catalog entries of the stageable tools (ADR 0007). Stageable tools are approval-gated, so scripts\n * can only `stage()` them whatever their `callableBy` (stage-only `codemode` ones are also never\n * declared to the model): searchable and describable, never callable (no `tools` binding), so\n * their call label is the `stage()` call that records them.\n */\nexport const codeModeStageOnlyCatalog = (\n stageable: ReadonlyArray<NestedTool>\n): ReadonlyArray<CodeModeCatalogTool> =>\n stageable.map(({ def, moduleId, moduleDescription }) => {\n const tool: CodeModeCatalogTool = {\n name: def.name,\n identifier: toCodemodeIdentifier(def.name),\n callLabel: `stage(${JSON.stringify(def.name)})`,\n namespace: moduleId,\n description: def.description,\n inputSchema: def.parameters,\n outputSchema: def.outputSchema ?? textOutputSchema,\n structured: def.outputSchema !== undefined,\n exposure: 'stage'\n }\n\n return moduleDescription === undefined\n ? tool\n : { ...tool, namespaceDescription: moduleDescription }\n })\n\n/** Default inline budget of the nested tool listing, in estimated tokens. */\nexport const defaultCodeModeInlineBudget = 3000\n\n/** Estimated tokens of a text: four characters per token, rounded up. */\nexport const estimateCodeModeTokens = (text: string): number => Math.ceil(text.length / 4)\n\nconst maxShortTypeChars = 60\n\nconst shortType = (schema: CodeModeJsonSchema): string => {\n const rendered = renderToolOutputType(schema)\n\n if (rendered.length <= maxShortTypeChars) return rendered\n\n if (!Predicate.isBoolean(schema)) {\n if (schema.type === 'array') return 'Array<unknown>'\n\n if (schema.type === 'object') return 'object'\n }\n\n return 'unknown'\n}\n\n// Declarations only read names, descriptions, and schemas; `execute` is never called.\nconst declarationTool = (tool: CodeModeCatalogTool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n outputSchema: tool.outputSchema,\n execute: () => undefined\n})\n\nconst directToolLine = (tool: CodeModeCatalogTool) =>\n `- \\`tools.${tool.identifier}(args)\\` takes the arguments of the \\`${tool.name}\\` tool and resolves to \\`${shortType(tool.outputSchema)}\\`.`\n\nconst declarationMembers = (tools: ReadonlyArray<CodeModeCatalogTool>) =>\n renderDeclarations({ tools: tools.map(declarationTool) })\n\ntype Candidate = {\n readonly tool: CodeModeCatalogTool\n readonly index: number\n readonly cost: number\n}\n\nconst candidateCost = (tool: CodeModeCatalogTool) =>\n estimateCodeModeTokens(declarationMembers([tool]))\n\nconst groupByNamespace = <A extends { readonly tool: CodeModeCatalogTool }>(\n items: ReadonlyArray<A>\n): ReadonlyMap<string, ReadonlyArray<A>> => {\n const groups = new Map<string, Array<A>>()\n\n for (const item of items) {\n const group = groups.get(item.tool.namespace)\n\n if (group === undefined) {\n groups.set(item.tool.namespace, [item])\n } else {\n group.push(item)\n }\n }\n\n return groups\n}\n\nexport type CodeModeListing = {\n /** Tools placed in the description, in catalog order: every `all` tool, and the `listed` tools\n * that fit the budget.\n */\n readonly listed: ReadonlyArray<CodeModeCatalogTool>\n /** Namespaces (catalog order) with callable tools the description does not list. */\n readonly unlistedNamespaces: ReadonlyArray<string>\n}\n\n/**\n * Chooses the tools the description lists. `all` tools are always placed, outside the budget\n * (the model already has their declarations), and so are `pinned` tools. `listed` tools fill\n * `budget` estimated tokens fairly across namespaces: each round, every namespace still in play\n * places its cheapest remaining tool; a namespace whose next tool does not fit drops out. `search`\n * tools are never candidates.\n */\nexport const selectCodeModeListing = (\n catalog: ReadonlyArray<CodeModeCatalogTool>,\n budget: number\n): CodeModeListing => {\n const candidates = catalog.flatMap((tool, index): ReadonlyArray<Candidate> =>\n tool.exposure === 'listed' ? [{ tool, index, cost: candidateCost(tool) }] : []\n )\n\n const queues = new Map(\n [...groupByNamespace(candidates)].map(([namespace, group]) => [\n namespace,\n [...group].sort((left, right) => left.cost - right.cost || left.index - right.index)\n ])\n )\n\n const placed = new Set(\n catalog.flatMap((tool, index) =>\n tool.exposure === 'all' || tool.exposure === 'pinned' ? [index] : []\n )\n )\n\n const inPlay = new Set(queues.keys())\n let remaining = budget\n\n while (inPlay.size > 0) {\n for (const [namespace, queue] of queues) {\n if (!inPlay.has(namespace)) continue\n\n const next = queue.shift()\n\n if (next === undefined || next.cost > remaining) {\n inPlay.delete(namespace)\n continue\n }\n\n placed.add(next.index)\n remaining -= next.cost\n }\n }\n\n const unlisted = new Set(\n catalog.flatMap((tool, index) => (placed.has(index) ? [] : [tool.namespace]))\n )\n\n return {\n listed: catalog.filter((_, index) => placed.has(index)),\n unlistedNamespaces: [...new Set(catalog.map(tool => tool.namespace))].filter(namespace =>\n unlisted.has(namespace)\n )\n }\n}\n\nconst intro = [\n 'Run a JavaScript script that calls tools and returns only what matters.',\n '`code` is the body of an async function: top-level `await` and `return` work. Write plain JavaScript; simple TypeScript annotations are stripped. There is no Node.js, network, filesystem, `require`, `fetch`, or timers.',\n 'Call tools as `await tools.<id>(args)`. Arguments must be plain JSON (no `NaN`, `undefined` array items, `Map`, or functions). A call resolves to the declared result type and rejects with an Error whose message starts with `tools.<id>:` when the tool fails. Calls still running when the script ends are cancelled, so await every call (use `Promise.all` for parallel calls).',\n 'A call that yields files also resolves `files: [{ fileId, name, mimeType, size }]`, added to an object result or as `{ text, files }`. Pass `fileId`s to other tools; file bytes never enter the script.',\n 'Only the script output and its return value come back to you: filter and aggregate inside the script and return a small JSON value.'\n].join('\\n')\n\nconst stageLine = (reviewToolName: string) =>\n `- \\`await stage(name, args)\\`: record a call of a stageable tool for review instead of running it; resolves to \\`{ staged: true, key, index }\\`. Nothing runs until a person approves the plan through the \\`${reviewToolName}\\` tool, which the result tells you how to call. Once a script stages, it may only run read tools; a script that already ran a write tool cannot stage. \\`searchTools\\` marks approval-gated tools \\`stageOnly: true\\`: they have no \\`tools\\` binding, only \\`stage()\\` them.`\n\n/** Stageable tool names listed in the description; the rest are summarized with a count. */\nconst maxListedStageableTools = 20\n\n/**\n * Stageable tools the description names: `pinned` ones first, never `search` or deferred ones\n * (whose declaration is not in model context; scripts find them by search, ADR 0007).\n */\ntype StageableNames = {\n readonly pinned: ReadonlyArray<string>\n readonly listed: ReadonlyArray<string>\n}\n\nconst listedStageableNames = (staging: CodeModeStagingDescription): StageableNames => ({\n pinned: staging.tools.flatMap(({ def }) => (toolDiscovery(def) === 'pinned' ? [def.name] : [])),\n listed: staging.tools.flatMap(({ def }) => {\n const discovery = toolDiscovery(def)\n\n return discovery === 'search' || discovery === 'pinned' || isDeferredTool(def) ? [] : [def.name]\n })\n})\n\nconst hasStageableNames = (names: StageableNames) =>\n names.pinned.length > 0 || names.listed.length > 0\n\n/** `pinned` names are always shown; the cap applies to the others. */\nconst stageableSection = (names: StageableNames) => {\n const room = Math.max(0, maxListedStageableTools - names.pinned.length)\n const hidden = names.listed.length - room\n\n return [\n '## Stageable tools',\n 'Approval-gated tools a script cannot call through `tools`, only stage with `await stage(\"<name>\", args)` (arguments as for the tool of the same name):',\n ...[...names.pinned, ...names.listed.slice(0, room)].map(name => `- \\`${name}\\``),\n ...(hidden > 0 ? [`- … and ${hidden} more (find them with \\`searchTools\\`).`] : [])\n ].join('\\n')\n}\n\nconst globalLines = (store: boolean) => [\n '- `text(value)` and `console.log(...values)`: append text to the output.',\n '- `image(dataUrl)`: append a base64 image (a `data:` URL or `{ type: \"image\", data, mimeType }`).',\n '- `exit()`: end the script successfully.',\n '- `ALL_TOOLS`: `{ name, description }` of every callable tool.',\n '- `await searchTools(query, { limit?, namespace? })`: find tools by topic; resolves to `Array<{ name: string; description: string; signature: string }>` (default limit 8). `signature` is the call with its argument and result types. When you already know the exact name of a tool (listed in this description or the catalog, returned by an earlier `searchTools`, or called earlier in this conversation), call it as `tools.<id>(args)` without searching. Otherwise search, return the hits, and call the tool you choose in your next script. Never call a tool in the same script that found it. If a call fails on its arguments, read its `signature` (or `describeTool`) and retry.',\n '- `await describeTool(name)`: the full description and documented TypeScript declaration of a tool, or `undefined`; needed only when a signature is cut or unclear.',\n '- `await describeNamespace(name)`: `{ name, description?, tools: Array<{ name, description }> }` for a namespace, or `undefined`.',\n ...(store\n ? [\n '- `store(key, value)` and `load(key)`: keep JSON values (up to 256 KiB each) for later scripts; writes are saved only when the script succeeds. When fetched data is large, store it and return a summary, then filter it with `load()` in a later script instead of calling the tools again.'\n ]\n : [])\n]\n\nconst namespaceSection = (namespace: string, tools: ReadonlyArray<CodeModeCatalogTool>) => {\n const declared = tools.filter(tool => tool.exposure !== 'all')\n const direct = tools.filter(tool => tool.exposure === 'all')\n\n const description = tools.find(\n tool => tool.namespaceDescription !== undefined\n )?.namespaceDescription\n\n return [\n `### ${namespace}`,\n ...(description === undefined ? [] : [description]),\n ...(declared.length > 0 ? ['```ts', declarationMembers(declared), '```'] : []),\n ...direct.map(directToolLine)\n ].join('\\n')\n}\n\n// Fixed text: never derived from `search` tools or from which tools did not fit the budget.\nconst unlistedToolsLine =\n 'More tools may be callable than are listed here: find them with `await searchTools(query, { namespace? })` (each hit has its call signature) or `await describeNamespace(name)`; call the tool you choose in your next script, and call a tool whose exact name you already know directly, without searching.'\n\n/** Staged tool plans as the description shows them (`NestedToolStagingDescription`). */\nexport type CodeModeStagingDescription = {\n readonly tools: ReadonlyArray<NestedTool>\n readonly reviewToolName: string\n}\n\nexport type CodeModeDescriptionInput = {\n readonly tools: ReadonlyArray<NestedTool>\n readonly inlineBudget?: number\n /** Mention `store()`/`load()` persistence. */\n readonly store?: boolean\n /** Document `stage()` and list the stageable tools that are neither `search` nor deferred. */\n readonly staging?: CodeModeStagingDescription\n}\n\n/**\n * The code mode tool description: intro, globals one per line, then nested tools grouped by\n * namespace, then one fixed line pointing to `searchTools` and `describeNamespace`.\n * `all` tools get one line each outside the budget; `listed` tools are declared within the inline\n * budget; `search` tools never contribute, so adding or removing them (even whole namespaces of\n * them) leaves the text byte-identical. With `staging` (and stageable tools), `stage()` is listed\n * with the globals and the stageable tool names follow the nested tools; `search` and deferred\n * stageable tools are never named, so they leave the text byte-identical too once any stageable\n * tool exists.\n */\nexport const renderCodeModeDescription = (input: CodeModeDescriptionInput): string => {\n const catalog = codeModeCatalog(input.tools)\n\n const listing = selectCodeModeListing(catalog, input.inlineBudget ?? defaultCodeModeInlineBudget)\n\n const sections = [...groupByNamespace(listing.listed.map(tool => ({ tool })))].map(\n ([namespace, items]) =>\n namespaceSection(\n namespace,\n items.map(item => item.tool)\n )\n )\n\n const staging =\n input.staging !== undefined && input.staging.tools.length > 0 ? input.staging : undefined\n\n const stageableNames =\n staging === undefined ? { pinned: [], listed: [] } : listedStageableNames(staging)\n\n return [\n intro,\n [\n 'Globals:',\n ...globalLines(input.store === true),\n ...(staging === undefined ? [] : [stageLine(staging.reviewToolName)])\n ].join('\\n'),\n sections.length === 0\n ? 'Nested tools: none are listed here.'\n : ['## Nested tools by namespace', ...sections].join('\\n\\n'),\n ...(hasStageableNames(stageableNames) ? [stageableSection(stageableNames)] : []),\n unlistedToolsLine\n ].join('\\n\\n')\n}\n\n/** Longest `searchTools` signature, cut marker included (`describeTool` has the whole declaration). */\nexport const maxCodeModeSearchSignatureChars = 800\n\nconst signatureCutMarker = '… (describeTool for the full declaration)'\n\n// A rendered type on one line, without its description comments (`describeTool` keeps them). pi\n// puts every description line on its own `//` line and JSON-quotes keys and literals, so no other\n// line starts with `//`.\nconst compactText = (rendered: string) =>\n rendered\n .split('\\n')\n .map(line => line.trim())\n .filter(line => !line.startsWith('//'))\n .join(' ')\n\nconst compactResultType = (schema: CodeModeJsonSchema) => {\n const rendered = compactText(renderToolOutputType(schema))\n\n return rendered.length <= maxShortTypeChars ? rendered : shortType(schema)\n}\n\n// Cuts at a code point boundary: never leaves half of a surrogate pair.\nconst cutSignature = (signature: string) => {\n const end = maxCodeModeSearchSignatureChars - signatureCutMarker.length\n const kept = signature.slice(0, end)\n const last = kept.charCodeAt(kept.length - 1)\n\n return `${last >= 0xd800 && last <= 0xdbff ? kept.slice(0, -1) : kept}${signatureCutMarker}`\n}\n\n/**\n * The call a `searchTools` hit shows, enough to call the tool without `describeTool`:\n * `tools.<id>(args): Promise<result>`, or `stage(\"<name>\", args)` for a stageable tool. Bounded:\n * a long one ends with a pointer to `describeTool`.\n */\nexport const codeModeToolSignature = (tool: CodeModeCatalogTool): string => {\n const signature =\n tool.exposure === 'stage'\n ? `stage(${JSON.stringify(tool.name)}, ${compactText(schemaToType(tool.inputSchema))})`\n : `${tool.callLabel}(${compactText(schemaToType(tool.inputSchema))}): Promise<${compactResultType(tool.outputSchema)}>`\n\n return signature.length <= maxCodeModeSearchSignatureChars ? signature : cutSignature(signature)\n}\n\n/**\n * `describeTool` text: the description and TypeScript declaration of one tool. A stage-only tool\n * has no `tools` binding, so it is described as the `stage()` call that records it.\n */\nexport const describeCodeModeTool = (tool: CodeModeCatalogTool): string =>\n tool.exposure === 'stage'\n ? [\n tool.description,\n `Stage-only (approval-gated): record a call with \\`await stage(${JSON.stringify(tool.name)}, args)\\`; it runs only after a person approves the plan.`,\n `args: ${schemaToType(tool.inputSchema)}`\n ].join('\\n\\n')\n : renderToolSample(declarationTool(tool))\n\n/**\n * Finds a tool by identifier or raw name. A stageable tool's exact raw name wins first: it has no\n * binding, so a callable tool sharing its identifier (`archive-resource` vs `archive_resource`)\n * must not answer for it; callable lookups keep identifier precedence, as their bindings do.\n */\nexport const findCodeModeTool = (\n catalog: ReadonlyArray<CodeModeCatalogTool>,\n name: string\n): CodeModeCatalogTool | undefined =>\n catalog.find(tool => tool.exposure === 'stage' && tool.name === name) ??\n catalog.find(tool => tool.identifier === name) ??\n catalog.find(tool => tool.name === name)\n\n/** The instruction key of the code mode catalog (`catalog: 'instructions'`, ADR 0007). */\nexport const codeModeCatalogInstructionKey = 'yolk.codemode.catalog'\n\nconst CodeModeCatalogNamespace = Schema.Struct({\n name: Schema.String,\n description: Schema.optional(Schema.String),\n /** Every tool scripts reach in the namespace: callable and stage-only. */\n count: Schema.Number,\n /** Tools the listing shows. */\n shown: Schema.Number,\n /** The rendered declarations and direct tool lines of the shown tools. */\n listing: Schema.String\n})\n\n/** The catalog an instruction message records as its state (JSON, never model-visible). */\nexport const CodeModeCatalogSummary = Schema.Struct({\n namespaces: Schema.Array(CodeModeCatalogNamespace),\n /** Stageable tool names the catalog lists: `pinned` ones, then the others (never `search` or\n * deferred ones). */\n stageable: Schema.Struct({\n pinned: Schema.Array(Schema.String),\n listed: Schema.Array(Schema.String)\n })\n})\n\nexport type CodeModeCatalogSummary = typeof CodeModeCatalogSummary.Type\n\nconst decodeCatalogSummary = Schema.decodeUnknownOption(CodeModeCatalogSummary)\n\nconst encodeCatalogSummary = Schema.encodeOption(CodeModeCatalogSummary)\n\nconst namespaceListing = (tools: ReadonlyArray<CodeModeCatalogTool>) => {\n const declared = tools.filter(tool => tool.exposure !== 'all')\n const direct = tools.filter(tool => tool.exposure === 'all')\n\n return [\n ...(declared.length > 0 ? ['```ts', declarationMembers(declared), '```'] : []),\n ...direct.map(directToolLine)\n ].join('\\n')\n}\n\n/**\n * The catalog of one resolution: every namespace with its tool count and description, and the\n * listing of the tools the inline budget (or `pinned`) places. `search` and stage-only tools are\n * counted, never listed.\n */\nexport const summarizeCodeModeCatalog = (input: {\n readonly tools: ReadonlyArray<NestedTool>\n readonly staging?: CodeModeStagingDescription\n readonly inlineBudget?: number\n}): CodeModeCatalogSummary => {\n const catalog = codeModeCatalog(input.tools)\n const stageOnly = input.staging === undefined ? [] : codeModeStageOnlyCatalog(input.staging.tools)\n const listing = selectCodeModeListing(catalog, input.inlineBudget ?? defaultCodeModeInlineBudget)\n const listedByNamespace = groupByNamespace(listing.listed.map(tool => ({ tool })))\n\n const namespaces = [...groupByNamespace([...catalog, ...stageOnly].map(tool => ({ tool })))].map(\n ([name, items]) => {\n const shown = (listedByNamespace.get(name) ?? []).map(item => item.tool)\n\n const description = items.find(item => item.tool.namespaceDescription !== undefined)?.tool\n .namespaceDescription\n\n const namespace = {\n name,\n count: items.length,\n shown: shown.length,\n listing: namespaceListing(shown)\n }\n\n return description === undefined ? namespace : { ...namespace, description }\n }\n )\n\n return {\n namespaces,\n stageable:\n input.staging === undefined ? { pinned: [], listed: [] } : listedStageableNames(input.staging)\n }\n}\n\nconst namespaceLine = (namespace: CodeModeCatalogSummary['namespaces'][number]) => {\n const count = namespace.count === 1 ? '1 tool' : `${namespace.count} tools`\n\n const label =\n namespace.shown === namespace.count\n ? count\n : namespace.shown === 0\n ? `${count}, none listed`\n : `${count}, ${namespace.shown} listed`\n\n return `- \\`${namespace.name}\\` (${label})${namespace.description === undefined ? '' : `: ${namespace.description}`}`\n}\n\n/** The full catalog text of an instruction message. */\nexport const renderCodeModeCatalog = (summary: CodeModeCatalogSummary): string =>\n [\n '# Code mode catalog',\n 'Tools `codemode` scripts can call, by namespace; the latest catalog in the conversation replaces any earlier one. Call a listed tool as `await tools.<id>(args)`; find the others with `await searchTools(query, { namespace })` (each hit has its call signature); call the tool you choose in your next script, and call a tool whose exact name you already know directly, without searching.',\n ['## Namespaces', ...summary.namespaces.map(namespaceLine)].join('\\n'),\n ...summary.namespaces.flatMap(namespace =>\n namespace.listing.length === 0 ? [] : [`### ${namespace.name}\\n${namespace.listing}`]\n ),\n ...(hasStageableNames(summary.stageable) ? [stageableSection(summary.stageable)] : [])\n ].join('\\n\\n')\n\n/**\n * The host instruction of the code mode catalog: its state is the encoded summary, and its render\n * the full catalog (every change renders it whole, see `RunInstruction.render`) or a removal notice.\n */\nexport const codeModeCatalogInstruction = (input: {\n readonly tools: ReadonlyArray<NestedTool>\n readonly staging?: CodeModeStagingDescription\n readonly inlineBudget?: number\n}): RunInstruction => {\n const summary = summarizeCodeModeCatalog(input)\n\n return {\n key: codeModeCatalogInstructionKey,\n state:\n summary.namespaces.length === 0\n ? undefined\n : Option.getOrUndefined(encodeCatalogSummary(summary)),\n render: current => {\n const decoded = current === undefined ? Option.none() : decodeCatalogSummary(current)\n\n return Option.isNone(decoded)\n ? 'Code mode tools are no longer available: do not call previously listed code mode tools.'\n : renderCodeModeCatalog(decoded.value)\n }\n }\n}\n\n/**\n * The code mode description when the catalog is delivered as an instruction: invariant across\n * catalog changes (only staging availability adds the `stage()` line).\n */\nexport const renderCodeModeInstructedDescription = (input: {\n readonly store?: boolean\n readonly staging?: CodeModeStagingDescription\n}): string =>\n [\n intro,\n [\n 'Globals:',\n ...globalLines(input.store === true),\n ...(input.staging === undefined ? [] : [stageLine(input.staging.reviewToolName)])\n ].join('\\n'),\n 'The tools scripts can call are in the \"Code mode catalog\" (namespaces, tool counts and listed tools; the latest one applies). Find the others with `await searchTools(query, { namespace? })` (each hit has its call signature); call the tool you choose in your next script, and call a tool whose exact name you already know directly, without searching.'\n ].join('\\n\\n')\n"],"mappings":"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"}
|
|
@@ -2,33 +2,34 @@ import { Effect } from "effect";
|
|
|
2
2
|
import * as Schema from "effect/Schema";
|
|
3
3
|
import { ClassifierModel } from "@yolk-sdk/agent/classification";
|
|
4
4
|
import { ToolRegistration } from "@yolk-sdk/agent/tools";
|
|
5
|
-
|
|
6
|
-
//#region src/classifier-tool.d.ts
|
|
7
5
|
/** Default name of the classifier tool. */
|
|
8
|
-
declare const classifierToolName = "classify";
|
|
6
|
+
export declare const classifierToolName = "classify";
|
|
9
7
|
/** Default cap of concurrent classifications per script. */
|
|
10
|
-
declare const defaultClassifierToolMaxConcurrency = 100;
|
|
8
|
+
export declare const defaultClassifierToolMaxConcurrency = 100;
|
|
11
9
|
/** Default cap of concurrent classifications per process, across scripts and registrations. */
|
|
12
|
-
declare const defaultClassifierProcessMaxConcurrency = 200;
|
|
10
|
+
export declare const defaultClassifierProcessMaxConcurrency = 200;
|
|
13
11
|
/** A concurrency cap shared by every classifier tool registration that uses it. */
|
|
14
|
-
type ClassifierConcurrencyLimiter = {
|
|
15
|
-
/** Maximum concurrent classifications. */
|
|
12
|
+
export type ClassifierConcurrencyLimiter = {
|
|
13
|
+
/** Maximum concurrent classifications. */
|
|
14
|
+
readonly max: number;
|
|
16
15
|
/** Runs `effect` holding one permit. Waiting is interruptible and never leaks a permit; the
|
|
17
16
|
* permit is released when `effect` ends, however it ends.
|
|
18
17
|
*/
|
|
19
18
|
readonly withPermit: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
|
|
20
19
|
};
|
|
21
20
|
/** A classifier concurrency limiter allowing `max` (at least 1) classifications at once. */
|
|
22
|
-
declare const makeClassifierConcurrencyLimiter: (max: number) => ClassifierConcurrencyLimiter;
|
|
21
|
+
export declare const makeClassifierConcurrencyLimiter: (max: number) => ClassifierConcurrencyLimiter;
|
|
23
22
|
/** The process-wide limiter every classifier tool uses unless given `processLimiter`. Default
|
|
24
23
|
* 200 concurrent classifications (200 concurrent AI Gateway classifications finished in about
|
|
25
24
|
* 1.2 s without rate-limit errors in a live probe).
|
|
26
25
|
*/
|
|
27
|
-
declare const defaultClassifierProcessLimiter: ClassifierConcurrencyLimiter;
|
|
26
|
+
export declare const defaultClassifierProcessLimiter: ClassifierConcurrencyLimiter;
|
|
28
27
|
type ClassifierModelService = (typeof ClassifierModel)['Service'];
|
|
29
28
|
type Classify = ClassifierModelService['classify'];
|
|
30
|
-
type MakeClassifierToolOptions = {
|
|
31
|
-
/** `ClassifierModel`'s `classify`, or the service value itself. */
|
|
29
|
+
export type MakeClassifierToolOptions = {
|
|
30
|
+
/** `ClassifierModel`'s `classify`, or the service value itself. */
|
|
31
|
+
readonly classify: Classify | ClassifierModelService;
|
|
32
|
+
/** Default `classify`. */
|
|
32
33
|
readonly name?: string;
|
|
33
34
|
/** Concurrent classifications per script (keyed by the parent tool call id of the nested call
|
|
34
35
|
* id `<parentToolCallId>/<seq>`, or the call id itself); default 100.
|
|
@@ -43,7 +44,7 @@ type MakeClassifierToolOptions = {
|
|
|
43
44
|
/** The classifier tool's input: one state and its named questions. Provider options stay
|
|
44
45
|
* host-owned and are never taken from scripts.
|
|
45
46
|
*/
|
|
46
|
-
declare const ClassifierToolParams: Schema.Struct<{
|
|
47
|
+
export declare const ClassifierToolParams: Schema.Struct<{
|
|
47
48
|
readonly state: Schema.Union<readonly [Schema.String, Schema.$Record<Schema.String, Schema.Codec<Schema.Json, Schema.Json, never, never>>, Schema.$Array<Schema.Codec<Schema.Json, Schema.Json, never, never>>]>;
|
|
48
49
|
readonly questions: Schema.$Record<Schema.NonEmptyString, Schema.Union<readonly [Schema.Struct<{
|
|
49
50
|
readonly type: Schema.Literal<"boolean">;
|
|
@@ -72,7 +73,6 @@ declare const ClassifierToolParams: Schema.Struct<{
|
|
|
72
73
|
* Each call takes a per-script permit (`maxConcurrency`) and then a process permit
|
|
73
74
|
* (`processLimiter`), so one script's queue never holds process permits it cannot use.
|
|
74
75
|
*/
|
|
75
|
-
declare const makeClassifierTool: <Context>(options: MakeClassifierToolOptions) => ToolRegistration<Context>;
|
|
76
|
-
|
|
77
|
-
export { ClassifierConcurrencyLimiter, ClassifierToolParams, MakeClassifierToolOptions, classifierToolName, defaultClassifierProcessLimiter, defaultClassifierProcessMaxConcurrency, defaultClassifierToolMaxConcurrency, makeClassifierConcurrencyLimiter, makeClassifierTool };
|
|
76
|
+
export declare const makeClassifierTool: <Context>(options: MakeClassifierToolOptions) => ToolRegistration<Context>;
|
|
77
|
+
export {};
|
|
78
78
|
//# sourceMappingURL=classifier-tool.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"classifier-tool.d.mts","names":[],"sources":["../src/classifier-tool.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"classifier-tool.d.mts","names":[],"sources":["../src/classifier-tool.ts"],"mappings":";;;;;qBA2Ba;;qBAGA;;qBAGA;;YAGD;;WAED;;;;WAIA,aAAa,GAAG,GAAG,GAAG,QAAQ,OAAO,OAAO,GAAG,GAAG,OAAO,OAAO,OAAO,GAAG,GAAG;;;qBAM3E,mCAAgC,gBAAkB;;;;;qBAWlD,iCAA+B;KAIvC,iCAAiC;KAEjC,WAAW;YAEJ;;WAED,UAAU,WAAW;;WAErB;;;;WAIA;;;;WAIA,iBAAiB;WACjB;;;;;qBAME,sBAAoB,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA+EpB,qBAAsB,SAAO,SAC/B,8BACR,iBAAiB"}
|
package/dist/classifier-tool.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import * as Schema from "effect/Schema";
|
|
|
3
3
|
import { AgentInputUsage, AgentOutputUsage, AgentUsage, ToolResult } from "@yolk-sdk/agent/protocol";
|
|
4
4
|
import { ClassificationResult, ClassifierQuestions, ClassifierState } from "@yolk-sdk/agent/classification";
|
|
5
5
|
import { makeTool, modelVisibleToolError, modelVisibleToolErrorStructuredContent } from "@yolk-sdk/agent/tools";
|
|
6
|
-
|
|
6
|
+
// src/classifier-tool.ts
|
|
7
7
|
/** Default name of the classifier tool. */
|
|
8
8
|
const classifierToolName = "classify";
|
|
9
9
|
/** Default cap of concurrent classifications per script. */
|
|
@@ -112,14 +112,14 @@ const makeClassifierTool = (options) => {
|
|
|
112
112
|
callableBy: "codemode",
|
|
113
113
|
discovery: "listed",
|
|
114
114
|
execute: ({ call, params }) => {
|
|
115
|
-
|
|
115
|
+
const request = {
|
|
116
116
|
state: params.state,
|
|
117
117
|
questions: params.questions
|
|
118
|
-
}
|
|
118
|
+
};
|
|
119
|
+
return withScriptPermit(call, classify(request)).pipe(Effect.map((result) => successResult(call, result)), Effect.catch((error) => Effect.succeed(errorResult(call, name, error))));
|
|
119
120
|
}
|
|
120
121
|
});
|
|
121
122
|
};
|
|
122
|
-
//#endregion
|
|
123
123
|
export { ClassifierToolParams, classifierToolName, defaultClassifierProcessLimiter, defaultClassifierProcessMaxConcurrency, defaultClassifierToolMaxConcurrency, makeClassifierConcurrencyLimiter, makeClassifierTool };
|
|
124
124
|
|
|
125
125
|
//# sourceMappingURL=classifier-tool.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"classifier-tool.mjs","names":[],"sources":["../src/classifier-tool.ts"],"sourcesContent":["import { Effect, Predicate, Semaphore } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport {\n ClassificationResult,\n ClassifierQuestions,\n ClassifierState,\n type ClassificationError,\n type ClassificationRequest,\n type ClassificationUsage,\n type ClassifierModel\n} from '@yolk-sdk/agent/classification'\nimport {\n AgentInputUsage,\n AgentOutputUsage,\n AgentUsage,\n ToolResult,\n type ToolCall\n} from '@yolk-sdk/agent/protocol'\nimport {\n makeTool,\n modelVisibleToolError,\n modelVisibleToolErrorStructuredContent,\n type ModelVisibleToolErrorReason,\n type ToolRegistration\n} from '@yolk-sdk/agent/tools'\n\n/** Default name of the classifier tool. */\nexport const classifierToolName = 'classify'\n\n/** Default cap of concurrent classifications per script. */\nexport const defaultClassifierToolMaxConcurrency = 100\n\n/** Default cap of concurrent classifications per process, across scripts and registrations. */\nexport const defaultClassifierProcessMaxConcurrency = 200\n\n/** A concurrency cap shared by every classifier tool registration that uses it. */\nexport type ClassifierConcurrencyLimiter = {\n /** Maximum concurrent classifications. */\n readonly max: number\n /** Runs `effect` holding one permit. Waiting is interruptible and never leaks a permit; the\n * permit is released when `effect` ends, however it ends.\n */\n readonly withPermit: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>\n}\n\nconst permitCount = (max: number) => Math.max(1, Math.floor(max))\n\n/** A classifier concurrency limiter allowing `max` (at least 1) classifications at once. */\nexport const makeClassifierConcurrencyLimiter = (max: number): ClassifierConcurrencyLimiter => {\n const permits = permitCount(max)\n const semaphore = Semaphore.makeUnsafe(permits)\n\n return { max: permits, withPermit: effect => semaphore.withPermits(1)(effect) }\n}\n\n/** The process-wide limiter every classifier tool uses unless given `processLimiter`. Default\n * 200 concurrent classifications (200 concurrent AI Gateway classifications finished in about\n * 1.2 s without rate-limit errors in a live probe).\n */\nexport const defaultClassifierProcessLimiter = makeClassifierConcurrencyLimiter(\n defaultClassifierProcessMaxConcurrency\n)\n\ntype ClassifierModelService = (typeof ClassifierModel)['Service']\n\ntype Classify = ClassifierModelService['classify']\n\nexport type MakeClassifierToolOptions = {\n /** `ClassifierModel`'s `classify`, or the service value itself. */\n readonly classify: Classify | ClassifierModelService\n /** Default `classify`. */\n readonly name?: string\n /** Concurrent classifications per script (keyed by the parent tool call id of the nested call\n * id `<parentToolCallId>/<seq>`, or the call id itself); default 100.\n */\n readonly maxConcurrency?: number\n /** Limiter shared across scripts and registrations; default `defaultClassifierProcessLimiter`\n * (200 per process). `false` disables the process cap (the per-script cap still applies).\n */\n readonly processLimiter?: ClassifierConcurrencyLimiter | false\n readonly description?: string\n}\n\n/** The classifier tool's input: one state and its named questions. Provider options stay\n * host-owned and are never taken from scripts.\n */\nexport const ClassifierToolParams = Schema.Struct({\n state: ClassifierState,\n questions: ClassifierQuestions\n})\n\nconst defaultDescription = (maxConcurrency: number) =>\n [\n 'Classify one item with a classifier model: answer named typed questions about one `state` (a string, JSON object, or JSON array) with probabilities.',\n 'Question types: `boolean` (`probability` of true), `choice` (one of the `criteria` keys, with `probabilities`), and `score` (an ordinal level from the `criteria` list, lowest first).',\n `Call it once per item; at most ${maxConcurrency} classifications of one script run at once and further calls queue.`\n ].join(' ')\n\n/** Token usage of a classification as agent usage. `costUsd` has no agent usage field; it stays\n * in the result's `structuredContent.usage`, so nested-call records carry token usage only.\n */\nconst agentUsage = (usage: ClassificationUsage): AgentUsage =>\n AgentUsage.make({\n input: AgentInputUsage.make({ total: usage.inputTokens }),\n output: AgentOutputUsage.make({ total: usage.outputTokens })\n })\n\nconst errorReason = (error: ClassificationError): ModelVisibleToolErrorReason =>\n Predicate.isTagged(error, 'ClassificationRequestInvalid') ? 'invalid_input' : 'unavailable'\n\nconst billedUsage = (error: ClassificationError) =>\n Predicate.isTagged(error, 'ClassificationResponseInvalid') ? error.usage : undefined\n\n/** The parent tool call id of a nested call id `<parentToolCallId>/<seq>`, else the id itself. */\nconst scriptKey = (call: ToolCall) => {\n const separator = call.id.lastIndexOf('/')\n\n return separator > 0 ? call.id.slice(0, separator) : call.id\n}\n\ntype ResultFields = {\n toolCallId: string\n content: string\n isError?: boolean\n structuredContent: unknown\n usage?: AgentUsage\n}\n\nconst withUsage = (fields: ResultFields, usage: ClassificationUsage | undefined) => {\n if (usage !== undefined) {\n fields.usage = agentUsage(usage)\n }\n\n return ToolResult.make(fields)\n}\n\nconst successResult = (call: ToolCall, result: ClassificationResult) =>\n withUsage(\n { toolCallId: call.id, content: JSON.stringify(result.answers), structuredContent: result },\n result.usage\n )\n\nconst errorResult = (call: ToolCall, name: string, error: ClassificationError) =>\n withUsage(\n {\n toolCallId: call.id,\n content: error.message,\n isError: true,\n structuredContent: modelVisibleToolErrorStructuredContent(\n modelVisibleToolError({ tool: name, reason: errorReason(error), message: error.message })\n )\n },\n billedUsage(error)\n )\n\n/**\n * A code-mode-only (`callableBy: 'codemode'`, `discovery: 'listed'`) read tool that classifies one\n * item per call with a classifier model. Its content is the compact JSON of the answers, its\n * `structuredContent` the full `ClassificationResult` (which nested calls resolve to), and its\n * token usage is reported on `ToolResult.usage`. Classifier errors become model-visible error\n * results; usage billed before a response error is kept.\n *\n * Each call takes a per-script permit (`maxConcurrency`) and then a process permit\n * (`processLimiter`), so one script's queue never holds process permits it cannot use.\n */\nexport const makeClassifierTool = <Context>(\n options: MakeClassifierToolOptions\n): ToolRegistration<Context> => {\n const name = options.name ?? classifierToolName\n\n const maxConcurrency = permitCount(options.maxConcurrency ?? defaultClassifierToolMaxConcurrency)\n\n const processLimiter =\n options.processLimiter === undefined ? defaultClassifierProcessLimiter : options.processLimiter\n\n const withProcessPermit = <A, E>(effect: Effect.Effect<A, E>) =>\n processLimiter === false ? effect : processLimiter.withPermit(effect)\n\n const classify = Predicate.isFunction(options.classify)\n ? options.classify\n : options.classify.classify\n\n // One semaphore per script (parent tool call), removed when its last classification ends.\n const scripts = new Map<string, { readonly semaphore: Semaphore.Semaphore; users: number }>()\n\n const withScriptPermit = <A, E>(call: ToolCall, effect: Effect.Effect<A, E>) =>\n Effect.acquireUseRelease(\n Effect.sync(() => {\n const key = scriptKey(call)\n\n const entry = scripts.get(key) ?? {\n semaphore: Semaphore.makeUnsafe(maxConcurrency),\n users: 0\n }\n\n entry.users++\n scripts.set(key, entry)\n\n return { key, entry }\n }),\n ({ entry }) => entry.semaphore.withPermits(1)(withProcessPermit(effect)),\n ({ key, entry }) =>\n Effect.sync(() => {\n entry.users--\n\n if (entry.users === 0 && scripts.get(key) === entry) scripts.delete(key)\n })\n )\n\n return makeTool<Context, typeof ClassifierToolParams>({\n name,\n description: options.description ?? defaultDescription(maxConcurrency),\n parameters: ClassifierToolParams,\n output: ClassificationResult,\n access: 'read',\n callableBy: 'codemode',\n discovery: 'listed',\n execute: ({ call, params }) => {\n const request: ClassificationRequest = { state: params.state, questions: params.questions }\n\n return withScriptPermit(call, classify(request)).pipe(\n Effect.map(result => successResult(call, result)),\n Effect.catch(error => Effect.succeed(errorResult(call, name, error)))\n )\n }\n })\n}\n"],"mappings":";;;;;;;AA2BA,MAAa,qBAAqB;;AAGlC,MAAa,sCAAsC;;AAGnD,MAAa,yCAAyC;AAYtD,MAAM,eAAe,QAAgB,KAAK,IAAI,GAAG,KAAK,MAAM,GAAG,CAAC;;AAGhE,MAAa,oCAAoC,QAA8C;CAC7F,MAAM,UAAU,YAAY,GAAG;CAC/B,MAAM,YAAY,UAAU,WAAW,OAAO;CAE9C,OAAO;EAAE,KAAK;EAAS,aAAY,WAAU,UAAU,YAAY,CAAC,EAAE,MAAM;CAAE;AAChF;;;;;AAMA,MAAa,kCAAkC,iCAAA,GAE/C;;;;AAyBA,MAAa,uBAAuB,OAAO,OAAO;CAChD,OAAO;CACP,WAAW;AACb,CAAC;AAED,MAAM,sBAAsB,mBAC1B;CACE;CACA;CACA,kCAAkC,eAAe;AACnD,EAAE,KAAK,GAAG;;;;AAKZ,MAAM,cAAc,UAClB,WAAW,KAAK;CACd,OAAO,gBAAgB,KAAK,EAAE,OAAO,MAAM,YAAY,CAAC;CACxD,QAAQ,iBAAiB,KAAK,EAAE,OAAO,MAAM,aAAa,CAAC;AAC7D,CAAC;AAEH,MAAM,eAAe,UACnB,UAAU,SAAS,OAAO,8BAA8B,IAAI,kBAAkB;AAEhF,MAAM,eAAe,UACnB,UAAU,SAAS,OAAO,+BAA+B,IAAI,MAAM,QAAQ,KAAA;;AAG7E,MAAM,aAAa,SAAmB;CACpC,MAAM,YAAY,KAAK,GAAG,YAAY,GAAG;CAEzC,OAAO,YAAY,IAAI,KAAK,GAAG,MAAM,GAAG,SAAS,IAAI,KAAK;AAC5D;AAUA,MAAM,aAAa,QAAsB,UAA2C;CAClF,IAAI,UAAU,KAAA,GACZ,OAAO,QAAQ,WAAW,KAAK;CAGjC,OAAO,WAAW,KAAK,MAAM;AAC/B;AAEA,MAAM,iBAAiB,MAAgB,WACrC,UACE;CAAE,YAAY,KAAK;CAAI,SAAS,KAAK,UAAU,OAAO,OAAO;CAAG,mBAAmB;AAAO,GAC1F,OAAO,KACT;AAEF,MAAM,eAAe,MAAgB,MAAc,UACjD,UACE;CACE,YAAY,KAAK;CACjB,SAAS,MAAM;CACf,SAAS;CACT,mBAAmB,uCACjB,sBAAsB;EAAE,MAAM;EAAM,QAAQ,YAAY,KAAK;EAAG,SAAS,MAAM;CAAQ,CAAC,CAC1F;AACF,GACA,YAAY,KAAK,CACnB;;;;;;;;;;;AAYF,MAAa,sBACX,YAC8B;CAC9B,MAAM,OAAO,QAAQ,QAAA;CAErB,MAAM,iBAAiB,YAAY,QAAQ,kBAAA,GAAqD;CAEhG,MAAM,iBACJ,QAAQ,mBAAmB,KAAA,IAAY,kCAAkC,QAAQ;CAEnF,MAAM,qBAA2B,WAC/B,mBAAmB,QAAQ,SAAS,eAAe,WAAW,MAAM;CAEtE,MAAM,WAAW,UAAU,WAAW,QAAQ,QAAQ,IAClD,QAAQ,WACR,QAAQ,SAAS;CAGrB,MAAM,0BAAU,IAAI,IAAwE;CAE5F,MAAM,oBAA0B,MAAgB,WAC9C,OAAO,kBACL,OAAO,WAAW;EAChB,MAAM,MAAM,UAAU,IAAI;EAE1B,MAAM,QAAQ,QAAQ,IAAI,GAAG,KAAK;GAChC,WAAW,UAAU,WAAW,cAAc;GAC9C,OAAO;EACT;EAEA,MAAM;EACN,QAAQ,IAAI,KAAK,KAAK;EAEtB,OAAO;GAAE;GAAK;EAAM;CACtB,CAAC,IACA,EAAE,YAAY,MAAM,UAAU,YAAY,CAAC,EAAE,kBAAkB,MAAM,CAAC,IACtE,EAAE,KAAK,YACN,OAAO,WAAW;EAChB,MAAM;EAEN,IAAI,MAAM,UAAU,KAAK,QAAQ,IAAI,GAAG,MAAM,OAAO,QAAQ,OAAO,GAAG;CACzE,CAAC,CACL;CAEF,OAAO,SAA+C;EACpD;EACA,aAAa,QAAQ,eAAe,mBAAmB,cAAc;EACrE,YAAY;EACZ,QAAQ;EACR,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,UAAU,EAAE,MAAM,aAAa;GAG7B,OAAO,iBAAiB,MAAM,SAAS;IAFE,OAAO,OAAO;IAAO,WAAW,OAAO;GAEnC,CAAC,CAAC,EAAE,KAC/C,OAAO,KAAI,WAAU,cAAc,MAAM,MAAM,CAAC,GAChD,OAAO,OAAM,UAAS,OAAO,QAAQ,YAAY,MAAM,MAAM,KAAK,CAAC,CAAC,CACtE;EACF;CACF,CAAC;AACH"}
|
|
1
|
+
{"version":3,"file":"classifier-tool.mjs","names":[],"sources":["../src/classifier-tool.ts"],"sourcesContent":["import { Effect, Predicate, Semaphore } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport {\n ClassificationResult,\n ClassifierQuestions,\n ClassifierState,\n type ClassificationError,\n type ClassificationRequest,\n type ClassificationUsage,\n type ClassifierModel\n} from '@yolk-sdk/agent/classification'\nimport {\n AgentInputUsage,\n AgentOutputUsage,\n AgentUsage,\n ToolResult,\n type ToolCall\n} from '@yolk-sdk/agent/protocol'\nimport {\n makeTool,\n modelVisibleToolError,\n modelVisibleToolErrorStructuredContent,\n type ModelVisibleToolErrorReason,\n type ToolRegistration\n} from '@yolk-sdk/agent/tools'\n\n/** Default name of the classifier tool. */\nexport const classifierToolName = 'classify'\n\n/** Default cap of concurrent classifications per script. */\nexport const defaultClassifierToolMaxConcurrency = 100\n\n/** Default cap of concurrent classifications per process, across scripts and registrations. */\nexport const defaultClassifierProcessMaxConcurrency = 200\n\n/** A concurrency cap shared by every classifier tool registration that uses it. */\nexport type ClassifierConcurrencyLimiter = {\n /** Maximum concurrent classifications. */\n readonly max: number\n /** Runs `effect` holding one permit. Waiting is interruptible and never leaks a permit; the\n * permit is released when `effect` ends, however it ends.\n */\n readonly withPermit: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>\n}\n\nconst permitCount = (max: number) => Math.max(1, Math.floor(max))\n\n/** A classifier concurrency limiter allowing `max` (at least 1) classifications at once. */\nexport const makeClassifierConcurrencyLimiter = (max: number): ClassifierConcurrencyLimiter => {\n const permits = permitCount(max)\n const semaphore = Semaphore.makeUnsafe(permits)\n\n return { max: permits, withPermit: effect => semaphore.withPermits(1)(effect) }\n}\n\n/** The process-wide limiter every classifier tool uses unless given `processLimiter`. Default\n * 200 concurrent classifications (200 concurrent AI Gateway classifications finished in about\n * 1.2 s without rate-limit errors in a live probe).\n */\nexport const defaultClassifierProcessLimiter = makeClassifierConcurrencyLimiter(\n defaultClassifierProcessMaxConcurrency\n)\n\ntype ClassifierModelService = (typeof ClassifierModel)['Service']\n\ntype Classify = ClassifierModelService['classify']\n\nexport type MakeClassifierToolOptions = {\n /** `ClassifierModel`'s `classify`, or the service value itself. */\n readonly classify: Classify | ClassifierModelService\n /** Default `classify`. */\n readonly name?: string\n /** Concurrent classifications per script (keyed by the parent tool call id of the nested call\n * id `<parentToolCallId>/<seq>`, or the call id itself); default 100.\n */\n readonly maxConcurrency?: number\n /** Limiter shared across scripts and registrations; default `defaultClassifierProcessLimiter`\n * (200 per process). `false` disables the process cap (the per-script cap still applies).\n */\n readonly processLimiter?: ClassifierConcurrencyLimiter | false\n readonly description?: string\n}\n\n/** The classifier tool's input: one state and its named questions. Provider options stay\n * host-owned and are never taken from scripts.\n */\nexport const ClassifierToolParams = Schema.Struct({\n state: ClassifierState,\n questions: ClassifierQuestions\n})\n\nconst defaultDescription = (maxConcurrency: number) =>\n [\n 'Classify one item with a classifier model: answer named typed questions about one `state` (a string, JSON object, or JSON array) with probabilities.',\n 'Question types: `boolean` (`probability` of true), `choice` (one of the `criteria` keys, with `probabilities`), and `score` (an ordinal level from the `criteria` list, lowest first).',\n `Call it once per item; at most ${maxConcurrency} classifications of one script run at once and further calls queue.`\n ].join(' ')\n\n/** Token usage of a classification as agent usage. `costUsd` has no agent usage field; it stays\n * in the result's `structuredContent.usage`, so nested-call records carry token usage only.\n */\nconst agentUsage = (usage: ClassificationUsage): AgentUsage =>\n AgentUsage.make({\n input: AgentInputUsage.make({ total: usage.inputTokens }),\n output: AgentOutputUsage.make({ total: usage.outputTokens })\n })\n\nconst errorReason = (error: ClassificationError): ModelVisibleToolErrorReason =>\n Predicate.isTagged(error, 'ClassificationRequestInvalid') ? 'invalid_input' : 'unavailable'\n\nconst billedUsage = (error: ClassificationError) =>\n Predicate.isTagged(error, 'ClassificationResponseInvalid') ? error.usage : undefined\n\n/** The parent tool call id of a nested call id `<parentToolCallId>/<seq>`, else the id itself. */\nconst scriptKey = (call: ToolCall) => {\n const separator = call.id.lastIndexOf('/')\n\n return separator > 0 ? call.id.slice(0, separator) : call.id\n}\n\ntype ResultFields = {\n toolCallId: string\n content: string\n isError?: boolean\n structuredContent: unknown\n usage?: AgentUsage\n}\n\nconst withUsage = (fields: ResultFields, usage: ClassificationUsage | undefined) => {\n if (usage !== undefined) {\n fields.usage = agentUsage(usage)\n }\n\n return ToolResult.make(fields)\n}\n\nconst successResult = (call: ToolCall, result: ClassificationResult) =>\n withUsage(\n { toolCallId: call.id, content: JSON.stringify(result.answers), structuredContent: result },\n result.usage\n )\n\nconst errorResult = (call: ToolCall, name: string, error: ClassificationError) =>\n withUsage(\n {\n toolCallId: call.id,\n content: error.message,\n isError: true,\n structuredContent: modelVisibleToolErrorStructuredContent(\n modelVisibleToolError({ tool: name, reason: errorReason(error), message: error.message })\n )\n },\n billedUsage(error)\n )\n\n/**\n * A code-mode-only (`callableBy: 'codemode'`, `discovery: 'listed'`) read tool that classifies one\n * item per call with a classifier model. Its content is the compact JSON of the answers, its\n * `structuredContent` the full `ClassificationResult` (which nested calls resolve to), and its\n * token usage is reported on `ToolResult.usage`. Classifier errors become model-visible error\n * results; usage billed before a response error is kept.\n *\n * Each call takes a per-script permit (`maxConcurrency`) and then a process permit\n * (`processLimiter`), so one script's queue never holds process permits it cannot use.\n */\nexport const makeClassifierTool = <Context>(\n options: MakeClassifierToolOptions\n): ToolRegistration<Context> => {\n const name = options.name ?? classifierToolName\n\n const maxConcurrency = permitCount(options.maxConcurrency ?? defaultClassifierToolMaxConcurrency)\n\n const processLimiter =\n options.processLimiter === undefined ? defaultClassifierProcessLimiter : options.processLimiter\n\n const withProcessPermit = <A, E>(effect: Effect.Effect<A, E>) =>\n processLimiter === false ? effect : processLimiter.withPermit(effect)\n\n const classify = Predicate.isFunction(options.classify)\n ? options.classify\n : options.classify.classify\n\n // One semaphore per script (parent tool call), removed when its last classification ends.\n const scripts = new Map<string, { readonly semaphore: Semaphore.Semaphore; users: number }>()\n\n const withScriptPermit = <A, E>(call: ToolCall, effect: Effect.Effect<A, E>) =>\n Effect.acquireUseRelease(\n Effect.sync(() => {\n const key = scriptKey(call)\n\n const entry = scripts.get(key) ?? {\n semaphore: Semaphore.makeUnsafe(maxConcurrency),\n users: 0\n }\n\n entry.users++\n scripts.set(key, entry)\n\n return { key, entry }\n }),\n ({ entry }) => entry.semaphore.withPermits(1)(withProcessPermit(effect)),\n ({ key, entry }) =>\n Effect.sync(() => {\n entry.users--\n\n if (entry.users === 0 && scripts.get(key) === entry) scripts.delete(key)\n })\n )\n\n return makeTool<Context, typeof ClassifierToolParams>({\n name,\n description: options.description ?? defaultDescription(maxConcurrency),\n parameters: ClassifierToolParams,\n output: ClassificationResult,\n access: 'read',\n callableBy: 'codemode',\n discovery: 'listed',\n execute: ({ call, params }) => {\n const request: ClassificationRequest = { state: params.state, questions: params.questions }\n\n return withScriptPermit(call, classify(request)).pipe(\n Effect.map(result => successResult(call, result)),\n Effect.catch(error => Effect.succeed(errorResult(call, name, error)))\n )\n }\n })\n}\n"],"mappings":";;;;;;;AA2BA,MAAa,qBAAqB;;AAGlC,MAAa,sCAAsC;;AAGnD,MAAa,yCAAyC;AAYtD,MAAM,eAAe,QAAgB,KAAK,IAAI,GAAG,KAAK,MAAM,GAAG,CAAC;;AAGhE,MAAa,oCAAoC,QAA8C;CAC7F,MAAM,UAAU,YAAY,GAAG;CAC/B,MAAM,YAAY,UAAU,WAAW,OAAO;CAE9C,OAAO;EAAE,KAAK;EAAS,aAAY,WAAU,UAAU,YAAY,CAAC,CAAC,CAAC,MAAM;CAAE;AAChF;;;;;AAMA,MAAa,kCAAkC,iCAAA,GAE/C;;;;AAyBA,MAAa,uBAAuB,OAAO,OAAO;CAChD,OAAO;CACP,WAAW;AACb,CAAC;AAED,MAAM,sBAAsB,mBAC1B;CACE;CACA;CACA,kCAAkC,eAAe;AACnD,CAAC,CAAC,KAAK,GAAG;;;;AAKZ,MAAM,cAAc,UAClB,WAAW,KAAK;CACd,OAAO,gBAAgB,KAAK,EAAE,OAAO,MAAM,YAAY,CAAC;CACxD,QAAQ,iBAAiB,KAAK,EAAE,OAAO,MAAM,aAAa,CAAC;AAC7D,CAAC;AAEH,MAAM,eAAe,UACnB,UAAU,SAAS,OAAO,8BAA8B,IAAI,kBAAkB;AAEhF,MAAM,eAAe,UACnB,UAAU,SAAS,OAAO,+BAA+B,IAAI,MAAM,QAAQ,KAAA;;AAG7E,MAAM,aAAa,SAAmB;CACpC,MAAM,YAAY,KAAK,GAAG,YAAY,GAAG;CAEzC,OAAO,YAAY,IAAI,KAAK,GAAG,MAAM,GAAG,SAAS,IAAI,KAAK;AAC5D;AAUA,MAAM,aAAa,QAAsB,UAA2C;CAClF,IAAI,UAAU,KAAA,GACZ,OAAO,QAAQ,WAAW,KAAK;CAGjC,OAAO,WAAW,KAAK,MAAM;AAC/B;AAEA,MAAM,iBAAiB,MAAgB,WACrC,UACE;CAAE,YAAY,KAAK;CAAI,SAAS,KAAK,UAAU,OAAO,OAAO;CAAG,mBAAmB;AAAO,GAC1F,OAAO,KACT;AAEF,MAAM,eAAe,MAAgB,MAAc,UACjD,UACE;CACE,YAAY,KAAK;CACjB,SAAS,MAAM;CACf,SAAS;CACT,mBAAmB,uCACjB,sBAAsB;EAAE,MAAM;EAAM,QAAQ,YAAY,KAAK;EAAG,SAAS,MAAM;CAAQ,CAAC,CAC1F;AACF,GACA,YAAY,KAAK,CACnB;;;;;;;;;;;AAYF,MAAa,sBACX,YAC8B;CAC9B,MAAM,OAAO,QAAQ,QAAA;CAErB,MAAM,iBAAiB,YAAY,QAAQ,kBAAA,GAAqD;CAEhG,MAAM,iBACJ,QAAQ,mBAAmB,KAAA,IAAY,kCAAkC,QAAQ;CAEnF,MAAM,qBAA2B,WAC/B,mBAAmB,QAAQ,SAAS,eAAe,WAAW,MAAM;CAEtE,MAAM,WAAW,UAAU,WAAW,QAAQ,QAAQ,IAClD,QAAQ,WACR,QAAQ,SAAS;CAGrB,MAAM,0BAAU,IAAI,IAAwE;CAE5F,MAAM,oBAA0B,MAAgB,WAC9C,OAAO,kBACL,OAAO,WAAW;EAChB,MAAM,MAAM,UAAU,IAAI;EAE1B,MAAM,QAAQ,QAAQ,IAAI,GAAG,KAAK;GAChC,WAAW,UAAU,WAAW,cAAc;GAC9C,OAAO;EACT;EAEA,MAAM;EACN,QAAQ,IAAI,KAAK,KAAK;EAEtB,OAAO;GAAE;GAAK;EAAM;CACtB,CAAC,IACA,EAAE,YAAY,MAAM,UAAU,YAAY,CAAC,CAAC,CAAC,kBAAkB,MAAM,CAAC,IACtE,EAAE,KAAK,YACN,OAAO,WAAW;EAChB,MAAM;EAEN,IAAI,MAAM,UAAU,KAAK,QAAQ,IAAI,GAAG,MAAM,OAAO,QAAQ,OAAO,GAAG;CACzE,CAAC,CACL;CAEF,OAAO,SAA+C;EACpD;EACA,aAAa,QAAQ,eAAe,mBAAmB,cAAc;EACrE,YAAY;EACZ,QAAQ;EACR,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,UAAU,EAAE,MAAM,aAAa;GAC7B,MAAM,UAAiC;IAAE,OAAO,OAAO;IAAO,WAAW,OAAO;GAAU;GAE1F,OAAO,iBAAiB,MAAM,SAAS,OAAO,CAAC,CAAC,CAAC,KAC/C,OAAO,KAAI,WAAU,cAAc,MAAM,MAAM,CAAC,GAChD,OAAO,OAAM,UAAS,OAAO,QAAQ,YAAY,MAAM,MAAM,KAAK,CAAC,CAAC,CACtE;EACF;CACF,CAAC;AACH"}
|