@tanstack/ai-code-mode 0.2.12 → 0.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.
Files changed (36) hide show
  1. package/package.json +3 -3
  2. package/skills/ai-code-mode/SKILL.md +79 -0
  3. package/src/create-code-mode-tool.ts +8 -2
  4. package/src/create-code-mode.ts +23 -13
  5. package/src/create-discovery-tool.ts +108 -0
  6. package/src/create-system-prompt.ts +25 -10
  7. package/src/index.ts +2 -0
  8. package/src/types.ts +25 -0
  9. package/dist/esm/agent-store.d.ts +0 -21
  10. package/dist/esm/agent-store.js +0 -29
  11. package/dist/esm/agent-store.js.map +0 -1
  12. package/dist/esm/bindings/tool-to-binding.d.ts +0 -25
  13. package/dist/esm/bindings/tool-to-binding.js +0 -94
  14. package/dist/esm/bindings/tool-to-binding.js.map +0 -1
  15. package/dist/esm/code-wrapper.d.ts +0 -9
  16. package/dist/esm/code-wrapper.js +0 -18
  17. package/dist/esm/code-wrapper.js.map +0 -1
  18. package/dist/esm/create-code-mode-tool.d.ts +0 -50
  19. package/dist/esm/create-code-mode-tool.js +0 -143
  20. package/dist/esm/create-code-mode-tool.js.map +0 -1
  21. package/dist/esm/create-code-mode.d.ts +0 -41
  22. package/dist/esm/create-code-mode.js +0 -12
  23. package/dist/esm/create-code-mode.js.map +0 -1
  24. package/dist/esm/create-system-prompt.d.ts +0 -24
  25. package/dist/esm/create-system-prompt.js +0 -66
  26. package/dist/esm/create-system-prompt.js.map +0 -1
  27. package/dist/esm/index.d.ts +0 -10
  28. package/dist/esm/index.js +0 -23
  29. package/dist/esm/index.js.map +0 -1
  30. package/dist/esm/strip-typescript.d.ts +0 -44
  31. package/dist/esm/strip-typescript.js +0 -49
  32. package/dist/esm/strip-typescript.js.map +0 -1
  33. package/dist/esm/type-generator/json-schema-to-ts.d.ts +0 -31
  34. package/dist/esm/type-generator/json-schema-to-ts.js +0 -100
  35. package/dist/esm/type-generator/json-schema-to-ts.js.map +0 -1
  36. package/dist/esm/types.d.ts +0 -216
@@ -1,50 +0,0 @@
1
- import { z } from 'zod';
2
- import { ServerTool } from '@tanstack/ai';
3
- import { CodeModeToolConfig } from './types.js';
4
- /**
5
- * Schema for the execute_typescript tool input
6
- */
7
- declare const executeTypescriptInputSchema: z.ZodObject<{
8
- typescriptCode: z.ZodString;
9
- }, z.core.$strip>;
10
- /**
11
- * Schema for the execute_typescript tool output
12
- */
13
- declare const executeTypescriptOutputSchema: z.ZodObject<{
14
- success: z.ZodBoolean;
15
- result: z.ZodOptional<z.ZodUnknown>;
16
- logs: z.ZodOptional<z.ZodArray<z.ZodString>>;
17
- error: z.ZodOptional<z.ZodObject<{
18
- message: z.ZodString;
19
- name: z.ZodOptional<z.ZodString>;
20
- line: z.ZodOptional<z.ZodNumber>;
21
- }, z.core.$strip>>;
22
- }, z.core.$strip>;
23
- export type ExecuteTypescriptInput = z.infer<typeof executeTypescriptInputSchema>;
24
- export type ExecuteTypescriptOutput = z.infer<typeof executeTypescriptOutputSchema>;
25
- /**
26
- * Create an execute_typescript tool that can be used alongside other agent tools.
27
- *
28
- * This tool allows an LLM to execute TypeScript code in a secure sandbox.
29
- * Tools passed in the config become `external_*` functions available inside the sandbox.
30
- *
31
- * @example
32
- * ```typescript
33
- * import { createCodeMode } from '@tanstack/ai-code-mode'
34
- * import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'
35
- *
36
- * const { tool, systemPrompt } = createCodeMode({
37
- * driver: createNodeIsolateDriver(),
38
- * tools: [weatherTool, dbTool], // Become external_fetchWeather, external_dbQuery
39
- * timeout: 30000,
40
- * })
41
- *
42
- * chat({
43
- * systemPrompts: [myPrompt, systemPrompt],
44
- * tools: [tool, searchTool, emailTool],
45
- * messages,
46
- * })
47
- * ```
48
- */
49
- export declare function createCodeModeTool(config: CodeModeToolConfig): ServerTool<typeof executeTypescriptInputSchema, typeof executeTypescriptOutputSchema, 'execute_typescript'>;
50
- export {};
@@ -1,143 +0,0 @@
1
- import { z } from "zod";
2
- import { toolDefinition } from "@tanstack/ai";
3
- import { toolsToBindings, createEventAwareBindings } from "./bindings/tool-to-binding.js";
4
- import { stripTypeScript } from "./strip-typescript.js";
5
- const executeTypescriptInputSchema = z.object({
6
- typescriptCode: z.string().describe(
7
- "TypeScript code to execute in the sandbox. Use external_* functions to call available APIs. Return a value to pass results back."
8
- )
9
- });
10
- const executeTypescriptOutputSchema = z.object({
11
- success: z.boolean().describe("Whether execution completed without errors"),
12
- result: z.unknown().optional().describe("Return value from the executed code"),
13
- logs: z.array(z.string()).optional().describe("Console output captured during execution"),
14
- error: z.object({
15
- message: z.string(),
16
- name: z.string().optional(),
17
- line: z.number().optional()
18
- }).optional().describe("Error details if execution failed")
19
- });
20
- function createCodeModeTool(config) {
21
- const {
22
- driver,
23
- tools,
24
- timeout = 3e4,
25
- memoryLimit = 128,
26
- getSkillBindings,
27
- transpile = stripTypeScript
28
- } = config;
29
- if (tools.length === 0) {
30
- throw new Error("At least one tool must be provided to createCodeModeTool");
31
- }
32
- const staticBindings = toolsToBindings(tools, "external_");
33
- const definition = toolDefinition({
34
- name: "execute_typescript",
35
- description: buildToolDescription(tools),
36
- inputSchema: executeTypescriptInputSchema,
37
- outputSchema: executeTypescriptOutputSchema
38
- });
39
- return definition.server(
40
- async (input, toolContext) => {
41
- const { typescriptCode } = input;
42
- const emitCustomEvent = toolContext?.emitCustomEvent || (() => {
43
- });
44
- if (!typescriptCode || typeof typescriptCode !== "string") {
45
- return {
46
- success: false,
47
- error: {
48
- message: "typescriptCode must be a non-empty string",
49
- name: "ValidationError"
50
- }
51
- };
52
- }
53
- let isolateContext = null;
54
- emitCustomEvent("code_mode:execution_started", {
55
- timestamp: Date.now(),
56
- codeLength: typescriptCode.length
57
- });
58
- try {
59
- let strippedCode;
60
- try {
61
- strippedCode = await transpile(typescriptCode);
62
- } catch (error) {
63
- return {
64
- success: false,
65
- error: {
66
- message: error instanceof Error ? error.message : String(error),
67
- name: "TypeScriptError"
68
- }
69
- };
70
- }
71
- const skillBindings = getSkillBindings ? await getSkillBindings() : {};
72
- const allBindings = { ...staticBindings, ...skillBindings };
73
- const eventAwareBindings = createEventAwareBindings(
74
- allBindings,
75
- emitCustomEvent
76
- );
77
- isolateContext = await driver.createContext({
78
- bindings: eventAwareBindings,
79
- timeout,
80
- memoryLimit
81
- });
82
- const executionResult = await isolateContext.execute(strippedCode);
83
- if (executionResult.logs && executionResult.logs.length > 0) {
84
- for (const log of executionResult.logs) {
85
- let level = "log";
86
- let message = log;
87
- if (log.startsWith("ERROR: ")) {
88
- level = "error";
89
- message = log.slice(7);
90
- } else if (log.startsWith("WARN: ")) {
91
- level = "warn";
92
- message = log.slice(6);
93
- } else if (log.startsWith("INFO: ")) {
94
- level = "info";
95
- message = log.slice(6);
96
- }
97
- emitCustomEvent("code_mode:console", {
98
- level,
99
- message,
100
- timestamp: Date.now()
101
- });
102
- }
103
- }
104
- if (executionResult.success) {
105
- return {
106
- success: true,
107
- result: executionResult.value,
108
- logs: executionResult.logs
109
- };
110
- } else {
111
- return {
112
- success: false,
113
- error: executionResult.error ? {
114
- message: executionResult.error.message,
115
- name: executionResult.error.name
116
- } : { message: "Unknown execution error" },
117
- logs: executionResult.logs
118
- };
119
- }
120
- } catch (error) {
121
- return {
122
- success: false,
123
- error: {
124
- message: error instanceof Error ? error.message : String(error),
125
- name: error instanceof Error ? error.name : "Error"
126
- }
127
- };
128
- } finally {
129
- if (isolateContext) {
130
- await isolateContext.dispose();
131
- }
132
- }
133
- }
134
- );
135
- }
136
- function buildToolDescription(tools) {
137
- const externalFunctions = tools.map((t) => `external_${t.name}`).join(", ");
138
- return `Execute TypeScript code in a secure sandbox environment. The code can use these external API functions: ${externalFunctions}. All external_* calls are async and must be awaited. Return a value to pass results back. Use console.log() for debugging.`;
139
- }
140
- export {
141
- createCodeModeTool
142
- };
143
- //# sourceMappingURL=create-code-mode-tool.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-code-mode-tool.js","sources":["../../src/create-code-mode-tool.ts"],"sourcesContent":["import { z } from 'zod'\nimport { toolDefinition } from '@tanstack/ai'\nimport {\n createEventAwareBindings,\n toolsToBindings,\n} from './bindings/tool-to-binding'\nimport { stripTypeScript } from './strip-typescript'\nimport type { ServerTool, ToolExecutionContext } from '@tanstack/ai'\nimport type {\n CodeModeTool,\n CodeModeToolConfig,\n CodeModeToolResult,\n IsolateContext,\n} from './types'\n\n/**\n * Schema for the execute_typescript tool input\n */\nconst executeTypescriptInputSchema = z.object({\n typescriptCode: z\n .string()\n .describe(\n 'TypeScript code to execute in the sandbox. ' +\n 'Use external_* functions to call available APIs. ' +\n 'Return a value to pass results back.',\n ),\n})\n\n/**\n * Schema for the execute_typescript tool output\n */\nconst executeTypescriptOutputSchema = z.object({\n success: z.boolean().describe('Whether execution completed without errors'),\n result: z\n .unknown()\n .optional()\n .describe('Return value from the executed code'),\n logs: z\n .array(z.string())\n .optional()\n .describe('Console output captured during execution'),\n error: z\n .object({\n message: z.string(),\n name: z.string().optional(),\n line: z.number().optional(),\n })\n .optional()\n .describe('Error details if execution failed'),\n})\n\nexport type ExecuteTypescriptInput = z.infer<\n typeof executeTypescriptInputSchema\n>\nexport type ExecuteTypescriptOutput = z.infer<\n typeof executeTypescriptOutputSchema\n>\n\n/**\n * Create an execute_typescript tool that can be used alongside other agent tools.\n *\n * This tool allows an LLM to execute TypeScript code in a secure sandbox.\n * Tools passed in the config become `external_*` functions available inside the sandbox.\n *\n * @example\n * ```typescript\n * import { createCodeMode } from '@tanstack/ai-code-mode'\n * import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'\n *\n * const { tool, systemPrompt } = createCodeMode({\n * driver: createNodeIsolateDriver(),\n * tools: [weatherTool, dbTool], // Become external_fetchWeather, external_dbQuery\n * timeout: 30000,\n * })\n *\n * chat({\n * systemPrompts: [myPrompt, systemPrompt],\n * tools: [tool, searchTool, emailTool],\n * messages,\n * })\n * ```\n */\nexport function createCodeModeTool(\n config: CodeModeToolConfig,\n): ServerTool<\n typeof executeTypescriptInputSchema,\n typeof executeTypescriptOutputSchema,\n 'execute_typescript'\n> {\n const {\n driver,\n tools,\n timeout = 30000,\n memoryLimit = 128,\n getSkillBindings,\n transpile = stripTypeScript,\n } = config\n\n // Validate tools\n if (tools.length === 0) {\n throw new Error('At least one tool must be provided to createCodeModeTool')\n }\n\n // Transform tools to bindings with external_ prefix (static bindings)\n const staticBindings = toolsToBindings(tools, 'external_')\n\n // Create the tool definition\n const definition = toolDefinition({\n name: 'execute_typescript' as const,\n description: buildToolDescription(tools),\n inputSchema: executeTypescriptInputSchema,\n outputSchema: executeTypescriptOutputSchema,\n })\n\n // Return server tool with execute function that accepts context\n return definition.server(\n async (\n input,\n toolContext?: ToolExecutionContext,\n ): Promise<CodeModeToolResult> => {\n const { typescriptCode } = input\n\n // Get emitCustomEvent from context or use no-op\n const emitCustomEvent = toolContext?.emitCustomEvent || (() => {})\n\n if (!typescriptCode || typeof typescriptCode !== 'string') {\n return {\n success: false,\n error: {\n message: 'typescriptCode must be a non-empty string',\n name: 'ValidationError',\n },\n }\n }\n\n // Create a fresh sandbox context for this execution\n let isolateContext: IsolateContext | null = null\n\n // Emit execution started event immediately\n emitCustomEvent('code_mode:execution_started', {\n timestamp: Date.now(),\n codeLength: typescriptCode.length,\n })\n\n try {\n // Step 1: Strip TypeScript (also serves as syntax validation via the\n // transpiler — sucrase by default, or a user-supplied `transpile`)\n let strippedCode: string\n try {\n strippedCode = await transpile(typescriptCode)\n } catch (error) {\n // Type/syntax error from the transpiler\n return {\n success: false,\n error: {\n message: error instanceof Error ? error.message : String(error),\n name: 'TypeScriptError',\n },\n }\n }\n\n // Step 2: Get dynamic skill bindings if available\n const skillBindings = getSkillBindings ? await getSkillBindings() : {}\n\n // Step 3: Merge static and dynamic bindings, then wrap with event awareness\n const allBindings = { ...staticBindings, ...skillBindings }\n const eventAwareBindings = createEventAwareBindings(\n allBindings,\n emitCustomEvent,\n )\n\n // Step 4: Create sandbox context with event-aware bindings\n isolateContext = await driver.createContext({\n bindings: eventAwareBindings,\n timeout,\n memoryLimit,\n })\n\n // Step 5: Execute the code in the sandbox\n const executionResult = await isolateContext.execute(strippedCode)\n\n // Emit console logs as custom events\n if (executionResult.logs && executionResult.logs.length > 0) {\n for (const log of executionResult.logs) {\n // Parse log level from prefix (added by sandbox console implementation)\n let level: 'log' | 'warn' | 'error' | 'info' = 'log'\n let message = log\n\n if (log.startsWith('ERROR: ')) {\n level = 'error'\n message = log.slice(7)\n } else if (log.startsWith('WARN: ')) {\n level = 'warn'\n message = log.slice(6)\n } else if (log.startsWith('INFO: ')) {\n level = 'info'\n message = log.slice(6)\n }\n\n emitCustomEvent('code_mode:console', {\n level,\n message,\n timestamp: Date.now(),\n })\n }\n }\n\n if (executionResult.success) {\n return {\n success: true,\n result: executionResult.value,\n logs: executionResult.logs,\n }\n } else {\n return {\n success: false,\n error: executionResult.error\n ? {\n message: executionResult.error.message,\n name: executionResult.error.name,\n }\n : { message: 'Unknown execution error' },\n logs: executionResult.logs,\n }\n }\n } catch (error) {\n return {\n success: false,\n error: {\n message: error instanceof Error ? error.message : String(error),\n name: error instanceof Error ? error.name : 'Error',\n },\n }\n } finally {\n // Always clean up the sandbox context\n if (isolateContext) {\n await isolateContext.dispose()\n }\n }\n },\n )\n}\n\n/**\n * Build the tool description including available external functions\n */\nfunction buildToolDescription(tools: Array<CodeModeTool>): string {\n const externalFunctions = tools.map((t) => `external_${t.name}`).join(', ')\n\n return (\n `Execute TypeScript code in a secure sandbox environment. ` +\n `The code can use these external API functions: ${externalFunctions}. ` +\n `All external_* calls are async and must be awaited. ` +\n `Return a value to pass results back. Use console.log() for debugging.`\n )\n}\n"],"names":[],"mappings":";;;;AAkBA,MAAM,+BAA+B,EAAE,OAAO;AAAA,EAC5C,gBAAgB,EACb,OAAA,EACA;AAAA,IACC;AAAA,EAAA;AAIN,CAAC;AAKD,MAAM,gCAAgC,EAAE,OAAO;AAAA,EAC7C,SAAS,EAAE,UAAU,SAAS,4CAA4C;AAAA,EAC1E,QAAQ,EACL,QAAA,EACA,SAAA,EACA,SAAS,qCAAqC;AAAA,EACjD,MAAM,EACH,MAAM,EAAE,OAAA,CAAQ,EAChB,SAAA,EACA,SAAS,0CAA0C;AAAA,EACtD,OAAO,EACJ,OAAO;AAAA,IACN,SAAS,EAAE,OAAA;AAAA,IACX,MAAM,EAAE,OAAA,EAAS,SAAA;AAAA,IACjB,MAAM,EAAE,OAAA,EAAS,SAAA;AAAA,EAAS,CAC3B,EACA,WACA,SAAS,mCAAmC;AACjD,CAAC;AAiCM,SAAS,mBACd,QAKA;AACA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,cAAc;AAAA,IACd;AAAA,IACA,YAAY;AAAA,EAAA,IACV;AAGJ,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AAGA,QAAM,iBAAiB,gBAAgB,OAAO,WAAW;AAGzD,QAAM,aAAa,eAAe;AAAA,IAChC,MAAM;AAAA,IACN,aAAa,qBAAqB,KAAK;AAAA,IACvC,aAAa;AAAA,IACb,cAAc;AAAA,EAAA,CACf;AAGD,SAAO,WAAW;AAAA,IAChB,OACE,OACA,gBACgC;AAChC,YAAM,EAAE,mBAAmB;AAG3B,YAAM,kBAAkB,aAAa,oBAAoB,MAAM;AAAA,MAAC;AAEhE,UAAI,CAAC,kBAAkB,OAAO,mBAAmB,UAAU;AACzD,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO;AAAA,YACL,SAAS;AAAA,YACT,MAAM;AAAA,UAAA;AAAA,QACR;AAAA,MAEJ;AAGA,UAAI,iBAAwC;AAG5C,sBAAgB,+BAA+B;AAAA,QAC7C,WAAW,KAAK,IAAA;AAAA,QAChB,YAAY,eAAe;AAAA,MAAA,CAC5B;AAED,UAAI;AAGF,YAAI;AACJ,YAAI;AACF,yBAAe,MAAM,UAAU,cAAc;AAAA,QAC/C,SAAS,OAAO;AAEd,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,OAAO;AAAA,cACL,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,cAC9D,MAAM;AAAA,YAAA;AAAA,UACR;AAAA,QAEJ;AAGA,cAAM,gBAAgB,mBAAmB,MAAM,iBAAA,IAAqB,CAAA;AAGpE,cAAM,cAAc,EAAE,GAAG,gBAAgB,GAAG,cAAA;AAC5C,cAAM,qBAAqB;AAAA,UACzB;AAAA,UACA;AAAA,QAAA;AAIF,yBAAiB,MAAM,OAAO,cAAc;AAAA,UAC1C,UAAU;AAAA,UACV;AAAA,UACA;AAAA,QAAA,CACD;AAGD,cAAM,kBAAkB,MAAM,eAAe,QAAQ,YAAY;AAGjE,YAAI,gBAAgB,QAAQ,gBAAgB,KAAK,SAAS,GAAG;AAC3D,qBAAW,OAAO,gBAAgB,MAAM;AAEtC,gBAAI,QAA2C;AAC/C,gBAAI,UAAU;AAEd,gBAAI,IAAI,WAAW,SAAS,GAAG;AAC7B,sBAAQ;AACR,wBAAU,IAAI,MAAM,CAAC;AAAA,YACvB,WAAW,IAAI,WAAW,QAAQ,GAAG;AACnC,sBAAQ;AACR,wBAAU,IAAI,MAAM,CAAC;AAAA,YACvB,WAAW,IAAI,WAAW,QAAQ,GAAG;AACnC,sBAAQ;AACR,wBAAU,IAAI,MAAM,CAAC;AAAA,YACvB;AAEA,4BAAgB,qBAAqB;AAAA,cACnC;AAAA,cACA;AAAA,cACA,WAAW,KAAK,IAAA;AAAA,YAAI,CACrB;AAAA,UACH;AAAA,QACF;AAEA,YAAI,gBAAgB,SAAS;AAC3B,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,QAAQ,gBAAgB;AAAA,YACxB,MAAM,gBAAgB;AAAA,UAAA;AAAA,QAE1B,OAAO;AACL,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,OAAO,gBAAgB,QACnB;AAAA,cACE,SAAS,gBAAgB,MAAM;AAAA,cAC/B,MAAM,gBAAgB,MAAM;AAAA,YAAA,IAE9B,EAAE,SAAS,0BAAA;AAAA,YACf,MAAM,gBAAgB;AAAA,UAAA;AAAA,QAE1B;AAAA,MACF,SAAS,OAAO;AACd,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO;AAAA,YACL,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,YAC9D,MAAM,iBAAiB,QAAQ,MAAM,OAAO;AAAA,UAAA;AAAA,QAC9C;AAAA,MAEJ,UAAA;AAEE,YAAI,gBAAgB;AAClB,gBAAM,eAAe,QAAA;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAAA,EAAA;AAEJ;AAKA,SAAS,qBAAqB,OAAoC;AAChE,QAAM,oBAAoB,MAAM,IAAI,CAAC,MAAM,YAAY,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI;AAE1E,SACE,2GACkD,iBAAiB;AAIvE;"}
@@ -1,41 +0,0 @@
1
- import { CodeModeToolConfig } from './types.js';
2
- /**
3
- * Create both the `execute_typescript` tool and its matching system prompt
4
- * from a single config object.
5
- *
6
- * This is the recommended way to set up Code Mode — it ensures the tool and
7
- * system prompt always stay in sync.
8
- *
9
- * @example
10
- * ```typescript
11
- * import { createCodeMode } from '@tanstack/ai-code-mode'
12
- * import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'
13
- *
14
- * const { tool, systemPrompt } = createCodeMode({
15
- * driver: createNodeIsolateDriver(),
16
- * tools: [weatherTool, dbTool],
17
- * timeout: 30000,
18
- * })
19
- *
20
- * chat({
21
- * systemPrompts: [myPrompt, systemPrompt],
22
- * tools: [tool, ...otherTools],
23
- * messages,
24
- * })
25
- * ```
26
- */
27
- export declare function createCodeMode(config: CodeModeToolConfig): {
28
- tool: import('@tanstack/ai').ServerTool<import('zod').ZodObject<{
29
- typescriptCode: import('zod').ZodString;
30
- }, import('zod/v4/core').$strip>, import('zod').ZodObject<{
31
- success: import('zod').ZodBoolean;
32
- result: import('zod').ZodOptional<import('zod').ZodUnknown>;
33
- logs: import('zod').ZodOptional<import('zod').ZodArray<import('zod').ZodString>>;
34
- error: import('zod').ZodOptional<import('zod').ZodObject<{
35
- message: import('zod').ZodString;
36
- name: import('zod').ZodOptional<import('zod').ZodString>;
37
- line: import('zod').ZodOptional<import('zod').ZodNumber>;
38
- }, import('zod/v4/core').$strip>>;
39
- }, import('zod/v4/core').$strip>, "execute_typescript", unknown>;
40
- systemPrompt: string;
41
- };
@@ -1,12 +0,0 @@
1
- import { createCodeModeTool } from "./create-code-mode-tool.js";
2
- import { createCodeModeSystemPrompt } from "./create-system-prompt.js";
3
- function createCodeMode(config) {
4
- return {
5
- tool: createCodeModeTool(config),
6
- systemPrompt: createCodeModeSystemPrompt(config)
7
- };
8
- }
9
- export {
10
- createCodeMode
11
- };
12
- //# sourceMappingURL=create-code-mode.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-code-mode.js","sources":["../../src/create-code-mode.ts"],"sourcesContent":["import { createCodeModeTool } from './create-code-mode-tool'\nimport { createCodeModeSystemPrompt } from './create-system-prompt'\nimport type { CodeModeToolConfig } from './types'\n\n/**\n * Create both the `execute_typescript` tool and its matching system prompt\n * from a single config object.\n *\n * This is the recommended way to set up Code Mode — it ensures the tool and\n * system prompt always stay in sync.\n *\n * @example\n * ```typescript\n * import { createCodeMode } from '@tanstack/ai-code-mode'\n * import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'\n *\n * const { tool, systemPrompt } = createCodeMode({\n * driver: createNodeIsolateDriver(),\n * tools: [weatherTool, dbTool],\n * timeout: 30000,\n * })\n *\n * chat({\n * systemPrompts: [myPrompt, systemPrompt],\n * tools: [tool, ...otherTools],\n * messages,\n * })\n * ```\n */\nexport function createCodeMode(config: CodeModeToolConfig) {\n return {\n tool: createCodeModeTool(config),\n systemPrompt: createCodeModeSystemPrompt(config),\n }\n}\n"],"names":[],"mappings":";;AA6BO,SAAS,eAAe,QAA4B;AACzD,SAAO;AAAA,IACL,MAAM,mBAAmB,MAAM;AAAA,IAC/B,cAAc,2BAA2B,MAAM;AAAA,EAAA;AAEnD;"}
@@ -1,24 +0,0 @@
1
- import { CodeModeToolConfig } from './types.js';
2
- /**
3
- * Create a system prompt snippet that documents the execute_typescript tool
4
- * and all available external_* functions.
5
- *
6
- * Add this to your system prompts array when using createCodeModeTool.
7
- *
8
- * @example
9
- * ```typescript
10
- * import { createCodeMode } from '@tanstack/ai-code-mode'
11
- * import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'
12
- *
13
- * const { tool, systemPrompt } = createCodeMode({
14
- * driver: createNodeIsolateDriver(),
15
- * tools: [weatherTool, dbTool],
16
- * })
17
- *
18
- * chat({
19
- * systemPrompts: ['You are a helpful assistant.', systemPrompt],
20
- * tools: [tool, ...otherTools],
21
- * })
22
- * ```
23
- */
24
- export declare function createCodeModeSystemPrompt(config: CodeModeToolConfig): string;
@@ -1,66 +0,0 @@
1
- import { toolsToBindings } from "./bindings/tool-to-binding.js";
2
- import { generateTypeStubs } from "./type-generator/json-schema-to-ts.js";
3
- function createCodeModeSystemPrompt(config) {
4
- const { tools } = config;
5
- const bindings = toolsToBindings(tools, "external_");
6
- const typeStubs = generateTypeStubs(bindings);
7
- const functionDocs = Object.entries(bindings).map(([name, binding]) => {
8
- const doc = `- \`${name}(input)\`: ${binding.description}`;
9
- return doc;
10
- }).join("\n");
11
- return `## Code Execution Tool
12
-
13
- You have access to \`execute_typescript\` which runs TypeScript code in a sandboxed environment.
14
-
15
- ### When to Use
16
-
17
- Use \`execute_typescript\` when you need to:
18
- - Process data with loops, conditionals, or complex logic
19
- - Make multiple API calls in parallel (Promise.all)
20
- - Transform, filter, or aggregate data
21
- - Perform calculations or data analysis
22
-
23
- For simple operations, prefer calling tools directly.
24
-
25
- ### Available External APIs
26
-
27
- Inside your TypeScript code, you can call these async functions:
28
-
29
- ${functionDocs}
30
-
31
- ### Type Definitions
32
-
33
- \`\`\`typescript
34
- ${typeStubs}
35
- \`\`\`
36
-
37
- ### Example
38
-
39
- \`\`\`typescript
40
- // Fetch weather for multiple cities in parallel
41
- const cities = ["Tokyo", "Paris", "NYC"];
42
- const results = await Promise.all(
43
- cities.map(city => external_fetchWeather({ location: city }))
44
- );
45
-
46
- // Find the warmest city
47
- const warmest = results.reduce((prev, curr) =>
48
- curr.temperature > prev.temperature ? curr : prev
49
- );
50
-
51
- return { warmestCity: warmest.location, temperature: warmest.temperature };
52
- \`\`\`
53
-
54
- ### Important Notes
55
-
56
- - All \`external_*\` calls are async - always use \`await\`
57
- - Return a value to pass results back to you
58
- - Use \`console.log()\` for debugging (logs are captured)
59
- - The sandbox is isolated - no network access or file system
60
- - Each execution is independent (no shared state between calls)
61
- `;
62
- }
63
- export {
64
- createCodeModeSystemPrompt
65
- };
66
- //# sourceMappingURL=create-system-prompt.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-system-prompt.js","sources":["../../src/create-system-prompt.ts"],"sourcesContent":["import { toolsToBindings } from './bindings/tool-to-binding'\nimport { generateTypeStubs } from './type-generator/json-schema-to-ts'\nimport type { CodeModeToolConfig } from './types'\n\n/**\n * Create a system prompt snippet that documents the execute_typescript tool\n * and all available external_* functions.\n *\n * Add this to your system prompts array when using createCodeModeTool.\n *\n * @example\n * ```typescript\n * import { createCodeMode } from '@tanstack/ai-code-mode'\n * import { createNodeIsolateDriver } from '@tanstack/ai-isolate-node'\n *\n * const { tool, systemPrompt } = createCodeMode({\n * driver: createNodeIsolateDriver(),\n * tools: [weatherTool, dbTool],\n * })\n *\n * chat({\n * systemPrompts: ['You are a helpful assistant.', systemPrompt],\n * tools: [tool, ...otherTools],\n * })\n * ```\n */\nexport function createCodeModeSystemPrompt(config: CodeModeToolConfig): string {\n const { tools } = config\n\n // Transform tools to bindings with external_ prefix to generate correct type stubs\n const bindings = toolsToBindings(tools, 'external_')\n\n // Generate TypeScript type stubs for the external functions\n const typeStubs = generateTypeStubs(bindings)\n\n // Build function documentation\n const functionDocs = Object.entries(bindings)\n .map(([name, binding]) => {\n const doc = `- \\`${name}(input)\\`: ${binding.description}`\n return doc\n })\n .join('\\n')\n\n return `## Code Execution Tool\n\nYou have access to \\`execute_typescript\\` which runs TypeScript code in a sandboxed environment.\n\n### When to Use\n\nUse \\`execute_typescript\\` when you need to:\n- Process data with loops, conditionals, or complex logic\n- Make multiple API calls in parallel (Promise.all)\n- Transform, filter, or aggregate data\n- Perform calculations or data analysis\n\nFor simple operations, prefer calling tools directly.\n\n### Available External APIs\n\nInside your TypeScript code, you can call these async functions:\n\n${functionDocs}\n\n### Type Definitions\n\n\\`\\`\\`typescript\n${typeStubs}\n\\`\\`\\`\n\n### Example\n\n\\`\\`\\`typescript\n// Fetch weather for multiple cities in parallel\nconst cities = [\"Tokyo\", \"Paris\", \"NYC\"];\nconst results = await Promise.all(\n cities.map(city => external_fetchWeather({ location: city }))\n);\n\n// Find the warmest city\nconst warmest = results.reduce((prev, curr) => \n curr.temperature > prev.temperature ? curr : prev\n);\n\nreturn { warmestCity: warmest.location, temperature: warmest.temperature };\n\\`\\`\\`\n\n### Important Notes\n\n- All \\`external_*\\` calls are async - always use \\`await\\`\n- Return a value to pass results back to you\n- Use \\`console.log()\\` for debugging (logs are captured)\n- The sandbox is isolated - no network access or file system\n- Each execution is independent (no shared state between calls)\n`\n}\n"],"names":[],"mappings":";;AA0BO,SAAS,2BAA2B,QAAoC;AAC7E,QAAM,EAAE,UAAU;AAGlB,QAAM,WAAW,gBAAgB,OAAO,WAAW;AAGnD,QAAM,YAAY,kBAAkB,QAAQ;AAG5C,QAAM,eAAe,OAAO,QAAQ,QAAQ,EACzC,IAAI,CAAC,CAAC,MAAM,OAAO,MAAM;AACxB,UAAM,MAAM,OAAO,IAAI,cAAc,QAAQ,WAAW;AACxD,WAAO;AAAA,EACT,CAAC,EACA,KAAK,IAAI;AAEZ,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBP,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA,EAKZ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BX;"}
@@ -1,10 +0,0 @@
1
- export { createCodeModeTool } from './create-code-mode-tool.js';
2
- export type { ExecuteTypescriptInput, ExecuteTypescriptOutput, } from './create-code-mode-tool.js';
3
- export { createCodeModeSystemPrompt } from './create-system-prompt.js';
4
- export { createCodeMode } from './create-code-mode.js';
5
- export { InMemoryAgentStore, generateAgentName, type AgentSession, type AgentStore, } from './agent-store.js';
6
- export { toolToBinding, toolsToBindings, createEventAwareBindings, } from './bindings/tool-to-binding.js';
7
- export { generateTypeStubs, jsonSchemaToTypeScript, type TypeGeneratorOptions, } from './type-generator/json-schema-to-ts.js';
8
- export { stripTypeScript } from './strip-typescript.js';
9
- export { wrapCode } from './code-wrapper.js';
10
- export type { CodeModeToolConfig, CodeModeToolResult, IsolateDriver, IsolateConfig, IsolateContext, ExecutionResult, NormalizedError, ToolBinding, CodeModeTool, ToolExecutionContext, } from './types.js';
package/dist/esm/index.js DELETED
@@ -1,23 +0,0 @@
1
- import { createCodeModeTool } from "./create-code-mode-tool.js";
2
- import { createCodeModeSystemPrompt } from "./create-system-prompt.js";
3
- import { createCodeMode } from "./create-code-mode.js";
4
- import { InMemoryAgentStore, generateAgentName } from "./agent-store.js";
5
- import { createEventAwareBindings, toolToBinding, toolsToBindings } from "./bindings/tool-to-binding.js";
6
- import { generateTypeStubs, jsonSchemaToTypeScript } from "./type-generator/json-schema-to-ts.js";
7
- import { stripTypeScript } from "./strip-typescript.js";
8
- import { wrapCode } from "./code-wrapper.js";
9
- export {
10
- InMemoryAgentStore,
11
- createCodeMode,
12
- createCodeModeSystemPrompt,
13
- createCodeModeTool,
14
- createEventAwareBindings,
15
- generateAgentName,
16
- generateTypeStubs,
17
- jsonSchemaToTypeScript,
18
- stripTypeScript,
19
- toolToBinding,
20
- toolsToBindings,
21
- wrapCode
22
- };
23
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -1,44 +0,0 @@
1
- /**
2
- * Strip TypeScript syntax from code, converting it to plain JavaScript.
3
- *
4
- * This is a safety net to ensure that even if an LLM generates TypeScript
5
- * code with type annotations, it will be converted to valid JavaScript
6
- * before being sent to the sandbox for execution.
7
- *
8
- * Uses sucrase's pure-JavaScript `transform`, which strips the TypeScript
9
- * syntax that LLM-generated snippets use in practice:
10
- * - Type annotations (: string, : number, etc.)
11
- * - Generic types (Array<T>, Record<K, V>, etc.)
12
- * - Interface and type declarations
13
- * - Type assertions
14
- * - Enums (converted to JavaScript objects)
15
- *
16
- * Unlike esbuild, sucrase has no native binary and pulls in no Node-only
17
- * built-ins on its `transform` path, so this module is safe to bundle for
18
- * browsers and edge runtimes (Cloudflare Workers/Pages etc.).
19
- *
20
- * Limitations vs esbuild: sucrase is a type-stripper, not a down-leveler.
21
- * `disableESTransforms` leaves modern ECMAScript syntax untouched (the sandbox
22
- * engines are modern), and sucrase does NOT compile a few exotic constructs:
23
- * - TypeScript value `namespace`/`module` blocks are DROPPED (not emitted as an
24
- * IIFE), so referencing the namespace at runtime throws `ReferenceError`.
25
- * - Decorators and the `accessor` keyword pass through un-lowered, so the
26
- * sandbox sees invalid syntax.
27
- * - Post-ES2022 syntax (`using` declarations, RegExp `/v`·`/d` flags) is passed
28
- * through; it runs on modern V8/Node sandboxes but may fail on older engines
29
- * (e.g. QuickJS).
30
- * If you need any of these, supply a heavier (Node-only) transpiler via the
31
- * `transpile` option on `createCodeModeTool`.
32
- *
33
- * The code is wrapped in an async function before transformation to allow
34
- * top-level `return` and `await` statements, then unwrapped after.
35
- *
36
- * Note on errors: sucrase reports syntax errors with a position relative to the
37
- * *wrapped* code (offset by the one-line wrapper prefix), so any line numbers
38
- * surfaced downstream (e.g. `CodeModeToolResult.error.line`) are approximate.
39
- *
40
- * @param code - TypeScript or JavaScript code
41
- * @returns Plain JavaScript code with all type syntax removed
42
- * @throws Error if sucrase fails (e.g., syntax error) or wrapper extraction fails
43
- */
44
- export declare function stripTypeScript(code: string): Promise<string>;
@@ -1,49 +0,0 @@
1
- import { transform } from "sucrase";
2
- const WRAPPER_START = "___TANSTACK_WRAPPER_START___";
3
- const WRAPPER_END = "___TANSTACK_WRAPPER_END___";
4
- async function stripTypeScript(code) {
5
- const wrappedCode = `async function ${WRAPPER_START}() {
6
- ${code}
7
- }; ${WRAPPER_END}`;
8
- const result = transform(wrappedCode, {
9
- // Only strip/lower TypeScript-specific syntax...
10
- transforms: ["typescript"],
11
- // ...and leave modern ECMAScript syntax untouched for the sandbox engines.
12
- disableESTransforms: true
13
- });
14
- const transformed = result.code;
15
- const functionStart = transformed.indexOf(`async function ${WRAPPER_START}()`);
16
- if (functionStart === -1) {
17
- throw new Error(
18
- "[stripTypeScript] Could not find wrapper function start in transformed output"
19
- );
20
- }
21
- const openBrace = transformed.indexOf("{", functionStart);
22
- if (openBrace === -1) {
23
- throw new Error(
24
- "[stripTypeScript] Could not find opening brace in transformed output"
25
- );
26
- }
27
- const endMarkerIndex = transformed.indexOf(WRAPPER_END);
28
- if (endMarkerIndex === -1) {
29
- throw new Error(
30
- "[stripTypeScript] Could not find end marker in transformed output"
31
- );
32
- }
33
- const codeBeforeEndMarker = transformed.substring(
34
- openBrace + 1,
35
- endMarkerIndex
36
- );
37
- const closingBraceIndex = codeBeforeEndMarker.lastIndexOf("}");
38
- if (closingBraceIndex === -1) {
39
- throw new Error(
40
- "[stripTypeScript] Could not find closing brace in transformed output"
41
- );
42
- }
43
- const functionBody = codeBeforeEndMarker.substring(0, closingBraceIndex).trim();
44
- return functionBody;
45
- }
46
- export {
47
- stripTypeScript
48
- };
49
- //# sourceMappingURL=strip-typescript.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"strip-typescript.js","sources":["../../src/strip-typescript.ts"],"sourcesContent":["import { transform } from 'sucrase'\n\n// Unique markers for wrapping/unwrapping code\nconst WRAPPER_START = '___TANSTACK_WRAPPER_START___'\nconst WRAPPER_END = '___TANSTACK_WRAPPER_END___'\n\n/**\n * Strip TypeScript syntax from code, converting it to plain JavaScript.\n *\n * This is a safety net to ensure that even if an LLM generates TypeScript\n * code with type annotations, it will be converted to valid JavaScript\n * before being sent to the sandbox for execution.\n *\n * Uses sucrase's pure-JavaScript `transform`, which strips the TypeScript\n * syntax that LLM-generated snippets use in practice:\n * - Type annotations (: string, : number, etc.)\n * - Generic types (Array<T>, Record<K, V>, etc.)\n * - Interface and type declarations\n * - Type assertions\n * - Enums (converted to JavaScript objects)\n *\n * Unlike esbuild, sucrase has no native binary and pulls in no Node-only\n * built-ins on its `transform` path, so this module is safe to bundle for\n * browsers and edge runtimes (Cloudflare Workers/Pages etc.).\n *\n * Limitations vs esbuild: sucrase is a type-stripper, not a down-leveler.\n * `disableESTransforms` leaves modern ECMAScript syntax untouched (the sandbox\n * engines are modern), and sucrase does NOT compile a few exotic constructs:\n * - TypeScript value `namespace`/`module` blocks are DROPPED (not emitted as an\n * IIFE), so referencing the namespace at runtime throws `ReferenceError`.\n * - Decorators and the `accessor` keyword pass through un-lowered, so the\n * sandbox sees invalid syntax.\n * - Post-ES2022 syntax (`using` declarations, RegExp `/v`·`/d` flags) is passed\n * through; it runs on modern V8/Node sandboxes but may fail on older engines\n * (e.g. QuickJS).\n * If you need any of these, supply a heavier (Node-only) transpiler via the\n * `transpile` option on `createCodeModeTool`.\n *\n * The code is wrapped in an async function before transformation to allow\n * top-level `return` and `await` statements, then unwrapped after.\n *\n * Note on errors: sucrase reports syntax errors with a position relative to the\n * *wrapped* code (offset by the one-line wrapper prefix), so any line numbers\n * surfaced downstream (e.g. `CodeModeToolResult.error.line`) are approximate.\n *\n * @param code - TypeScript or JavaScript code\n * @returns Plain JavaScript code with all type syntax removed\n * @throws Error if sucrase fails (e.g., syntax error) or wrapper extraction fails\n */\n// sucrase's transform is synchronous, but we keep the published Promise-returning\n// signature so existing `await stripTypeScript(...)` callers (and a custom async\n// `transpile` hook) stay source-compatible across this swap.\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function stripTypeScript(code: string): Promise<string> {\n // Wrap the code in an async function to allow top-level return/await.\n // This is necessary because top-level `return` is invalid outside a function.\n const wrappedCode = `async function ${WRAPPER_START}() {\\n${code}\\n}; ${WRAPPER_END}`\n\n const result = transform(wrappedCode, {\n // Only strip/lower TypeScript-specific syntax...\n transforms: ['typescript'],\n // ...and leave modern ECMAScript syntax untouched for the sandbox engines.\n disableESTransforms: true,\n })\n\n // Extract the code from inside the wrapper function\n const transformed = result.code\n\n // Find the function declaration start\n const functionStart = transformed.indexOf(`async function ${WRAPPER_START}()`)\n if (functionStart === -1) {\n throw new Error(\n '[stripTypeScript] Could not find wrapper function start in transformed output',\n )\n }\n\n // Find the opening brace of the function\n const openBrace = transformed.indexOf('{', functionStart)\n if (openBrace === -1) {\n throw new Error(\n '[stripTypeScript] Could not find opening brace in transformed output',\n )\n }\n\n // Find the end marker (regardless of formatting)\n const endMarkerIndex = transformed.indexOf(WRAPPER_END)\n if (endMarkerIndex === -1) {\n throw new Error(\n '[stripTypeScript] Could not find end marker in transformed output',\n )\n }\n\n // Find the closing brace of the function (last } before the end marker)\n // We need to find the } that matches the function opening\n const codeBeforeEndMarker = transformed.substring(\n openBrace + 1,\n endMarkerIndex,\n )\n\n // Find the last } before the end marker, accounting for the semicolon\n // The code will be: ...function body...}; WRAPPER_END or ...};\\nWRAPPER_END\n const closingBraceIndex = codeBeforeEndMarker.lastIndexOf('}')\n\n if (closingBraceIndex === -1) {\n throw new Error(\n '[stripTypeScript] Could not find closing brace in transformed output',\n )\n }\n\n // Extract the function body (between { and })\n const functionBody = codeBeforeEndMarker\n .substring(0, closingBraceIndex)\n .trim()\n\n return functionBody\n}\n"],"names":[],"mappings":";AAGA,MAAM,gBAAgB;AACtB,MAAM,cAAc;AAiDpB,eAAsB,gBAAgB,MAA+B;AAGnE,QAAM,cAAc,kBAAkB,aAAa;AAAA,EAAS,IAAI;AAAA,KAAQ,WAAW;AAEnF,QAAM,SAAS,UAAU,aAAa;AAAA;AAAA,IAEpC,YAAY,CAAC,YAAY;AAAA;AAAA,IAEzB,qBAAqB;AAAA,EAAA,CACtB;AAGD,QAAM,cAAc,OAAO;AAG3B,QAAM,gBAAgB,YAAY,QAAQ,kBAAkB,aAAa,IAAI;AAC7E,MAAI,kBAAkB,IAAI;AACxB,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAGA,QAAM,YAAY,YAAY,QAAQ,KAAK,aAAa;AACxD,MAAI,cAAc,IAAI;AACpB,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAGA,QAAM,iBAAiB,YAAY,QAAQ,WAAW;AACtD,MAAI,mBAAmB,IAAI;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAIA,QAAM,sBAAsB,YAAY;AAAA,IACtC,YAAY;AAAA,IACZ;AAAA,EAAA;AAKF,QAAM,oBAAoB,oBAAoB,YAAY,GAAG;AAE7D,MAAI,sBAAsB,IAAI;AAC5B,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAGA,QAAM,eAAe,oBAClB,UAAU,GAAG,iBAAiB,EAC9B,KAAA;AAEH,SAAO;AACT;"}
@@ -1,31 +0,0 @@
1
- import { ToolBinding } from '../types.js';
2
- /**
3
- * Options for type stub generation
4
- */
5
- export interface TypeGeneratorOptions {
6
- /**
7
- * Include JSDoc comments with descriptions
8
- * @default true
9
- */
10
- includeDescriptions?: boolean;
11
- }
12
- /**
13
- * Generate TypeScript type stubs for all tool bindings
14
- *
15
- * These stubs are included in the LLM system prompt so it knows
16
- * the exact type signatures of available tools.
17
- *
18
- * Tool names match the actual function names injected into the sandbox.
19
- */
20
- export declare function generateTypeStubs(bindings: Record<string, ToolBinding>, options?: TypeGeneratorOptions): string;
21
- interface TypeResult {
22
- name: string;
23
- declaration: string;
24
- }
25
- /**
26
- * Convert a JSON Schema to a TypeScript type
27
- *
28
- * Supports basic types: string, number, boolean, object, array
29
- */
30
- export declare function jsonSchemaToTypeScript(schema: Record<string, unknown>, typeName: string): TypeResult;
31
- export {};
@@ -1,100 +0,0 @@
1
- function generateTypeStubs(bindings, options = {}) {
2
- const { includeDescriptions = true } = options;
3
- const declarations = [];
4
- for (const [name, binding] of Object.entries(bindings)) {
5
- const inputTypeName = `${capitalize(name)}Input`;
6
- const outputTypeName = `${capitalize(name)}Output`;
7
- const inputType = jsonSchemaToTypeScript(binding.inputSchema, inputTypeName);
8
- if (inputType.declaration) {
9
- declarations.push(inputType.declaration);
10
- }
11
- let outputTypeRef = "unknown";
12
- if (binding.outputSchema) {
13
- const outputType = jsonSchemaToTypeScript(
14
- binding.outputSchema,
15
- outputTypeName
16
- );
17
- if (outputType.declaration) {
18
- declarations.push(outputType.declaration);
19
- }
20
- outputTypeRef = outputType.name;
21
- }
22
- const description = includeDescriptions && binding.description ? `/** ${binding.description} */
23
- ` : "";
24
- declarations.push(
25
- `${description}declare function ${name}(input: ${inputType.name}): Promise<${outputTypeRef}>;`
26
- );
27
- }
28
- return declarations.join("\n\n");
29
- }
30
- function jsonSchemaToTypeScript(schema, typeName) {
31
- const type = schemaToType(schema);
32
- if (schema.type === "object" && schema.properties && Object.keys(schema.properties).length > 0) {
33
- return {
34
- name: typeName,
35
- declaration: `interface ${typeName} ${type}`
36
- };
37
- }
38
- return {
39
- name: type,
40
- declaration: ""
41
- };
42
- }
43
- function schemaToType(schema) {
44
- if (typeof schema !== "object") {
45
- return "unknown";
46
- }
47
- const schemaType = schema.type;
48
- if (schemaType === "string") return "string";
49
- if (schemaType === "number" || schemaType === "integer") return "number";
50
- if (schemaType === "boolean") return "boolean";
51
- if (schemaType === "null") return "null";
52
- if (schemaType === "array") {
53
- const items = schema.items;
54
- const itemType = items ? schemaToType(items) : "unknown";
55
- return `Array<${itemType}>`;
56
- }
57
- if (schemaType === "object" && schema.properties) {
58
- const properties = schema.properties;
59
- const required = new Set(
60
- schema.required ?? []
61
- );
62
- const props = Object.entries(properties).map(([key, propSchema]) => {
63
- const optional = required.has(key) ? "" : "?";
64
- const propType = schemaToType(propSchema);
65
- const safeName = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `"${key}"`;
66
- return ` ${safeName}${optional}: ${propType};`;
67
- }).join("\n");
68
- return `{
69
- ${props}
70
- }`;
71
- }
72
- if (schema.enum) {
73
- const enumValues = schema.enum;
74
- return enumValues.map((v) => JSON.stringify(v)).join(" | ");
75
- }
76
- if (schema.anyOf || schema.oneOf) {
77
- const variants = schema.anyOf || schema.oneOf;
78
- return variants.map((v) => schemaToType(v)).join(" | ");
79
- }
80
- if (Array.isArray(schemaType)) {
81
- return schemaType.map((t) => {
82
- if (t === "string") return "string";
83
- if (t === "number" || t === "integer") return "number";
84
- if (t === "boolean") return "boolean";
85
- if (t === "null") return "null";
86
- if (t === "array") return "Array<unknown>";
87
- if (t === "object") return "object";
88
- return "unknown";
89
- }).join(" | ");
90
- }
91
- return "unknown";
92
- }
93
- function capitalize(str) {
94
- return str.charAt(0).toUpperCase() + str.slice(1);
95
- }
96
- export {
97
- generateTypeStubs,
98
- jsonSchemaToTypeScript
99
- };
100
- //# sourceMappingURL=json-schema-to-ts.js.map