@ny4n/codemode 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -0
- package/README.md +56 -7
- package/dist/declarations.d.ts +6 -21
- package/dist/declarations.d.ts.map +1 -1
- package/dist/declarations.js +100 -122
- package/dist/declarations.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/portable.d.ts +1 -1
- package/dist/portable.d.ts.map +1 -1
- package/dist/portable.js.map +1 -1
- package/dist/runtime/execution.d.ts +14 -2
- package/dist/runtime/execution.d.ts.map +1 -1
- package/dist/runtime/execution.js +158 -35
- package/dist/runtime/execution.js.map +1 -1
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/host.js +25 -11
- package/dist/runtime/host.js.map +1 -1
- package/dist/runtime/inline.d.ts.map +1 -1
- package/dist/runtime/inline.js +1 -0
- package/dist/runtime/inline.js.map +1 -1
- package/dist/runtime/prelude-source.d.ts +3 -1
- package/dist/runtime/prelude-source.d.ts.map +1 -1
- package/dist/runtime/prelude-source.js +16 -6
- package/dist/runtime/prelude-source.js.map +1 -1
- package/dist/runtime/protocol.d.ts +38 -3
- package/dist/runtime/protocol.d.ts.map +1 -1
- package/dist/runtime/protocol.js +6 -1
- package/dist/runtime/protocol.js.map +1 -1
- package/dist/runtime/remote.d.ts.map +1 -1
- package/dist/runtime/remote.js +5 -0
- package/dist/runtime/remote.js.map +1 -1
- package/dist/runtime/vm.d.ts +2 -0
- package/dist/runtime/vm.d.ts.map +1 -1
- package/dist/runtime/vm.js +131 -9
- package/dist/runtime/vm.js.map +1 -1
- package/dist/search.d.ts +33 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +112 -0
- package/dist/search.js.map +1 -0
- package/dist/source.d.ts +2 -1
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +8 -2
- package/dist/source.js.map +1 -1
- package/dist/types.d.ts +102 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +6 -1
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ await sandbox.close();
|
|
|
49
49
|
- `tools.<name>(args)` returns a promise. Arguments and results make a JSON round trip. A tool that throws rejects with an `Error` carrying the same message. Tool names are also exposed as identifiers: characters that are not valid in identifiers become `_` (`toCodemodeIdentifier`), so `my-tool` is `tools.my_tool` as well as `tools["my-tool"]`.
|
|
50
50
|
- `ALL_TOOLS` lists `{ name, description }` for every tool, with `name` as the identifier.
|
|
51
51
|
- `text(value)` appends a text item to `result.output`; values other than strings are JSON-stringified. `console.log/info/warn/error/debug` append text items with `console: true`.
|
|
52
|
-
- `image(urlOrItem)` appends an image item. It accepts a base64 `data:` URL, `{ image_url }`, or an
|
|
52
|
+
- `image(urlOrItem)` appends an image item. It accepts a base64 `data:` URL, `{ image_url }`, or an image block (`{ type: "image", data, mimeType }`, as MCP tools and `@ny4n/ai` produce). Remote URLs are rejected.
|
|
53
53
|
- `exit()` ends the script successfully right away, keeping its output and store writes.
|
|
54
54
|
- `globals` passed to the sandbox are called as top-level functions, for example a host helper `image(ref)`. They behave like tools but are not recorded in `result.calls`. A name like `models.classify` puts the function on a frozen `models` object. With `spread: true`, `execute` receives all call arguments as an array instead of the first one, and `signature` replaces the declaration generated from the schemas.
|
|
55
55
|
- `store(key, value)` and `load(key)` read and write JSON values synchronously. See [Store](#store).
|
|
@@ -59,6 +59,24 @@ await sandbox.close();
|
|
|
59
59
|
|
|
60
60
|
`memoryLimitBytes` caps the VM's heap. Allocations beyond it fail inside the script as `InternalError: out of memory`.
|
|
61
61
|
|
|
62
|
+
Aborts, timeouts, and `close()` request worker termination without waiting for the worker to exit. On Bun, a built-in such as a long `String.prototype.indexOf` may not poll QuickJS's interrupt handler, so its worker can keep computing until the built-in returns. Stopping unrefs the worker after requesting termination, because `terminate()` refs it internally. This does not guarantee computation has stopped. On Bun 1.4.0, a pending `terminate()` can still delay host process exit despite `unref()`; cancellation results and `close()` do not wait for it.
|
|
63
|
+
|
|
64
|
+
Hosts that limit concurrency can track actual worker lifetime with `onWorkerStarted(exited)`, called for each worker started by `execute()` or `start()`. Its promise resolves when that worker exits, not when the script result settles:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
const workers = new Set<Promise<void>>();
|
|
68
|
+
const sandbox = new CodemodeSandbox({
|
|
69
|
+
onWorkerStarted(exited) {
|
|
70
|
+
workers.add(exited);
|
|
71
|
+
void exited.then(() => workers.delete(exited));
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Keep a concurrency slot occupied until `exited` resolves. `close()` does not wait for these promises.
|
|
77
|
+
|
|
78
|
+
To enforce an admission limit, pass `acquireWorker()`. It runs synchronously after WASM loading, immediately before each worker is created. Throw to reject the execution without starting a worker; otherwise return a release callback. The sandbox calls it once on actual worker exit or if the worker constructor fails. Share reservation state across sandbox instances, and do not release it when a script result settles.
|
|
79
|
+
|
|
62
80
|
## Store
|
|
63
81
|
|
|
64
82
|
`store`/`load` let scripts keep values across executions. The sandbox does not persist anything itself: pass the current values as `options.store`, and a successful result reports what the script changed as `result.storeWrites` (`{ set, delete }`). Failed executions report no writes.
|
|
@@ -83,7 +101,7 @@ const source = await tools.read({ path: "package.json" });
|
|
|
83
101
|
text(JSON.parse(source).name);
|
|
84
102
|
```
|
|
85
103
|
|
|
86
|
-
Supported fields are `max_output_tokens`, a token budget for the output, and `timeout_ms`, a hard deadline. The sandbox does not act on them; the caller decides. The options line is replaced by an empty line, so line numbers in stack traces still match the input. Empty input, invalid JSON, unknown fields,
|
|
104
|
+
Supported fields are `max_output_tokens`, a token budget for the output, and `timeout_ms`, a hard deadline. The sandbox does not act on them; the caller decides. The options line is replaced by an empty line, so line numbers in stack traces still match the input. Empty input, invalid JSON, unknown fields, an options line without code, or an options line on any line but the first throw `CodemodeSourceError`. `CODEMODE_SOURCE_GRAMMAR` is a Lark grammar for providers that support grammar-constrained tool input. Both are also available from the lightweight `@ny4n/codemode/source` entry.
|
|
87
105
|
|
|
88
106
|
## Bundled Node and Bun hosts
|
|
89
107
|
|
|
@@ -167,7 +185,7 @@ Bind the class with `script_name`. Binding a class exported from the agent's own
|
|
|
167
185
|
}
|
|
168
186
|
```
|
|
169
187
|
|
|
170
|
-
Then replace the sandbox. Tools, options other than `wasm` and `
|
|
188
|
+
Then replace the sandbox. Tools, options other than the worker-specific `wasm`, `workerUrl`, `acquireWorker`, and `onWorkerStarted`, and results stay the same:
|
|
171
189
|
|
|
172
190
|
```ts
|
|
173
191
|
import type { CodemodeSandboxDurableObject } from "@ny4n/codemode/cloudflare";
|
|
@@ -243,7 +261,7 @@ renderDeclarations({ tools: sandbox.tools, globals: sandbox.globals });
|
|
|
243
261
|
// };
|
|
244
262
|
```
|
|
245
263
|
|
|
246
|
-
Schemas only shape the declarations; values are not validated against them. Local references (`#/$defs/...`, `#/definitions/...`) are expanded; recursive and remote references render as `unknown`.
|
|
264
|
+
Property descriptions become `//` comments. Constraints the type cannot express follow as tags, such as `// @integer @minimum 1 @default 20`; they are dropped first when a type exceeds the size limit. Schemas only shape the declarations; values are not validated against them. Local references (`#/$defs/...`, `#/definitions/...`) are expanded; recursive and remote references render as `unknown`.
|
|
247
265
|
|
|
248
266
|
## Using with @ny4n/agent-core
|
|
249
267
|
|
|
@@ -293,6 +311,37 @@ const codemodeTool: AgentTool = {
|
|
|
293
311
|
|
|
294
312
|
`result.output` items already have the shape of `@ny4n/ai`'s `TextContent` and `ImageContent`. Calling `tool.execute()` directly skips the agent's `beforeToolCall` and `afterToolCall` hooks. To apply them to nested calls too, run each call through `runToolCall()` from `@ny4n/agent-core`, as the [mcp-codemode example](https://github.com/blxzer77/nyan/tree/main/packages/agent/examples/mcp-codemode) does. That example also rejects failed nested calls inside the script and combines codemode with MCP tools.
|
|
295
313
|
|
|
314
|
+
## Deterministic runs
|
|
315
|
+
|
|
316
|
+
`sandbox.start(code, options)` runs a script so that a host can run it again after a restart and get the same behavior, for example to resume it from a durable log of its calls' results. `execute()` is unaffected.
|
|
317
|
+
|
|
318
|
+
The VM only runs when the host hands it something, and has no timers or I/O, so it is deterministic except for what it reads from its environment. `start()` fixes that:
|
|
319
|
+
|
|
320
|
+
- **Time:** `Date.now()` reads `startedAt`, then the `now` of the result being processed, never going backwards. `performance.now()` counts from `startedAt`.
|
|
321
|
+
- **Randomness:** `Math.random()` and the VM's other randomness come from `seed`.
|
|
322
|
+
- **Timezone:** UTC, whatever the host's.
|
|
323
|
+
- **Garbage collection:** `WeakRef` and `FinalizationRegistry` do not exist.
|
|
324
|
+
- **Result order:** the host answers each call with a result number (1, 2, ...), and the VM applies results strictly in that order, whatever order a transport delivers them in.
|
|
325
|
+
|
|
326
|
+
The run declares its own tools and globals, and the host answers every call itself:
|
|
327
|
+
|
|
328
|
+
```ts
|
|
329
|
+
const run = sandbox.start(code, {
|
|
330
|
+
startedAt: Date.now(),
|
|
331
|
+
seed: 7,
|
|
332
|
+
tools: [{ name: "read", description: "Read a file" }],
|
|
333
|
+
onStarted: (fingerprint) => {}, // what the VM is: engine versions, prelude hash, limits
|
|
334
|
+
onCall: (call) => {
|
|
335
|
+
// call.id is the VM's own number for the call, in the order the script made them.
|
|
336
|
+
void readFile(call.args).then((text) => run.deliver(nextResult++, Date.now(), call.id, { ok: true, value: text }));
|
|
337
|
+
},
|
|
338
|
+
onIdle: (seq, issued) => {}, // after result `seq` (0: the first run), `issued` calls in total
|
|
339
|
+
});
|
|
340
|
+
const result = await run.result;
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
A run has no deadline unless `timeoutMs` is given. Result numbers must run 1, 2, ... without gaps. The same script, `startedAt`, `seed`, tools (with their `jsName`), globals and store, answered with the same results in the same order, makes the same calls with the same arguments and produces the same output on any VM with the same fingerprint. To end a run with an error the script cannot catch, abort its `signal`.
|
|
344
|
+
|
|
296
345
|
## Results
|
|
297
346
|
|
|
298
347
|
`execute()` never rejects for script failures. `result.error.kind` is one of:
|
|
@@ -300,8 +349,8 @@ const codemodeTool: AgentTool = {
|
|
|
300
349
|
| kind | meaning |
|
|
301
350
|
| --------- | --------------------------------------------------------------------------- |
|
|
302
351
|
| `script` | the script threw or failed to parse; `stack` points at `codemode.js:<line>` |
|
|
303
|
-
| `timeout` | the deadline expired or the interrupt budget ran out;
|
|
304
|
-
| `aborted` | `options.signal` fired or `close()` was called;
|
|
352
|
+
| `timeout` | the deadline expired or the interrupt budget ran out; VM shutdown was requested |
|
|
353
|
+
| `aborted` | `options.signal` fired or `close()` was called; VM shutdown was requested |
|
|
305
354
|
| `sandbox` | the VM or its transport failed, for example a wasm trap, a missing worker file, or a failed remote |
|
|
306
355
|
|
|
307
356
|
`result.output` holds the text and image items in the order the script produced them, also for failed executions. The host keeps all of it until the script ends, so output is limited to `MAX_OUTPUT_CHARS` (16 Mi) characters of text and base64 image data and `MAX_OUTPUT_ITEMS` (100000) items. Past either limit the script fails with a `RangeError`, even if it catches the error. `result.calls` lists every tool call with `status: "ok" | "error" | "cancelled"`. A call that is still running when the script returns (not awaited) is aborted through the tool's `signal` and reported as `cancelled`.
|
|
@@ -320,6 +369,6 @@ The worker keeps script execution off the host thread: QuickJS runs synchronousl
|
|
|
320
369
|
|
|
321
370
|
## Runtime notes
|
|
322
371
|
|
|
323
|
-
-
|
|
372
|
+
- Node and Bun support memory limits, interrupts, and a catchable `RangeError` for deep recursion (QuickJS's stack guard is enabled; without it the wasm stack overflows and traps). Bun may delay worker exit during non-interruptible built-ins; results do not wait for exit.
|
|
324
373
|
- Stack traces use QuickJS frames (`at f (codemode.js:2:31)`), prefixed with `Name: message` like V8. The wrapper prefix shares line 1 with the script, so line numbers are exact; column numbers on line 1 are shifted.
|
|
325
374
|
- QuickJS is an interpreter. Glue code and filtering tool results are fast enough; heavy computation is slower than in V8.
|
package/dist/declarations.d.ts
CHANGED
|
@@ -3,11 +3,6 @@ export { toCodemodeIdentifier };
|
|
|
3
3
|
import type { CodemodeJsonSchema, CodemodeTool } from "./types.ts";
|
|
4
4
|
/** Largest rendered input type, in characters, before it becomes `unknown`. */
|
|
5
5
|
export declare const DEFAULT_INPUT_SCHEMA_MAX_CHARS = 16000;
|
|
6
|
-
/**
|
|
7
|
-
* TypeScript types for MCP results, from the MCP `CallToolResult` schema, so `CallToolResult<T>`
|
|
8
|
-
* declarations can refer to them.
|
|
9
|
-
*/
|
|
10
|
-
export declare const MCP_TYPESCRIPT_PREAMBLE = "type Role = \"user\" | \"assistant\";\ntype MetaObject = Record<string, unknown>;\ntype Annotations = {\n audience?: Role[];\n priority?: number;\n lastModified?: string;\n};\ntype Icon = {\n src: string;\n mimeType?: string;\n sizes?: string[];\n theme?: \"light\" | \"dark\";\n};\ntype TextResourceContents = {\n uri: string;\n mimeType?: string;\n _meta?: MetaObject;\n text: string;\n};\ntype BlobResourceContents = {\n uri: string;\n mimeType?: string;\n _meta?: MetaObject;\n blob: string;\n};\ntype TextContent = {\n type: \"text\";\n text: string;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype ImageContent = {\n type: \"image\";\n data: string;\n mimeType: string;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype AudioContent = {\n type: \"audio\";\n data: string;\n mimeType: string;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype ResourceLink = {\n icons?: Icon[];\n name: string;\n title?: string;\n uri: string;\n description?: string;\n mimeType?: string;\n annotations?: Annotations;\n size?: number;\n _meta?: MetaObject;\n type: \"resource_link\";\n};\ntype EmbeddedResource = {\n type: \"resource\";\n resource: TextResourceContents | BlobResourceContents;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype ContentBlock =\n | TextContent\n | ImageContent\n | AudioContent\n | ResourceLink\n | EmbeddedResource;\ntype CallToolResult<TStructured = { [key: string]: unknown }> = {\n _meta?: MetaObject;\n content: ContentBlock[];\n isError?: boolean;\n structuredContent?: TStructured;\n [key: string]: unknown;\n};";
|
|
11
6
|
export interface RenderDeclarationsOptions {
|
|
12
7
|
tools?: readonly CodemodeTool[];
|
|
13
8
|
globals?: readonly CodemodeTool[];
|
|
@@ -21,8 +16,6 @@ export declare function renderDeclarations(options: RenderDeclarationsOptions):
|
|
|
21
16
|
/**
|
|
22
17
|
* One tool as a member of the `tools` object: `name(args: T): Promise<R>;` with the
|
|
23
18
|
* name as the identifier scripts use. Input types longer than `inputMaxChars` render as `unknown`.
|
|
24
|
-
* Tools whose output schema is an MCP `CallToolResult` render as `Promise<CallToolResult<T>>`,
|
|
25
|
-
* which needs {@link MCP_TYPESCRIPT_PREAMBLE}.
|
|
26
19
|
*/
|
|
27
20
|
export declare function renderToolSignature(tool: Pick<CodemodeTool, "name" | "inputSchema" | "outputSchema">, options?: {
|
|
28
21
|
inputMaxChars?: number;
|
|
@@ -34,23 +27,15 @@ export declare function renderToolSignature(tool: Pick<CodemodeTool, "name" | "i
|
|
|
34
27
|
export declare function renderToolSample(tool: Pick<CodemodeTool, "name" | "description" | "inputSchema" | "outputSchema">, options?: {
|
|
35
28
|
inputMaxChars?: number;
|
|
36
29
|
}): string;
|
|
37
|
-
/**
|
|
38
|
-
* The `structuredContent` schema of an MCP `CallToolResult` output schema (detected by a
|
|
39
|
-
* `content` array of objects, boolean `isError`, and object `_meta`), `true` when it declares none, or
|
|
40
|
-
* `undefined` when the schema is not a `CallToolResult`.
|
|
41
|
-
*/
|
|
42
|
-
export declare function mcpStructuredContentSchema(schema: CodemodeJsonSchema | undefined): CodemodeJsonSchema | undefined;
|
|
43
|
-
/**
|
|
44
|
-
* The type a tool call resolves to: `CallToolResult<T>` for MCP output schemas (needs
|
|
45
|
-
* {@link MCP_TYPESCRIPT_PREAMBLE}), the schema's type otherwise, and `unknown` without a schema.
|
|
46
|
-
*/
|
|
30
|
+
/** The type a tool call resolves to: the output schema's type, and `unknown` without a schema. */
|
|
47
31
|
export declare function renderToolOutputType(schema: CodemodeJsonSchema | undefined): string;
|
|
48
32
|
/**
|
|
49
33
|
* Convert a JSON Schema to a TypeScript type expression: objects on one line (`{ a: string; b?: number; }`) with properties sorted by name,
|
|
50
|
-
* or one property per line with `//` comments when a property has a description
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* `unknown`.
|
|
34
|
+
* or one property per line with `//` comments when a property has a description or constraints the
|
|
35
|
+
* type cannot express (`// @integer @minimum 1 @default 20`); `Array<T>` for arrays. Local references
|
|
36
|
+
* (`#/$defs/...`, `#/definitions/...`) resolve against `schema`; recursive and remote references
|
|
37
|
+
* render as `unknown`. A result longer than `maxChars` is rendered again without the constraint tags,
|
|
38
|
+
* and renders as `unknown` if it is still too long.
|
|
54
39
|
*/
|
|
55
40
|
export declare function schemaToType(schema: CodemodeJsonSchema, options?: {
|
|
56
41
|
maxChars?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"declarations.d.ts","sourceRoot":"","sources":["../src/declarations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAEhC,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAInE,+EAA+E;AAC/E,eAAO,MAAM,8BAA8B,QAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"declarations.d.ts","sourceRoot":"","sources":["../src/declarations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAEhC,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAInE,+EAA+E;AAC/E,eAAO,MAAM,8BAA8B,QAAS,CAAC;AAyBrD,MAAM,WAAW,yBAAyB;IACzC,KAAK,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAChC,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,MAAM,CAyB7E;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,GAAG,cAAc,CAAC,EACjE,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACtC,MAAM,CAMR;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,GAAG,aAAa,GAAG,cAAc,CAAC,EACjF,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACtC,MAAM,CAGR;AAED,kGAAkG;AAClG,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GAAG,MAAM,CAEnF;AAiCD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAMpG"}
|
package/dist/declarations.js
CHANGED
|
@@ -6,86 +6,27 @@ const INDENT = " ";
|
|
|
6
6
|
export const DEFAULT_INPUT_SCHEMA_MAX_CHARS = 16_000;
|
|
7
7
|
/** Local `$ref` expansions per rendered schema, so shared definitions cannot blow up the output. */
|
|
8
8
|
const MAX_REF_EXPANSIONS = 32;
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
text: string;
|
|
31
|
-
};
|
|
32
|
-
type BlobResourceContents = {
|
|
33
|
-
uri: string;
|
|
34
|
-
mimeType?: string;
|
|
35
|
-
_meta?: MetaObject;
|
|
36
|
-
blob: string;
|
|
37
|
-
};
|
|
38
|
-
type TextContent = {
|
|
39
|
-
type: "text";
|
|
40
|
-
text: string;
|
|
41
|
-
annotations?: Annotations;
|
|
42
|
-
_meta?: MetaObject;
|
|
43
|
-
};
|
|
44
|
-
type ImageContent = {
|
|
45
|
-
type: "image";
|
|
46
|
-
data: string;
|
|
47
|
-
mimeType: string;
|
|
48
|
-
annotations?: Annotations;
|
|
49
|
-
_meta?: MetaObject;
|
|
50
|
-
};
|
|
51
|
-
type AudioContent = {
|
|
52
|
-
type: "audio";
|
|
53
|
-
data: string;
|
|
54
|
-
mimeType: string;
|
|
55
|
-
annotations?: Annotations;
|
|
56
|
-
_meta?: MetaObject;
|
|
57
|
-
};
|
|
58
|
-
type ResourceLink = {
|
|
59
|
-
icons?: Icon[];
|
|
60
|
-
name: string;
|
|
61
|
-
title?: string;
|
|
62
|
-
uri: string;
|
|
63
|
-
description?: string;
|
|
64
|
-
mimeType?: string;
|
|
65
|
-
annotations?: Annotations;
|
|
66
|
-
size?: number;
|
|
67
|
-
_meta?: MetaObject;
|
|
68
|
-
type: "resource_link";
|
|
69
|
-
};
|
|
70
|
-
type EmbeddedResource = {
|
|
71
|
-
type: "resource";
|
|
72
|
-
resource: TextResourceContents | BlobResourceContents;
|
|
73
|
-
annotations?: Annotations;
|
|
74
|
-
_meta?: MetaObject;
|
|
75
|
-
};
|
|
76
|
-
type ContentBlock =
|
|
77
|
-
| TextContent
|
|
78
|
-
| ImageContent
|
|
79
|
-
| AudioContent
|
|
80
|
-
| ResourceLink
|
|
81
|
-
| EmbeddedResource;
|
|
82
|
-
type CallToolResult<TStructured = { [key: string]: unknown }> = {
|
|
83
|
-
_meta?: MetaObject;
|
|
84
|
-
content: ContentBlock[];
|
|
85
|
-
isError?: boolean;
|
|
86
|
-
structuredContent?: TStructured;
|
|
87
|
-
[key: string]: unknown;
|
|
88
|
-
};`;
|
|
9
|
+
/** JSON Schema keywords with a number or string value shown as `@keyword value` property tags. */
|
|
10
|
+
const TAG_KEYWORDS = [
|
|
11
|
+
"minimum",
|
|
12
|
+
"exclusiveMinimum",
|
|
13
|
+
"maximum",
|
|
14
|
+
"exclusiveMaximum",
|
|
15
|
+
"multipleOf",
|
|
16
|
+
"minLength",
|
|
17
|
+
"maxLength",
|
|
18
|
+
"pattern",
|
|
19
|
+
"format",
|
|
20
|
+
"minItems",
|
|
21
|
+
"maxItems",
|
|
22
|
+
];
|
|
23
|
+
/** Tag keywords whose values all hold at once, so only the largest (lower) or smallest (upper) matters. */
|
|
24
|
+
const LOWER_BOUNDS = new Set(["minimum", "exclusiveMinimum", "minLength", "minItems"]);
|
|
25
|
+
const UPPER_BOUNDS = new Set(["maximum", "exclusiveMaximum", "maxLength", "maxItems"]);
|
|
26
|
+
/** Longest property tag; longer ones (large defaults, long patterns) are left out. */
|
|
27
|
+
const MAX_TAG_CHARS = 80;
|
|
28
|
+
/** Characters that end a `//` comment. */
|
|
29
|
+
const LINE_TERMINATORS = /[\r\n\u2028\u2029]/g;
|
|
89
30
|
/**
|
|
90
31
|
* Render TypeScript declarations for the script-visible API. Tools become members of
|
|
91
32
|
* `declare const tools`, globals become `declare function` statements, and `ns.member` globals
|
|
@@ -119,8 +60,6 @@ export function renderDeclarations(options) {
|
|
|
119
60
|
/**
|
|
120
61
|
* One tool as a member of the `tools` object: `name(args: T): Promise<R>;` with the
|
|
121
62
|
* name as the identifier scripts use. Input types longer than `inputMaxChars` render as `unknown`.
|
|
122
|
-
* Tools whose output schema is an MCP `CallToolResult` render as `Promise<CallToolResult<T>>`,
|
|
123
|
-
* which needs {@link MCP_TYPESCRIPT_PREAMBLE}.
|
|
124
63
|
*/
|
|
125
64
|
export function renderToolSignature(tool, options = {}) {
|
|
126
65
|
const input = tool.inputSchema === undefined
|
|
@@ -136,32 +75,8 @@ export function renderToolSample(tool, options = {}) {
|
|
|
136
75
|
const declaration = `declare const tools: { ${renderToolSignature(tool, options)} };`;
|
|
137
76
|
return `${tool.description?.trim() ?? ""}\n\ncodemode tool declaration:\n\`\`\`ts\n${declaration}\n\`\`\``;
|
|
138
77
|
}
|
|
139
|
-
/**
|
|
140
|
-
* The `structuredContent` schema of an MCP `CallToolResult` output schema (detected by a
|
|
141
|
-
* `content` array of objects, boolean `isError`, and object `_meta`), `true` when it declares none, or
|
|
142
|
-
* `undefined` when the schema is not a `CallToolResult`.
|
|
143
|
-
*/
|
|
144
|
-
export function mcpStructuredContentSchema(schema) {
|
|
145
|
-
if (!isObject(schema) || !isObject(schema.properties))
|
|
146
|
-
return undefined;
|
|
147
|
-
const { content, isError, _meta, structuredContent } = schema.properties;
|
|
148
|
-
if (!isObject(content) || content.type !== "array" || !isObject(content.items) || content.items.type !== "object") {
|
|
149
|
-
return undefined;
|
|
150
|
-
}
|
|
151
|
-
if (!isObject(isError) || isError.type !== "boolean" || !isObject(_meta) || _meta.type !== "object")
|
|
152
|
-
return undefined;
|
|
153
|
-
return isObject(structuredContent) || typeof structuredContent === "boolean" ? structuredContent : true;
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* The type a tool call resolves to: `CallToolResult<T>` for MCP output schemas (needs
|
|
157
|
-
* {@link MCP_TYPESCRIPT_PREAMBLE}), the schema's type otherwise, and `unknown` without a schema.
|
|
158
|
-
*/
|
|
78
|
+
/** The type a tool call resolves to: the output schema's type, and `unknown` without a schema. */
|
|
159
79
|
export function renderToolOutputType(schema) {
|
|
160
|
-
const structured = mcpStructuredContentSchema(schema);
|
|
161
|
-
if (structured !== undefined) {
|
|
162
|
-
const type = schemaToType(structured);
|
|
163
|
-
return type === "unknown" ? "CallToolResult" : `CallToolResult<${type}>`;
|
|
164
|
-
}
|
|
165
80
|
return schema === undefined ? "unknown" : schemaToType(schema);
|
|
166
81
|
}
|
|
167
82
|
function renderGlobal(head, global, indent) {
|
|
@@ -181,12 +96,12 @@ function docComment(description, indent) {
|
|
|
181
96
|
return `${indent}/** ${lines[0]} */\n`;
|
|
182
97
|
return `${indent}/**\n${lines.map((line) => `${indent} *${line ? ` ${line}` : ""}`).join("\n")}\n${indent} */\n`;
|
|
183
98
|
}
|
|
184
|
-
function propertyKey(name) {
|
|
185
|
-
return IDENTIFIER.test(name) ? name : JSON.stringify(name);
|
|
186
|
-
}
|
|
187
99
|
function isObject(value) {
|
|
188
100
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
189
101
|
}
|
|
102
|
+
function propertyKey(name) {
|
|
103
|
+
return IDENTIFIER.test(name) ? name : JSON.stringify(name);
|
|
104
|
+
}
|
|
190
105
|
function union(types) {
|
|
191
106
|
const unique = [...new Set(types)];
|
|
192
107
|
if (unique.includes("unknown"))
|
|
@@ -195,14 +110,19 @@ function union(types) {
|
|
|
195
110
|
}
|
|
196
111
|
/**
|
|
197
112
|
* Convert a JSON Schema to a TypeScript type expression: objects on one line (`{ a: string; b?: number; }`) with properties sorted by name,
|
|
198
|
-
* or one property per line with `//` comments when a property has a description
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* `unknown`.
|
|
113
|
+
* or one property per line with `//` comments when a property has a description or constraints the
|
|
114
|
+
* type cannot express (`// @integer @minimum 1 @default 20`); `Array<T>` for arrays. Local references
|
|
115
|
+
* (`#/$defs/...`, `#/definitions/...`) resolve against `schema`; recursive and remote references
|
|
116
|
+
* render as `unknown`. A result longer than `maxChars` is rendered again without the constraint tags,
|
|
117
|
+
* and renders as `unknown` if it is still too long.
|
|
202
118
|
*/
|
|
203
119
|
export function schemaToType(schema, options = {}) {
|
|
204
|
-
const
|
|
205
|
-
|
|
120
|
+
const render = (tags) => toType(schema, { root: schema, resolving: new Set(), expansions: 0, tags });
|
|
121
|
+
const type = render(true);
|
|
122
|
+
if (options.maxChars === undefined || type.length <= options.maxChars)
|
|
123
|
+
return type;
|
|
124
|
+
const untagged = render(false);
|
|
125
|
+
return untagged.length <= options.maxChars ? untagged : "unknown";
|
|
206
126
|
}
|
|
207
127
|
function resolveRef(ref, root) {
|
|
208
128
|
if (ref !== "#" && !ref.startsWith("#/"))
|
|
@@ -298,6 +218,58 @@ function arrayType(schema, context) {
|
|
|
298
218
|
function descriptionOf(property) {
|
|
299
219
|
return isObject(property) && typeof property.description === "string" ? property.description.trim() : "";
|
|
300
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* Constraints of a property that its TypeScript type cannot express, as JSDoc-style tags:
|
|
223
|
+
* `@integer @minimum 1 @maximum 100 @default 20`. Empty when there are none.
|
|
224
|
+
*/
|
|
225
|
+
function constraintTags(property) {
|
|
226
|
+
if (!isObject(property))
|
|
227
|
+
return "";
|
|
228
|
+
// Optional fields such as Pydantic's `int | None` keep their constraints in the non-null branch.
|
|
229
|
+
// The branch's constraints apply together with the property's, so both are read.
|
|
230
|
+
const variants = Array.isArray(property.anyOf) ? property.anyOf : property.oneOf;
|
|
231
|
+
const nonNull = Array.isArray(variants)
|
|
232
|
+
? variants.filter((variant) => !isObject(variant) || variant.type !== "null")
|
|
233
|
+
: [];
|
|
234
|
+
const branch = nonNull.length === 1 ? nonNull[0] : undefined;
|
|
235
|
+
const branches = isObject(branch) ? [property, branch] : [property];
|
|
236
|
+
// Draft-04 and OpenAPI 3.0 make `minimum`/`maximum` exclusive with a boolean `exclusiveMinimum`/`exclusiveMaximum`.
|
|
237
|
+
const schemas = branches.map((schema) => ({
|
|
238
|
+
...schema,
|
|
239
|
+
...(schema.exclusiveMinimum === true ? { minimum: undefined, exclusiveMinimum: schema.minimum } : {}),
|
|
240
|
+
...(schema.exclusiveMaximum === true ? { maximum: undefined, exclusiveMaximum: schema.maximum } : {}),
|
|
241
|
+
}));
|
|
242
|
+
const tags = [];
|
|
243
|
+
const isInteger = (type) => type === "integer" || (Array.isArray(type) && type.includes("integer"));
|
|
244
|
+
if (schemas.some((schema) => isInteger(schema.type)))
|
|
245
|
+
tags.push("@integer");
|
|
246
|
+
for (const keyword of TAG_KEYWORDS) {
|
|
247
|
+
const values = schemas.map((schema) => schema[keyword]);
|
|
248
|
+
if (LOWER_BOUNDS.has(keyword) || UPPER_BOUNDS.has(keyword)) {
|
|
249
|
+
const numbers = values.filter((value) => typeof value === "number");
|
|
250
|
+
if (numbers.length === 0)
|
|
251
|
+
continue;
|
|
252
|
+
tags.push(`@${keyword} ${LOWER_BOUNDS.has(keyword) ? Math.max(...numbers) : Math.min(...numbers)}`);
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
for (const value of new Set(values)) {
|
|
256
|
+
if (typeof value === "number" || typeof value === "string")
|
|
257
|
+
tags.push(`@${keyword} ${value}`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
if (schemas.some((schema) => schema.uniqueItems === true))
|
|
261
|
+
tags.push("@uniqueItems");
|
|
262
|
+
// Annotations, unlike constraints, come from the property itself.
|
|
263
|
+
if (property.default !== undefined && property.default !== null) {
|
|
264
|
+
tags.push(`@default ${JSON.stringify(property.default)}`);
|
|
265
|
+
}
|
|
266
|
+
if (property.deprecated === true)
|
|
267
|
+
tags.push("@deprecated");
|
|
268
|
+
return tags
|
|
269
|
+
.filter((tag) => tag.length <= MAX_TAG_CHARS)
|
|
270
|
+
.map((tag) => tag.replace(LINE_TERMINATORS, (char) => `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}`))
|
|
271
|
+
.join(" ");
|
|
272
|
+
}
|
|
301
273
|
function objectType(schema, context) {
|
|
302
274
|
const properties = isObject(schema.properties) ? schema.properties : {};
|
|
303
275
|
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
@@ -316,14 +288,20 @@ function objectType(schema, context) {
|
|
|
316
288
|
}
|
|
317
289
|
if (members.length === 0)
|
|
318
290
|
return "{}";
|
|
319
|
-
|
|
291
|
+
const comments = names.map((name) => {
|
|
292
|
+
const lines = descriptionOf(properties[name])
|
|
293
|
+
.split(LINE_TERMINATORS)
|
|
294
|
+
.map((line) => line.trim())
|
|
295
|
+
.filter(Boolean);
|
|
296
|
+
const tags = context.tags ? constraintTags(properties[name]) : "";
|
|
297
|
+
return tags ? [...lines, tags] : lines;
|
|
298
|
+
});
|
|
299
|
+
if (!comments.some((comment) => comment.length > 0))
|
|
320
300
|
return `{ ${members.join(" ")} }`;
|
|
321
301
|
const lines = ["{"];
|
|
322
|
-
|
|
323
|
-
for (const line of
|
|
324
|
-
|
|
325
|
-
lines.push(`${INDENT}// ${line.trim()}`);
|
|
326
|
-
}
|
|
302
|
+
comments.forEach((comment, index) => {
|
|
303
|
+
for (const line of comment)
|
|
304
|
+
lines.push(`${INDENT}// ${line}`);
|
|
327
305
|
lines.push(`${INDENT}${members[index].replaceAll("\n", `\n${INDENT}`)}`);
|
|
328
306
|
});
|
|
329
307
|
for (const member of members.slice(names.length))
|
package/dist/declarations.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"declarations.js","sourceRoot":"","sources":["../src/declarations.ts"],"names":[],"mappings":"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","sourcesContent":["import { toCodemodeIdentifier } from \"./identifier.ts\";\n\nexport { toCodemodeIdentifier };\n\nimport type { CodemodeJsonSchema, CodemodeTool } from \"./types.ts\";\n\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nconst INDENT = \" \";\n/** Largest rendered input type, in characters, before it becomes `unknown`. */\nexport const DEFAULT_INPUT_SCHEMA_MAX_CHARS = 16_000;\n/** Local `$ref` expansions per rendered schema, so shared definitions cannot blow up the output. */\nconst MAX_REF_EXPANSIONS = 32;\n\n/**\n * TypeScript types for MCP results, from the MCP `CallToolResult` schema, so `CallToolResult<T>`\n * declarations can refer to them.\n */\nexport const MCP_TYPESCRIPT_PREAMBLE = `type Role = \"user\" | \"assistant\";\ntype MetaObject = Record<string, unknown>;\ntype Annotations = {\n audience?: Role[];\n priority?: number;\n lastModified?: string;\n};\ntype Icon = {\n src: string;\n mimeType?: string;\n sizes?: string[];\n theme?: \"light\" | \"dark\";\n};\ntype TextResourceContents = {\n uri: string;\n mimeType?: string;\n _meta?: MetaObject;\n text: string;\n};\ntype BlobResourceContents = {\n uri: string;\n mimeType?: string;\n _meta?: MetaObject;\n blob: string;\n};\ntype TextContent = {\n type: \"text\";\n text: string;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype ImageContent = {\n type: \"image\";\n data: string;\n mimeType: string;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype AudioContent = {\n type: \"audio\";\n data: string;\n mimeType: string;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype ResourceLink = {\n icons?: Icon[];\n name: string;\n title?: string;\n uri: string;\n description?: string;\n mimeType?: string;\n annotations?: Annotations;\n size?: number;\n _meta?: MetaObject;\n type: \"resource_link\";\n};\ntype EmbeddedResource = {\n type: \"resource\";\n resource: TextResourceContents | BlobResourceContents;\n annotations?: Annotations;\n _meta?: MetaObject;\n};\ntype ContentBlock =\n | TextContent\n | ImageContent\n | AudioContent\n | ResourceLink\n | EmbeddedResource;\ntype CallToolResult<TStructured = { [key: string]: unknown }> = {\n _meta?: MetaObject;\n content: ContentBlock[];\n isError?: boolean;\n structuredContent?: TStructured;\n [key: string]: unknown;\n};`;\n\nexport interface RenderDeclarationsOptions {\n\ttools?: readonly CodemodeTool[];\n\tglobals?: readonly CodemodeTool[];\n}\n\n/**\n * Render TypeScript declarations for the script-visible API. Tools become members of\n * `declare const tools`, globals become `declare function` statements, and `ns.member` globals\n * members of `declare const ns`. Descriptions become doc comments; schemas become types.\n */\nexport function renderDeclarations(options: RenderDeclarationsOptions): string {\n\tconst sections: string[] = [];\n\tconst tools = options.tools ?? [];\n\tif (tools.length > 0) {\n\t\tconst members = tools.map(\n\t\t\t(tool) => `${docComment(tool.description, INDENT)}${INDENT}${renderToolSignature(tool)}`,\n\t\t);\n\t\tsections.push(`declare const tools: {\\n${members.join(\"\\n\")}\\n};`);\n\t}\n\tconst namespaces = new Map<string, string[]>();\n\tfor (const global of options.globals ?? []) {\n\t\tconst dot = global.name.indexOf(\".\");\n\t\tif (dot === -1) {\n\t\t\tsections.push(renderGlobal(`declare function ${global.name}`, global, \"\"));\n\t\t\tcontinue;\n\t\t}\n\t\tconst namespace = global.name.slice(0, dot);\n\t\tconst members = namespaces.get(namespace) ?? [];\n\t\tif (members.length === 0) namespaces.set(namespace, members);\n\t\tmembers.push(renderGlobal(global.name.slice(dot + 1), global, INDENT));\n\t}\n\tfor (const [namespace, members] of namespaces) {\n\t\tsections.push(`declare const ${namespace}: {\\n${members.join(\"\\n\")}\\n};`);\n\t}\n\treturn sections.join(\"\\n\\n\");\n}\n\n/**\n * One tool as a member of the `tools` object: `name(args: T): Promise<R>;` with the\n * name as the identifier scripts use. Input types longer than `inputMaxChars` render as `unknown`.\n * Tools whose output schema is an MCP `CallToolResult` render as `Promise<CallToolResult<T>>`,\n * which needs {@link MCP_TYPESCRIPT_PREAMBLE}.\n */\nexport function renderToolSignature(\n\ttool: Pick<CodemodeTool, \"name\" | \"inputSchema\" | \"outputSchema\">,\n\toptions: { inputMaxChars?: number } = {},\n): string {\n\tconst input =\n\t\ttool.inputSchema === undefined\n\t\t\t? \"unknown\"\n\t\t\t: schemaToType(tool.inputSchema, { maxChars: options.inputMaxChars ?? DEFAULT_INPUT_SCHEMA_MAX_CHARS });\n\treturn `${toCodemodeIdentifier(tool.name)}(args: ${input}): Promise<${renderToolOutputType(tool.outputSchema)}>;`;\n}\n\n/**\n * A tool's sample: the description followed by the tool's declaration. Used for tool\n * listings and `ALL_TOOLS` entries.\n */\nexport function renderToolSample(\n\ttool: Pick<CodemodeTool, \"name\" | \"description\" | \"inputSchema\" | \"outputSchema\">,\n\toptions: { inputMaxChars?: number } = {},\n): string {\n\tconst declaration = `declare const tools: { ${renderToolSignature(tool, options)} };`;\n\treturn `${tool.description?.trim() ?? \"\"}\\n\\ncodemode tool declaration:\\n\\`\\`\\`ts\\n${declaration}\\n\\`\\`\\``;\n}\n\n/**\n * The `structuredContent` schema of an MCP `CallToolResult` output schema (detected by a\n * `content` array of objects, boolean `isError`, and object `_meta`), `true` when it declares none, or\n * `undefined` when the schema is not a `CallToolResult`.\n */\nexport function mcpStructuredContentSchema(schema: CodemodeJsonSchema | undefined): CodemodeJsonSchema | undefined {\n\tif (!isObject(schema) || !isObject(schema.properties)) return undefined;\n\tconst { content, isError, _meta, structuredContent } = schema.properties;\n\tif (!isObject(content) || content.type !== \"array\" || !isObject(content.items) || content.items.type !== \"object\") {\n\t\treturn undefined;\n\t}\n\tif (!isObject(isError) || isError.type !== \"boolean\" || !isObject(_meta) || _meta.type !== \"object\")\n\t\treturn undefined;\n\treturn isObject(structuredContent) || typeof structuredContent === \"boolean\" ? structuredContent : true;\n}\n\n/**\n * The type a tool call resolves to: `CallToolResult<T>` for MCP output schemas (needs\n * {@link MCP_TYPESCRIPT_PREAMBLE}), the schema's type otherwise, and `unknown` without a schema.\n */\nexport function renderToolOutputType(schema: CodemodeJsonSchema | undefined): string {\n\tconst structured = mcpStructuredContentSchema(schema);\n\tif (structured !== undefined) {\n\t\tconst type = schemaToType(structured);\n\t\treturn type === \"unknown\" ? \"CallToolResult\" : `CallToolResult<${type}>`;\n\t}\n\treturn schema === undefined ? \"unknown\" : schemaToType(schema);\n}\n\nfunction renderGlobal(head: string, global: CodemodeTool, indent: string): string {\n\tif (global.signature !== undefined) {\n\t\treturn `${docComment(global.description, indent)}${indent}${head}${global.signature};`;\n\t}\n\tconst input = global.inputSchema === undefined ? \"unknown\" : schemaToType(global.inputSchema);\n\tconst output = global.outputSchema === undefined ? \"unknown\" : schemaToType(global.outputSchema);\n\treturn `${docComment(global.description, indent)}${indent}${head}(args: ${input}): Promise<${output}>;`;\n}\n\nfunction docComment(description: string | undefined, indent: string): string {\n\tconst text = description?.trim();\n\tif (!text) return \"\";\n\tconst lines = text.replaceAll(\"*/\", \"*\\\\/\").split(/\\r?\\n/);\n\tif (lines.length === 1) return `${indent}/** ${lines[0]} */\\n`;\n\treturn `${indent}/**\\n${lines.map((line) => `${indent} *${line ? ` ${line}` : \"\"}`).join(\"\\n\")}\\n${indent} */\\n`;\n}\n\nfunction propertyKey(name: string): string {\n\treturn IDENTIFIER.test(name) ? name : JSON.stringify(name);\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction union(types: string[]): string {\n\tconst unique = [...new Set(types)];\n\tif (unique.includes(\"unknown\")) return \"unknown\";\n\treturn unique.length === 0 ? \"never\" : unique.join(\" | \");\n}\n\n/**\n * Convert a JSON Schema to a TypeScript type expression: objects on one line (`{ a: string; b?: number; }`) with properties sorted by name,\n * or one property per line with `//` comments when a property has a description; `Array<T>` for\n * arrays. Local references (`#/$defs/...`, `#/definitions/...`) resolve against `schema`;\n * recursive and remote references render as `unknown`. A result longer than `maxChars` renders as\n * `unknown`.\n */\nexport function schemaToType(schema: CodemodeJsonSchema, options: { maxChars?: number } = {}): string {\n\tconst type = toType(schema, { root: schema, resolving: new Set(), expansions: 0 });\n\treturn options.maxChars !== undefined && type.length > options.maxChars ? \"unknown\" : type;\n}\n\ninterface SchemaContext {\n\troot: CodemodeJsonSchema;\n\t/** References being expanded on the current path, to stop at recursive types. */\n\tresolving: Set<string>;\n\texpansions: number;\n}\n\nfunction resolveRef(ref: string, root: CodemodeJsonSchema): CodemodeJsonSchema | undefined {\n\tif (ref !== \"#\" && !ref.startsWith(\"#/\")) return undefined;\n\tlet current: unknown = root;\n\tfor (const segment of ref.slice(2).split(\"/\").filter(Boolean)) {\n\t\tconst key = decodeURIComponent(segment).replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\");\n\t\tif (!isObject(current) || !(key in current)) return undefined;\n\t\tcurrent = current[key];\n\t}\n\treturn typeof current === \"boolean\" || isObject(current) ? current : undefined;\n}\n\nfunction toType(schema: CodemodeJsonSchema, context: SchemaContext): string {\n\tif (schema === true) return \"unknown\";\n\tif (schema === false) return \"never\";\n\tif (!isObject(schema)) return \"unknown\";\n\tif (typeof schema.$ref === \"string\") {\n\t\tconst ref = schema.$ref;\n\t\tif (context.resolving.has(ref) || context.expansions >= MAX_REF_EXPANSIONS) return \"unknown\";\n\t\tconst target = resolveRef(ref, context.root);\n\t\tif (target === undefined) return \"unknown\";\n\t\tcontext.expansions++;\n\t\tcontext.resolving.add(ref);\n\t\ttry {\n\t\t\treturn toType(target, context);\n\t\t} finally {\n\t\t\tcontext.resolving.delete(ref);\n\t\t}\n\t}\n\n\tif (\"const\" in schema) return JSON.stringify(schema.const) ?? \"unknown\";\n\tif (Array.isArray(schema.enum)) return union(schema.enum.map((value) => JSON.stringify(value) ?? \"unknown\"));\n\n\tconst variants = Array.isArray(schema.anyOf) ? schema.anyOf : Array.isArray(schema.oneOf) ? schema.oneOf : undefined;\n\tif (variants) return union(variants.map((variant) => toType(variant as CodemodeJsonSchema, context)));\n\tif (Array.isArray(schema.allOf)) {\n\t\tconst parts = schema.allOf\n\t\t\t.map((part) => toType(part as CodemodeJsonSchema, context))\n\t\t\t.filter((part) => part !== \"unknown\");\n\t\treturn parts.length === 0\n\t\t\t? \"unknown\"\n\t\t\t: parts.map((part) => (part.includes(\" | \") ? `(${part})` : part)).join(\" & \");\n\t}\n\n\tconst type = schema.type;\n\tif (Array.isArray(type)) return union(type.map((entry) => toType({ ...schema, type: entry }, context)));\n\tswitch (type) {\n\t\tcase \"string\":\n\t\t\treturn \"string\";\n\t\tcase \"number\":\n\t\tcase \"integer\":\n\t\t\treturn \"number\";\n\t\tcase \"boolean\":\n\t\t\treturn \"boolean\";\n\t\tcase \"null\":\n\t\t\treturn \"null\";\n\t\tcase \"array\":\n\t\t\treturn arrayType(schema, context);\n\t\tcase \"object\":\n\t\t\treturn objectType(schema, context);\n\t\tcase undefined:\n\t\t\tif (\"properties\" in schema || \"additionalProperties\" in schema || \"required\" in schema) {\n\t\t\t\treturn objectType(schema, context);\n\t\t\t}\n\t\t\tif (\"items\" in schema || \"prefixItems\" in schema) return arrayType(schema, context);\n\t\t\treturn \"unknown\";\n\t\tdefault:\n\t\t\treturn \"unknown\";\n\t}\n}\n\nfunction arrayType(schema: Record<string, unknown>, context: SchemaContext): string {\n\tif (schema.items !== undefined && !Array.isArray(schema.items)) {\n\t\treturn `Array<${toType(schema.items as CodemodeJsonSchema, context)}>`;\n\t}\n\tconst tuple = Array.isArray(schema.prefixItems)\n\t\t? schema.prefixItems\n\t\t: Array.isArray(schema.items)\n\t\t\t? schema.items\n\t\t\t: [];\n\tif (tuple.length > 0) return `[${tuple.map((item) => toType(item as CodemodeJsonSchema, context)).join(\", \")}]`;\n\treturn \"unknown[]\";\n}\n\nfunction descriptionOf(property: unknown): string {\n\treturn isObject(property) && typeof property.description === \"string\" ? property.description.trim() : \"\";\n}\n\nfunction objectType(schema: Record<string, unknown>, context: SchemaContext): string {\n\tconst properties = isObject(schema.properties) ? schema.properties : {};\n\tconst required = new Set(Array.isArray(schema.required) ? schema.required : []);\n\tconst names = Object.keys(properties).sort();\n\tconst members = names.map((name) => {\n\t\tconst optional = required.has(name) ? \"\" : \"?\";\n\t\treturn `${propertyKey(name)}${optional}: ${toType(properties[name] as CodemodeJsonSchema, context)};`;\n\t});\n\tconst additional = schema.additionalProperties;\n\tif (additional !== undefined && additional !== false) {\n\t\tconst type = additional === true ? \"unknown\" : toType(additional as CodemodeJsonSchema, context);\n\t\tmembers.push(`[key: string]: ${type};`);\n\t} else if (additional === undefined && names.length === 0) {\n\t\tmembers.push(\"[key: string]: unknown;\");\n\t}\n\tif (members.length === 0) return \"{}\";\n\tif (!names.some((name) => descriptionOf(properties[name]))) return `{ ${members.join(\" \")} }`;\n\n\tconst lines = [\"{\"];\n\tnames.forEach((name, index) => {\n\t\tfor (const line of descriptionOf(properties[name]).split(/\\r?\\n/)) {\n\t\t\tif (line.trim()) lines.push(`${INDENT}// ${line.trim()}`);\n\t\t}\n\t\tlines.push(`${INDENT}${members[index].replaceAll(\"\\n\", `\\n${INDENT}`)}`);\n\t});\n\tfor (const member of members.slice(names.length)) lines.push(`${INDENT}${member}`);\n\tlines.push(\"}\");\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"declarations.js","sourceRoot":"","sources":["../src/declarations.ts"],"names":[],"mappings":"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","sourcesContent":["import { toCodemodeIdentifier } from \"./identifier.ts\";\n\nexport { toCodemodeIdentifier };\n\nimport type { CodemodeJsonSchema, CodemodeTool } from \"./types.ts\";\n\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nconst INDENT = \" \";\n/** Largest rendered input type, in characters, before it becomes `unknown`. */\nexport const DEFAULT_INPUT_SCHEMA_MAX_CHARS = 16_000;\n/** Local `$ref` expansions per rendered schema, so shared definitions cannot blow up the output. */\nconst MAX_REF_EXPANSIONS = 32;\n/** JSON Schema keywords with a number or string value shown as `@keyword value` property tags. */\nconst TAG_KEYWORDS = [\n\t\"minimum\",\n\t\"exclusiveMinimum\",\n\t\"maximum\",\n\t\"exclusiveMaximum\",\n\t\"multipleOf\",\n\t\"minLength\",\n\t\"maxLength\",\n\t\"pattern\",\n\t\"format\",\n\t\"minItems\",\n\t\"maxItems\",\n];\n/** Tag keywords whose values all hold at once, so only the largest (lower) or smallest (upper) matters. */\nconst LOWER_BOUNDS = new Set([\"minimum\", \"exclusiveMinimum\", \"minLength\", \"minItems\"]);\nconst UPPER_BOUNDS = new Set([\"maximum\", \"exclusiveMaximum\", \"maxLength\", \"maxItems\"]);\n/** Longest property tag; longer ones (large defaults, long patterns) are left out. */\nconst MAX_TAG_CHARS = 80;\n/** Characters that end a `//` comment. */\nconst LINE_TERMINATORS = /[\\r\\n\\u2028\\u2029]/g;\n\nexport interface RenderDeclarationsOptions {\n\ttools?: readonly CodemodeTool[];\n\tglobals?: readonly CodemodeTool[];\n}\n\n/**\n * Render TypeScript declarations for the script-visible API. Tools become members of\n * `declare const tools`, globals become `declare function` statements, and `ns.member` globals\n * members of `declare const ns`. Descriptions become doc comments; schemas become types.\n */\nexport function renderDeclarations(options: RenderDeclarationsOptions): string {\n\tconst sections: string[] = [];\n\tconst tools = options.tools ?? [];\n\tif (tools.length > 0) {\n\t\tconst members = tools.map(\n\t\t\t(tool) => `${docComment(tool.description, INDENT)}${INDENT}${renderToolSignature(tool)}`,\n\t\t);\n\t\tsections.push(`declare const tools: {\\n${members.join(\"\\n\")}\\n};`);\n\t}\n\tconst namespaces = new Map<string, string[]>();\n\tfor (const global of options.globals ?? []) {\n\t\tconst dot = global.name.indexOf(\".\");\n\t\tif (dot === -1) {\n\t\t\tsections.push(renderGlobal(`declare function ${global.name}`, global, \"\"));\n\t\t\tcontinue;\n\t\t}\n\t\tconst namespace = global.name.slice(0, dot);\n\t\tconst members = namespaces.get(namespace) ?? [];\n\t\tif (members.length === 0) namespaces.set(namespace, members);\n\t\tmembers.push(renderGlobal(global.name.slice(dot + 1), global, INDENT));\n\t}\n\tfor (const [namespace, members] of namespaces) {\n\t\tsections.push(`declare const ${namespace}: {\\n${members.join(\"\\n\")}\\n};`);\n\t}\n\treturn sections.join(\"\\n\\n\");\n}\n\n/**\n * One tool as a member of the `tools` object: `name(args: T): Promise<R>;` with the\n * name as the identifier scripts use. Input types longer than `inputMaxChars` render as `unknown`.\n */\nexport function renderToolSignature(\n\ttool: Pick<CodemodeTool, \"name\" | \"inputSchema\" | \"outputSchema\">,\n\toptions: { inputMaxChars?: number } = {},\n): string {\n\tconst input =\n\t\ttool.inputSchema === undefined\n\t\t\t? \"unknown\"\n\t\t\t: schemaToType(tool.inputSchema, { maxChars: options.inputMaxChars ?? DEFAULT_INPUT_SCHEMA_MAX_CHARS });\n\treturn `${toCodemodeIdentifier(tool.name)}(args: ${input}): Promise<${renderToolOutputType(tool.outputSchema)}>;`;\n}\n\n/**\n * A tool's sample: the description followed by the tool's declaration. Used for tool\n * listings and `ALL_TOOLS` entries.\n */\nexport function renderToolSample(\n\ttool: Pick<CodemodeTool, \"name\" | \"description\" | \"inputSchema\" | \"outputSchema\">,\n\toptions: { inputMaxChars?: number } = {},\n): string {\n\tconst declaration = `declare const tools: { ${renderToolSignature(tool, options)} };`;\n\treturn `${tool.description?.trim() ?? \"\"}\\n\\ncodemode tool declaration:\\n\\`\\`\\`ts\\n${declaration}\\n\\`\\`\\``;\n}\n\n/** The type a tool call resolves to: the output schema's type, and `unknown` without a schema. */\nexport function renderToolOutputType(schema: CodemodeJsonSchema | undefined): string {\n\treturn schema === undefined ? \"unknown\" : schemaToType(schema);\n}\n\nfunction renderGlobal(head: string, global: CodemodeTool, indent: string): string {\n\tif (global.signature !== undefined) {\n\t\treturn `${docComment(global.description, indent)}${indent}${head}${global.signature};`;\n\t}\n\tconst input = global.inputSchema === undefined ? \"unknown\" : schemaToType(global.inputSchema);\n\tconst output = global.outputSchema === undefined ? \"unknown\" : schemaToType(global.outputSchema);\n\treturn `${docComment(global.description, indent)}${indent}${head}(args: ${input}): Promise<${output}>;`;\n}\n\nfunction docComment(description: string | undefined, indent: string): string {\n\tconst text = description?.trim();\n\tif (!text) return \"\";\n\tconst lines = text.replaceAll(\"*/\", \"*\\\\/\").split(/\\r?\\n/);\n\tif (lines.length === 1) return `${indent}/** ${lines[0]} */\\n`;\n\treturn `${indent}/**\\n${lines.map((line) => `${indent} *${line ? ` ${line}` : \"\"}`).join(\"\\n\")}\\n${indent} */\\n`;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction propertyKey(name: string): string {\n\treturn IDENTIFIER.test(name) ? name : JSON.stringify(name);\n}\n\nfunction union(types: string[]): string {\n\tconst unique = [...new Set(types)];\n\tif (unique.includes(\"unknown\")) return \"unknown\";\n\treturn unique.length === 0 ? \"never\" : unique.join(\" | \");\n}\n\n/**\n * Convert a JSON Schema to a TypeScript type expression: objects on one line (`{ a: string; b?: number; }`) with properties sorted by name,\n * or one property per line with `//` comments when a property has a description or constraints the\n * type cannot express (`// @integer @minimum 1 @default 20`); `Array<T>` for arrays. Local references\n * (`#/$defs/...`, `#/definitions/...`) resolve against `schema`; recursive and remote references\n * render as `unknown`. A result longer than `maxChars` is rendered again without the constraint tags,\n * and renders as `unknown` if it is still too long.\n */\nexport function schemaToType(schema: CodemodeJsonSchema, options: { maxChars?: number } = {}): string {\n\tconst render = (tags: boolean) => toType(schema, { root: schema, resolving: new Set(), expansions: 0, tags });\n\tconst type = render(true);\n\tif (options.maxChars === undefined || type.length <= options.maxChars) return type;\n\tconst untagged = render(false);\n\treturn untagged.length <= options.maxChars ? untagged : \"unknown\";\n}\n\ninterface SchemaContext {\n\troot: CodemodeJsonSchema;\n\t/** References being expanded on the current path, to stop at recursive types. */\n\tresolving: Set<string>;\n\texpansions: number;\n\t/** Whether property comments include constraint tags. */\n\ttags: boolean;\n}\n\nfunction resolveRef(ref: string, root: CodemodeJsonSchema): CodemodeJsonSchema | undefined {\n\tif (ref !== \"#\" && !ref.startsWith(\"#/\")) return undefined;\n\tlet current: unknown = root;\n\tfor (const segment of ref.slice(2).split(\"/\").filter(Boolean)) {\n\t\tconst key = decodeURIComponent(segment).replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\");\n\t\tif (!isObject(current) || !(key in current)) return undefined;\n\t\tcurrent = current[key];\n\t}\n\treturn typeof current === \"boolean\" || isObject(current) ? current : undefined;\n}\n\nfunction toType(schema: CodemodeJsonSchema, context: SchemaContext): string {\n\tif (schema === true) return \"unknown\";\n\tif (schema === false) return \"never\";\n\tif (!isObject(schema)) return \"unknown\";\n\tif (typeof schema.$ref === \"string\") {\n\t\tconst ref = schema.$ref;\n\t\tif (context.resolving.has(ref) || context.expansions >= MAX_REF_EXPANSIONS) return \"unknown\";\n\t\tconst target = resolveRef(ref, context.root);\n\t\tif (target === undefined) return \"unknown\";\n\t\tcontext.expansions++;\n\t\tcontext.resolving.add(ref);\n\t\ttry {\n\t\t\treturn toType(target, context);\n\t\t} finally {\n\t\t\tcontext.resolving.delete(ref);\n\t\t}\n\t}\n\n\tif (\"const\" in schema) return JSON.stringify(schema.const) ?? \"unknown\";\n\tif (Array.isArray(schema.enum)) return union(schema.enum.map((value) => JSON.stringify(value) ?? \"unknown\"));\n\n\tconst variants = Array.isArray(schema.anyOf) ? schema.anyOf : Array.isArray(schema.oneOf) ? schema.oneOf : undefined;\n\tif (variants) return union(variants.map((variant) => toType(variant as CodemodeJsonSchema, context)));\n\tif (Array.isArray(schema.allOf)) {\n\t\tconst parts = schema.allOf\n\t\t\t.map((part) => toType(part as CodemodeJsonSchema, context))\n\t\t\t.filter((part) => part !== \"unknown\");\n\t\treturn parts.length === 0\n\t\t\t? \"unknown\"\n\t\t\t: parts.map((part) => (part.includes(\" | \") ? `(${part})` : part)).join(\" & \");\n\t}\n\n\tconst type = schema.type;\n\tif (Array.isArray(type)) return union(type.map((entry) => toType({ ...schema, type: entry }, context)));\n\tswitch (type) {\n\t\tcase \"string\":\n\t\t\treturn \"string\";\n\t\tcase \"number\":\n\t\tcase \"integer\":\n\t\t\treturn \"number\";\n\t\tcase \"boolean\":\n\t\t\treturn \"boolean\";\n\t\tcase \"null\":\n\t\t\treturn \"null\";\n\t\tcase \"array\":\n\t\t\treturn arrayType(schema, context);\n\t\tcase \"object\":\n\t\t\treturn objectType(schema, context);\n\t\tcase undefined:\n\t\t\tif (\"properties\" in schema || \"additionalProperties\" in schema || \"required\" in schema) {\n\t\t\t\treturn objectType(schema, context);\n\t\t\t}\n\t\t\tif (\"items\" in schema || \"prefixItems\" in schema) return arrayType(schema, context);\n\t\t\treturn \"unknown\";\n\t\tdefault:\n\t\t\treturn \"unknown\";\n\t}\n}\n\nfunction arrayType(schema: Record<string, unknown>, context: SchemaContext): string {\n\tif (schema.items !== undefined && !Array.isArray(schema.items)) {\n\t\treturn `Array<${toType(schema.items as CodemodeJsonSchema, context)}>`;\n\t}\n\tconst tuple = Array.isArray(schema.prefixItems)\n\t\t? schema.prefixItems\n\t\t: Array.isArray(schema.items)\n\t\t\t? schema.items\n\t\t\t: [];\n\tif (tuple.length > 0) return `[${tuple.map((item) => toType(item as CodemodeJsonSchema, context)).join(\", \")}]`;\n\treturn \"unknown[]\";\n}\n\nfunction descriptionOf(property: unknown): string {\n\treturn isObject(property) && typeof property.description === \"string\" ? property.description.trim() : \"\";\n}\n\n/**\n * Constraints of a property that its TypeScript type cannot express, as JSDoc-style tags:\n * `@integer @minimum 1 @maximum 100 @default 20`. Empty when there are none.\n */\nfunction constraintTags(property: unknown): string {\n\tif (!isObject(property)) return \"\";\n\t// Optional fields such as Pydantic's `int | None` keep their constraints in the non-null branch.\n\t// The branch's constraints apply together with the property's, so both are read.\n\tconst variants = Array.isArray(property.anyOf) ? property.anyOf : property.oneOf;\n\tconst nonNull: unknown[] = Array.isArray(variants)\n\t\t? variants.filter((variant) => !isObject(variant) || variant.type !== \"null\")\n\t\t: [];\n\tconst branch = nonNull.length === 1 ? nonNull[0] : undefined;\n\tconst branches = isObject(branch) ? [property, branch] : [property];\n\t// Draft-04 and OpenAPI 3.0 make `minimum`/`maximum` exclusive with a boolean `exclusiveMinimum`/`exclusiveMaximum`.\n\tconst schemas = branches.map(\n\t\t(schema): Record<string, unknown> => ({\n\t\t\t...schema,\n\t\t\t...(schema.exclusiveMinimum === true ? { minimum: undefined, exclusiveMinimum: schema.minimum } : {}),\n\t\t\t...(schema.exclusiveMaximum === true ? { maximum: undefined, exclusiveMaximum: schema.maximum } : {}),\n\t\t}),\n\t);\n\n\tconst tags: string[] = [];\n\tconst isInteger = (type: unknown) => type === \"integer\" || (Array.isArray(type) && type.includes(\"integer\"));\n\tif (schemas.some((schema) => isInteger(schema.type))) tags.push(\"@integer\");\n\tfor (const keyword of TAG_KEYWORDS) {\n\t\tconst values = schemas.map((schema) => schema[keyword]);\n\t\tif (LOWER_BOUNDS.has(keyword) || UPPER_BOUNDS.has(keyword)) {\n\t\t\tconst numbers = values.filter((value) => typeof value === \"number\");\n\t\t\tif (numbers.length === 0) continue;\n\t\t\ttags.push(`@${keyword} ${LOWER_BOUNDS.has(keyword) ? Math.max(...numbers) : Math.min(...numbers)}`);\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const value of new Set(values)) {\n\t\t\tif (typeof value === \"number\" || typeof value === \"string\") tags.push(`@${keyword} ${value}`);\n\t\t}\n\t}\n\tif (schemas.some((schema) => schema.uniqueItems === true)) tags.push(\"@uniqueItems\");\n\t// Annotations, unlike constraints, come from the property itself.\n\tif (property.default !== undefined && property.default !== null) {\n\t\ttags.push(`@default ${JSON.stringify(property.default)}`);\n\t}\n\tif (property.deprecated === true) tags.push(\"@deprecated\");\n\treturn tags\n\t\t.filter((tag) => tag.length <= MAX_TAG_CHARS)\n\t\t.map((tag) => tag.replace(LINE_TERMINATORS, (char) => `\\\\u${char.charCodeAt(0).toString(16).padStart(4, \"0\")}`))\n\t\t.join(\" \");\n}\n\nfunction objectType(schema: Record<string, unknown>, context: SchemaContext): string {\n\tconst properties = isObject(schema.properties) ? schema.properties : {};\n\tconst required = new Set(Array.isArray(schema.required) ? schema.required : []);\n\tconst names = Object.keys(properties).sort();\n\tconst members = names.map((name) => {\n\t\tconst optional = required.has(name) ? \"\" : \"?\";\n\t\treturn `${propertyKey(name)}${optional}: ${toType(properties[name] as CodemodeJsonSchema, context)};`;\n\t});\n\tconst additional = schema.additionalProperties;\n\tif (additional !== undefined && additional !== false) {\n\t\tconst type = additional === true ? \"unknown\" : toType(additional as CodemodeJsonSchema, context);\n\t\tmembers.push(`[key: string]: ${type};`);\n\t} else if (additional === undefined && names.length === 0) {\n\t\tmembers.push(\"[key: string]: unknown;\");\n\t}\n\tif (members.length === 0) return \"{}\";\n\tconst comments = names.map((name) => {\n\t\tconst lines = descriptionOf(properties[name])\n\t\t\t.split(LINE_TERMINATORS)\n\t\t\t.map((line) => line.trim())\n\t\t\t.filter(Boolean);\n\t\tconst tags = context.tags ? constraintTags(properties[name]) : \"\";\n\t\treturn tags ? [...lines, tags] : lines;\n\t});\n\tif (!comments.some((comment) => comment.length > 0)) return `{ ${members.join(\" \")} }`;\n\n\tconst lines = [\"{\"];\n\tcomments.forEach((comment, index) => {\n\t\tfor (const line of comment) lines.push(`${INDENT}// ${line}`);\n\t\tlines.push(`${INDENT}${members[index].replaceAll(\"\\n\", `\\n${INDENT}`)}`);\n\t});\n\tfor (const member of members.slice(names.length)) lines.push(`${INDENT}${member}`);\n\tlines.push(\"}\");\n\treturn lines.join(\"\\n\");\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { DEFAULT_INPUT_SCHEMA_MAX_CHARS,
|
|
1
|
+
export { DEFAULT_INPUT_SCHEMA_MAX_CHARS, type RenderDeclarationsOptions, renderDeclarations, renderToolOutputType, renderToolSample, renderToolSignature, schemaToType, } from "./declarations.ts";
|
|
2
2
|
export { toCodemodeIdentifier } from "./identifier.ts";
|
|
3
3
|
export { CodemodeSandboxBase } from "./runtime/execution.ts";
|
|
4
4
|
export { CodemodeSandbox } from "./runtime/host.ts";
|
|
@@ -6,6 +6,6 @@ export { DEFAULT_INTERRUPT_BUDGET, InlineCodemodeSandbox, type InlineCodemodeSan
|
|
|
6
6
|
export { MAX_OUTPUT_CHARS, MAX_OUTPUT_ITEMS, MAX_STORE_TOTAL_CHARS, MAX_STORE_VALUE_CHARS, } from "./runtime/prelude-source.ts";
|
|
7
7
|
export { type CodemodeRemote, type CodemodeRemoteExchange, type CodemodeRemoteMessage, type CodemodeRemoteReply, type CodemodeRemoteRequest, type CodemodeServeOptions, RemoteCodemodeSandbox, type RemoteCodemodeSandboxOptions, serveCodemodeRemote, } from "./runtime/remote.ts";
|
|
8
8
|
export { CODEMODE_OPTIONS_PREFIX, CODEMODE_SOURCE_GRAMMAR, CodemodeSourceError, type CodemodeSourceOptions, type ParsedCodemodeSource, parseCodemodeSource, } from "./source.ts";
|
|
9
|
-
export type { CodemodeCall, CodemodeCallStatus, CodemodeError, CodemodeErrorKind, CodemodeExecuteOptions, CodemodeJsonSchema, CodemodeOutputItem, CodemodeResult, CodemodeSandboxBaseOptions, CodemodeSandboxOptions, CodemodeStoreWrites, CodemodeTool, CodemodeToolContext, } from "./types.ts";
|
|
9
|
+
export type { CodemodeCall, CodemodeCallStatus, CodemodeDeclaredGlobal, CodemodeDeclaredTool, CodemodeDuring, CodemodeError, CodemodeErrorKind, CodemodeExecuteOptions, CodemodeHostCall, CodemodeJsonSchema, CodemodeOutcome, CodemodeOutputItem, CodemodeResult, CodemodeRun, CodemodeRunOptions, CodemodeSandboxBaseOptions, CodemodeSandboxOptions, CodemodeStoreWrites, CodemodeTool, CodemodeToolContext, } from "./types.ts";
|
|
10
10
|
export { type CodemodeWasmModule, loadQuickJSWasm } from "./wasm.ts";
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,8BAA8B,EAC9B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,8BAA8B,EAC9B,KAAK,yBAAyB,EAC9B,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EACN,wBAAwB,EACxB,qBAAqB,EACrB,KAAK,4BAA4B,GACjC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,qBAAqB,EACrB,KAAK,4BAA4B,EACjC,mBAAmB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EACnB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,mBAAmB,GACnB,MAAM,aAAa,CAAC;AACrB,YAAY,EACX,YAAY,EACZ,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,0BAA0B,EAC1B,sBAAsB,EACtB,mBAAmB,EACnB,YAAY,EACZ,mBAAmB,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,kBAAkB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC"}
|