@assistant-ui/x-generative-compiler 0.0.6 → 0.0.8
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/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +41 -11
- package/dist/compile.js.map +1 -1
- package/dist/package.js +1 -1
- package/package.json +2 -2
- package/src/compile.test.ts +87 -5
- package/src/compile.ts +83 -17
package/dist/compile.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.d.ts","names":[],"sources":["../src/compile.ts"],"mappings":";;;KAoBY,QAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"compile.d.ts","names":[],"sources":["../src/compile.ts"],"mappings":";;;KAoBY,QAAA;AAAA,UA2CK,cAAA;EA3CL;EA6CV,MAAA,EAAQ,MAAM;;EAEd,QAAA;EA/CkB;EAiDlB,UAAA;EAN6B;;;;;;;;EAe7B,gBAAA;AAAA;AAAA,UAGe,aAAA;EACf,IAAA;EACA,GAAG;AAAA;AAAA;AAAA,cAIQ,sBAAA,SAA+B,KAAK;cACnC,OAAA,UAAiB,QAAA;AAAA;;iBASf,kBAAA,CAAmB,IAAY;;;;;iBA+I/B,iBAAA,CACd,IAAA,UACA,OAAA,EAAS,cAAA,GACR,aAAa"}
|
package/dist/compile.js
CHANGED
|
@@ -28,6 +28,8 @@ const DISTRIBUTION_PACKAGES = [
|
|
|
28
28
|
"@assistant-ui/react-native",
|
|
29
29
|
"@assistant-ui/react-ink"
|
|
30
30
|
];
|
|
31
|
+
/** Package that exports the generative UI runtime split by export condition. */
|
|
32
|
+
const GENERATIVE_UI_PACKAGE = "@assistant-ui/react-generative-ui";
|
|
31
33
|
/**
|
|
32
34
|
* The class whose instances expose split-by-condition tools (`present()`,
|
|
33
35
|
* `promptUser()`). A toolkit entry that calls a method on one of these passes
|
|
@@ -324,15 +326,25 @@ function unwrapToCall(node, name) {
|
|
|
324
326
|
*/
|
|
325
327
|
function collectGenerativeInstances(ast) {
|
|
326
328
|
const names = /* @__PURE__ */ new Set();
|
|
329
|
+
const generativeFactories = collectGenerativeFactoryImports(ast);
|
|
327
330
|
for (const statement of ast.program.body) {
|
|
328
|
-
|
|
329
|
-
|
|
331
|
+
const variableDeclaration = t.isVariableDeclaration(statement) ? statement : t.isExportNamedDeclaration(statement) && t.isVariableDeclaration(statement.declaration) ? statement.declaration : null;
|
|
332
|
+
if (!variableDeclaration) continue;
|
|
333
|
+
for (const declaration of variableDeclaration.declarations) {
|
|
330
334
|
const { id, init } = declaration;
|
|
331
|
-
if (t.isIdentifier(id) && t.isNewExpression(init) && t.isIdentifier(init.callee
|
|
335
|
+
if (t.isIdentifier(id) && t.isNewExpression(init) && t.isIdentifier(init.callee) && generativeFactories.has(init.callee.name)) names.add(id.name);
|
|
332
336
|
}
|
|
333
337
|
}
|
|
334
338
|
return names;
|
|
335
339
|
}
|
|
340
|
+
function collectGenerativeFactoryImports(ast) {
|
|
341
|
+
const names = /* @__PURE__ */ new Set();
|
|
342
|
+
for (const statement of ast.program.body) {
|
|
343
|
+
if (!t.isImportDeclaration(statement) || statement.source.value !== GENERATIVE_UI_PACKAGE) continue;
|
|
344
|
+
for (const specifier of statement.specifiers) if (t.isImportSpecifier(specifier) && t.isIdentifier(specifier.imported, { name: GENERATIVE_FACTORY })) names.add(specifier.local.name);
|
|
345
|
+
}
|
|
346
|
+
return names;
|
|
347
|
+
}
|
|
336
348
|
/**
|
|
337
349
|
* Collects the local names `unstable_interactableTool` is imported under from a
|
|
338
350
|
* distribution package, so toolkit entries calling it can be recognized
|
|
@@ -664,6 +676,16 @@ function isSafeToolkitSpread(entry, toolkitSpreadNames) {
|
|
|
664
676
|
const directMcpToolkit = unwrapToCall(entry.argument, MCP_TOOLKIT_WRAPPER);
|
|
665
677
|
return !!directMcpToolkit && t.isObjectExpression(directMcpToolkit.arguments[0]);
|
|
666
678
|
}
|
|
679
|
+
function genericUnsafeToolkitEntryMessage() {
|
|
680
|
+
return "each tool must be an inline object literal (`name: { ... }`) or a compiler-visible toolkit spread / generative tool (e.g. `...defineMcpToolkit(...)`, `...baseToolkit`, `generative.present()`, or `unstable_interactableTool(...)`) so its `execute` can be routed";
|
|
681
|
+
}
|
|
682
|
+
function describeUnsafeToolkitEntry(entry) {
|
|
683
|
+
if (!t.isObjectProperty(entry)) return genericUnsafeToolkitEntryMessage();
|
|
684
|
+
const toolName = memberName(entry.key, entry.computed);
|
|
685
|
+
const raw = entryRawValue(entry);
|
|
686
|
+
if (!toolName || !raw) return genericUnsafeToolkitEntryMessage();
|
|
687
|
+
return `tool "${toolName}" cannot be \`${generate(raw).code}\`; use an inline object literal (\`${toolName}: { ... }\`) or a compiler-visible toolkit spread / generative tool so its \`execute\` can be routed`;
|
|
688
|
+
}
|
|
667
689
|
/** The `JSONGenerativeUI` methods that produce a split-by-condition tool. */
|
|
668
690
|
const GENERATIVE_TOOL_METHODS = /* @__PURE__ */ new Set(["present", "promptUser"]);
|
|
669
691
|
/**
|
|
@@ -718,19 +740,20 @@ function compileToolkit(object, target, instances, interactableToolImports, tool
|
|
|
718
740
|
nextProperties.push(entry);
|
|
719
741
|
continue;
|
|
720
742
|
}
|
|
721
|
-
throw new GenerativeCompileError(
|
|
743
|
+
throw new GenerativeCompileError(describeUnsafeToolkitEntry(entry), filename);
|
|
722
744
|
}
|
|
745
|
+
const toolName = t.isObjectProperty(entry) ? memberName(entry.key, entry.computed) : void 0;
|
|
723
746
|
const execute = findMember(value, "execute");
|
|
724
747
|
const isStub = execute ? executeIsStubTool(execute) : false;
|
|
725
748
|
const isExternal = execute ? executeIsExternalTool(execute) : false;
|
|
726
|
-
const type = inferToolType(value, filename);
|
|
749
|
+
const type = inferToolType(value, toolName, filename);
|
|
727
750
|
const hasRender = !!findMember(value, "render");
|
|
728
751
|
const hasRenderText = !!findMember(value, "renderText");
|
|
729
|
-
if (type === "frontend" && !hasRender && !hasRenderText) throw new GenerativeCompileError("
|
|
730
|
-
if (type === "human" && !hasRender) throw new GenerativeCompileError("
|
|
731
|
-
if (type === "provider" && execute) applyProviderToolConfig(value, execute,
|
|
752
|
+
if (type === "frontend" && !hasRender && !hasRenderText) throw new GenerativeCompileError(`${typedToolSubject("frontend", toolName)} must declare a \`render\` or \`renderText\` (it has no server execute to show otherwise)`, filename);
|
|
753
|
+
if (type === "human" && !hasRender) throw new GenerativeCompileError(`${typedToolSubject("human", toolName)} must declare a \`render\` so it can collect input`, filename);
|
|
754
|
+
if (type === "provider" && execute) applyProviderToolConfig(value, execute, toolName, filename);
|
|
732
755
|
if (isExternal) {
|
|
733
|
-
if (!hasRender && !hasRenderText) throw new GenerativeCompileError("
|
|
756
|
+
if (!hasRender && !hasRenderText) throw new GenerativeCompileError(`${typedToolSubject("external", toolName)} must declare a \`render\` or \`renderText\` (assistant-ui only renders calls for tools defined elsewhere)`, filename);
|
|
734
757
|
if (target === "server") continue;
|
|
735
758
|
stripExternalToolMetadata(value);
|
|
736
759
|
}
|
|
@@ -826,15 +849,22 @@ function stripUseClient(member) {
|
|
|
826
849
|
* The loader writes the result back as a `type` field (see {@link setToolType})
|
|
827
850
|
* so the runtime keeps it.
|
|
828
851
|
*/
|
|
829
|
-
function inferToolType(object, filename) {
|
|
852
|
+
function inferToolType(object, toolName, filename) {
|
|
830
853
|
const execute = findMember(object, "execute");
|
|
831
|
-
if (!execute) throw new GenerativeCompileError(
|
|
854
|
+
if (!execute) throw new GenerativeCompileError(`${toolSubject(toolName)} must declare an \`execute\`; use \`humanTool()\` for a human-in-the-loop tool`, filename);
|
|
832
855
|
if (executeIsHumanTool(execute)) return "human";
|
|
833
856
|
if (executeIsProviderTool(execute)) return "provider";
|
|
834
857
|
if (executeIsStubTool(execute)) return "frontend";
|
|
835
858
|
if (executeIsExternalTool(execute)) return "backend";
|
|
836
859
|
return executeIsClient(execute) ? "frontend" : "backend";
|
|
837
860
|
}
|
|
861
|
+
function toolSubject(toolName) {
|
|
862
|
+
return toolName ? `tool "${toolName}"` : "every tool";
|
|
863
|
+
}
|
|
864
|
+
function typedToolSubject(type, toolName) {
|
|
865
|
+
if (toolName) return `${type} tool "${toolName}"`;
|
|
866
|
+
return `${/^[aeiou]/i.test(type) ? "an" : "a"} ${type} tool`;
|
|
867
|
+
}
|
|
838
868
|
function stripExternalToolMetadata(object) {
|
|
839
869
|
removeMember(object, "description");
|
|
840
870
|
removeMember(object, "parameters");
|
package/dist/compile.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.js","names":["pkgJson.version"],"sources":["../src/compile.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport * as nodePath from \"node:path\";\nimport { parse } from \"@babel/parser\";\nimport _traverse, { type NodePath } from \"@babel/traverse\";\nimport _generate from \"@babel/generator\";\nimport * as t from \"@babel/types\";\nimport { satisfies } from \"semver\";\nimport { DIRECTIVE, type Target } from \"./constants\";\nimport pkgJson from \"../package.json\" with { type: \"json\" };\n\n// @babel/traverse and @babel/generator are CJS; their default export is the\n// function itself under some interop and `{ default }` under others.\nconst traverse = (\n typeof _traverse === \"function\" ? _traverse : (_traverse as any).default\n) as typeof _traverse;\nconst generate = (\n typeof _generate === \"function\" ? _generate : (_generate as any).default\n) as typeof _generate;\n\nexport type ToolType = \"frontend\" | \"backend\" | \"human\" | \"provider\";\n\n/** The required wrapper around a toolkit's tools (stripped at build time). */\nconst TOOLKIT_WRAPPER = \"defineToolkit\";\n/** The helper that produces MCP-only toolkit fragments. */\nconst MCP_TOOLKIT_WRAPPER = \"defineMcpToolkit\";\n/** The required wrapper around a generative-UI library (stripped at build time). */\nconst COMPONENTS_WRAPPER = \"defineGenerativeComponents\";\n/** The core package whose metadata declares supported compiler versions. */\nconst CORE_PACKAGE = \"@assistant-ui/core\";\n/** This package, checked against core's compatibility range. */\nconst COMPILER_PACKAGE = \"@assistant-ui/x-generative-compiler\";\n/** Packages that re-export core's generative markers. */\nconst DISTRIBUTION_PACKAGES = [\n CORE_PACKAGE,\n \"@assistant-ui/react\",\n \"@assistant-ui/react-native\",\n \"@assistant-ui/react-ink\",\n] as const;\n/**\n * The class whose instances expose split-by-condition tools (`present()`,\n * `promptUser()`). A toolkit entry that calls a method on one of these passes\n * through untouched — the library, not this compiler, routes its halves.\n */\nconst GENERATIVE_FACTORY = \"JSONGenerativeUI\";\n/**\n * The factory producing an interactable's complete tool entry. Unlike\n * `JSONGenerativeUI`, its package has no per-target builds, so this compiler\n * splits the inline config: the client keeps `render`, the server drops it.\n * The factory's own `execute` is internal and client-safe (frontend tool).\n */\nconst INTERACTABLE_TOOL_FACTORY = \"unstable_interactableTool\";\n\n/** Mutable per-build outcomes the toolkit pass reports back for directive/guard injection. */\ninterface TargetFlags {\n /** A `render` survived on a client build (→ emit `\"use client\"`). */\n keptRender: boolean;\n /** A backend `execute` survived on a server build (→ emit `import \"server-only\"`). */\n keptBackendExecute: boolean;\n}\n\nexport interface CompileOptions {\n /** Which build target to emit. */\n target: Target;\n /** Source filename, used for error messages and source maps. */\n filename?: string;\n /** Emit a source map alongside the code. */\n sourceMaps?: boolean;\n /**\n * Whether the `server` target prepends `import \"server-only\"` when it keeps a\n * backend `execute`. Defaults to `true` (the Next.js/RSC convention, where the\n * guard fires via the `react-server` condition). Set `false` for bundlers\n * without a `react-server` layer (e.g. a Vite/TanStack Start `ssr` build),\n * where the split is already structural and importing `server-only` would\n * throw — see the Vite integration.\n */\n injectServerOnly?: boolean;\n}\n\nexport interface CompileResult {\n code: string;\n map?: object | null;\n}\n\n/** Thrown when a `\"use generative\"` file violates an authoring constraint. */\nexport class GenerativeCompileError extends Error {\n constructor(message: string, filename?: string) {\n super(\n `[assistant-ui/use-generative]${filename ? ` ${filename}:` : \"\"} ${message}`,\n );\n this.name = \"GenerativeCompileError\";\n }\n}\n\n/** Whether a source string opts into generative compilation via the directive. */\nexport function isGenerativeModule(code: string): boolean {\n // The directive must be a leading statement, preceded only by an optional BOM,\n // whitespace, and line/block comments. Scanned linearly — a regex over the\n // comment prefix is prone to catastrophic backtracking on crafted input.\n let i = code.charCodeAt(0) === 0xfeff ? 1 : 0;\n for (;;) {\n while (i < code.length && /\\s/.test(code[i]!)) i++;\n if (code.startsWith(\"//\", i)) {\n const nl = code.indexOf(\"\\n\", i);\n if (nl === -1) return false;\n i = nl + 1;\n } else if (code.startsWith(\"/*\", i)) {\n const end = code.indexOf(\"*/\", i + 2);\n if (end === -1) return false;\n i = end + 2;\n } else {\n break;\n }\n }\n\n const quote = code[i];\n if (quote !== '\"' && quote !== \"'\") return false;\n\n const directiveStart = i + 1;\n if (!code.startsWith(DIRECTIVE, directiveStart)) return false;\n\n const directiveEnd = directiveStart + DIRECTIVE.length;\n if (code[directiveEnd] !== quote) return false;\n\n return hasDirectiveTerminator(code, directiveEnd + 1);\n}\n\nfunction hasDirectiveTerminator(code: string, start: number): boolean {\n let i = start;\n let sawLineTerminator = false;\n for (;;) {\n if (i >= code.length) return true;\n\n const char = code.charCodeAt(i);\n if (isSemicolon(char)) return true;\n if (isLineTerminator(char)) {\n sawLineTerminator = true;\n i++;\n continue;\n }\n\n if (code.startsWith(\"//\", i)) {\n const lineEnd = nextLineTerminatorIndex(code, i + 2);\n if (lineEnd === -1) return true;\n sawLineTerminator = true;\n i = lineEnd + 1;\n continue;\n }\n\n if (code.startsWith(\"/*\", i)) {\n const end = code.indexOf(\"*/\", i + 2);\n if (end === -1) return false;\n sawLineTerminator ||= containsLineTerminator(code, i + 2, end);\n i = end + 2;\n continue;\n }\n\n if (/\\s/.test(code[i]!)) {\n i++;\n continue;\n }\n\n return sawLineTerminator && !startsExpressionContinuation(code, i);\n }\n}\n\nfunction nextLineTerminatorIndex(code: string, start: number): number {\n for (let i = start; i < code.length; i++) {\n if (isLineTerminator(code.charCodeAt(i))) return i;\n }\n return -1;\n}\n\nfunction containsLineTerminator(\n code: string,\n start: number,\n end: number,\n): boolean {\n for (let i = start; i < end; i++) {\n if (isLineTerminator(code.charCodeAt(i))) return true;\n }\n return false;\n}\n\nfunction startsExpressionContinuation(code: string, start: number): boolean {\n switch (code[start]) {\n case \".\":\n case \"+\":\n case \"-\":\n case \"*\":\n case \"/\":\n case \"%\":\n case \"<\":\n case \">\":\n case \"=\":\n case \"!\":\n case \"&\":\n case \"|\":\n case \"^\":\n case \"?\":\n case \":\":\n case \",\":\n case \"[\":\n case \"(\":\n case \"`\":\n return true;\n }\n\n return (\n startsKeywordContinuation(code, start, \"as\") ||\n startsKeywordContinuation(code, start, \"in\") ||\n startsKeywordContinuation(code, start, \"instanceof\") ||\n startsKeywordContinuation(code, start, \"satisfies\")\n );\n}\n\nfunction startsKeywordContinuation(\n code: string,\n start: number,\n keyword: string,\n): boolean {\n if (!code.startsWith(keyword, start)) return false;\n const next = code[start + keyword.length];\n return next === undefined || !/[\\p{ID_Continue}$]/u.test(next);\n}\n\nfunction isSemicolon(char: number): boolean {\n return char === 59;\n}\n\nfunction isLineTerminator(char: number): boolean {\n return char === 10 || char === 13 || char === 0x2028 || char === 0x2029;\n}\n\n/**\n * Rewrites a `\"use generative\"` module for a single build target, keeping only the\n * regions that target needs and pruning the imports the dropped regions used.\n */\nexport function compileGenerative(\n code: string,\n options: CompileOptions,\n): CompileResult {\n const { target, filename } = options;\n\n const ast = parse(code, {\n sourceType: \"module\",\n plugins: [\"typescript\", \"jsx\", \"explicitResourceManagement\"],\n });\n\n if (!ast.program.directives.some((d) => d.value.value === DIRECTIVE)) {\n throw new GenerativeCompileError(\n `missing \"${DIRECTIVE}\" directive`,\n filename,\n );\n }\n\n ensureCompilerCompatibleWithCore(ast, filename);\n\n // A module may hold several `defineToolkit(...)` / `defineGenerativeComponents(...)`\n // calls anywhere (e.g. a library built inside `new JSONGenerativeUI(...)` plus\n // the toolkit that exposes it). Tools may reference a `JSONGenerativeUI`\n // instance's `present()`/`promptUser()`, which the library — not this compiler —\n // splits across builds via export conditions; collect those instance names so\n // such entries pass through.\n ensureDefaultExport(ast, filename);\n const generativeInstances = collectGenerativeInstances(ast);\n const interactableToolImports = collectInteractableToolImports(ast);\n const toolkitSpreadNames = collectToolkitSpreadNames(\n ast,\n filename,\n createToolkitNameContext(),\n );\n\n const flags: TargetFlags = { keptRender: false, keptBackendExecute: false };\n\n traverse(ast, {\n CallExpression(path: NodePath<t.CallExpression>) {\n const callee = path.node.callee;\n const object = t.isObjectExpression(path.node.arguments[0])\n ? path.node.arguments[0]\n : null;\n\n if (t.isIdentifier(callee, { name: COMPONENTS_WRAPPER })) {\n if (!object) {\n throw new GenerativeCompileError(\n `${COMPONENTS_WRAPPER}() takes an inline object literal of components`,\n filename,\n );\n }\n compileComponents(object, target, flags, filename);\n // Unwrap the authoring helper to the bare library object so its import\n // can be pruned.\n path.replaceWith(object);\n path.skip();\n return;\n }\n\n if (t.isIdentifier(callee, { name: TOOLKIT_WRAPPER })) {\n if (!object) {\n throw new GenerativeCompileError(\n `${TOOLKIT_WRAPPER}() takes an inline object literal of tools`,\n filename,\n );\n }\n compileToolkit(\n object,\n target,\n generativeInstances,\n interactableToolImports,\n toolkitSpreadNames,\n flags,\n filename,\n );\n path.replaceWith(object);\n path.skip();\n }\n },\n });\n\n const { keptRender, keptBackendExecute } = flags;\n\n pruneUnused(ast);\n\n // Replace the module directives with the target-appropriate one.\n ast.program.directives = ast.program.directives.filter(\n (d) => d.value.value !== DIRECTIVE && d.value.value !== \"use client\",\n );\n if (target === \"client\" && keptRender) {\n ast.program.directives.unshift(\n t.directive(t.directiveLiteral(\"use client\")),\n );\n }\n if (\n target === \"server\" &&\n keptBackendExecute &&\n (options.injectServerOnly ?? true)\n ) {\n ast.program.body.unshift(\n t.importDeclaration([], t.stringLiteral(\"server-only\")),\n );\n }\n\n const result = generate(\n ast,\n {\n sourceMaps: options.sourceMaps ?? false,\n filename,\n jsescOption: { minimal: true },\n },\n code,\n );\n\n return { code: result.code, map: result.map };\n}\n\ninterface PackageJson {\n name?: string;\n version?: string;\n optionalDevDependencies?: Record<string, string>;\n}\n\nconst checkedCorePackageJsonPaths = new Set<string>();\n\n// This compiler's own version, inlined from package.json at build time. Read via\n// an import (not by walking the filesystem at runtime) so the literal survives\n// being bundled into a host package like `@assistant-ui/metro`, where no\n// standalone `@assistant-ui/x-generative-compiler` sits on disk to walk up to.\nconst COMPILER_VERSION = pkgJson.version;\n\nfunction ensureCompilerCompatibleWithCore(\n ast: t.File,\n filename: string | undefined,\n): void {\n const corePackageJsonPath = resolveCorePackageJson(ast, filename);\n if (\n !corePackageJsonPath ||\n checkedCorePackageJsonPaths.has(corePackageJsonPath)\n ) {\n return;\n }\n\n const corePackageJson = readPackageJson(corePackageJsonPath);\n const range = corePackageJson?.optionalDevDependencies?.[COMPILER_PACKAGE];\n if (!range) {\n checkedCorePackageJsonPaths.add(corePackageJsonPath);\n return;\n }\n\n let compatible = false;\n try {\n compatible = satisfies(COMPILER_VERSION, range, {\n includePrerelease: true,\n });\n } catch {\n throw new GenerativeCompileError(\n `${CORE_PACKAGE}@${corePackageJson.version ?? \"unknown\"} declares an ` +\n `invalid optionalDevDependencies range for ${COMPILER_PACKAGE}: ` +\n JSON.stringify(range),\n filename,\n );\n }\n\n if (!compatible) {\n throw new GenerativeCompileError(\n `${CORE_PACKAGE}@${corePackageJson.version ?? \"unknown\"} requires ` +\n `${COMPILER_PACKAGE} ${range}, but the current compiler is ` +\n `${COMPILER_VERSION}. Update @assistant-ui/next, @assistant-ui/vite, ` +\n \"or @assistant-ui/metro so their compiler satisfies the core package's \" +\n \"optionalDevDependencies range.\",\n filename,\n );\n }\n\n checkedCorePackageJsonPaths.add(corePackageJsonPath);\n}\n\nfunction resolveCorePackageJson(\n ast: t.File,\n filename: string | undefined,\n): string | null {\n for (const packageName of collectImportedDistributionPackages(ast)) {\n const packageJsonPath = resolvePackageJson(packageName, filename);\n if (!packageJsonPath) continue;\n if (packageName === CORE_PACKAGE) return packageJsonPath;\n\n const corePackageJsonPath = resolvePackageJson(\n CORE_PACKAGE,\n packageJsonPath,\n );\n if (corePackageJsonPath) return corePackageJsonPath;\n }\n\n return null;\n}\n\nfunction collectImportedDistributionPackages(ast: t.File): Set<string> {\n const packages = new Set<string>();\n\n for (const statement of ast.program.body) {\n const source =\n (t.isImportDeclaration(statement) ||\n t.isExportNamedDeclaration(statement) ||\n t.isExportAllDeclaration(statement)) &&\n statement.source\n ? statement.source.value\n : null;\n if (!source) continue;\n\n const packageName = packageNameFromSpecifier(source);\n if (packageName) packages.add(packageName);\n }\n\n return packages;\n}\n\nfunction packageNameFromSpecifier(specifier: string): string | null {\n for (const packageName of DISTRIBUTION_PACKAGES) {\n if (specifier === packageName || specifier.startsWith(`${packageName}/`)) {\n return packageName;\n }\n }\n\n return null;\n}\n\nfunction resolvePackageJson(\n packageName: string,\n filename: string | undefined,\n): string | null {\n const requirePath = normalizeRequirePath(filename);\n const require = createRequire(requirePath);\n\n try {\n return findPackageJson(require.resolve(packageName), packageName);\n } catch {\n return findPackageJsonFromNodeModules(packageName, requirePath);\n }\n}\n\nfunction normalizeRequirePath(filename: string | undefined): string {\n return cleanAbsoluteFilename(filename) ?? import.meta.url;\n}\n\n/** Strips a `?query`/`#hash` suffix and returns the path only if it is absolute. */\nfunction cleanAbsoluteFilename(filename: string | undefined): string | null {\n if (!filename) return null;\n const clean = filename.split(/[?#]/, 1)[0]!;\n return nodePath.isAbsolute(clean) ? clean : null;\n}\n\nfunction findPackageJson(\n fromPathOrUrl: string,\n packageName: string,\n): string | null {\n let current = nodePath.dirname(\n fromPathOrUrl.startsWith(\"file:\")\n ? new URL(fromPathOrUrl).pathname\n : nodePath.resolve(fromPathOrUrl),\n );\n\n for (;;) {\n const packageJsonPath = nodePath.join(current, \"package.json\");\n const packageJson = readPackageJson(packageJsonPath);\n if (packageJson?.name === packageName) return packageJsonPath;\n\n const parent = nodePath.dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n}\n\nfunction findPackageJsonFromNodeModules(\n packageName: string,\n fromPathOrUrl: string,\n): string | null {\n const parts = packageName.split(\"/\");\n let current = nodePath.dirname(\n fromPathOrUrl.startsWith(\"file:\")\n ? new URL(fromPathOrUrl).pathname\n : nodePath.resolve(fromPathOrUrl),\n );\n\n for (;;) {\n const packageJsonPath = nodePath.join(\n current,\n \"node_modules\",\n ...parts,\n \"package.json\",\n );\n const packageJson = readPackageJson(packageJsonPath);\n if (packageJson?.name === packageName) return packageJsonPath;\n\n const parent = nodePath.dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n}\n\nfunction readPackageJson(packageJsonPath: string): PackageJson | null {\n if (!existsSync(packageJsonPath)) return null;\n try {\n return JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as PackageJson;\n } catch (error) {\n throw new GenerativeCompileError(\n `could not parse package metadata at ${packageJsonPath}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n}\n\n/**\n * Errors unless the module's default export is the toolkit — a `defineToolkit(...)`\n * call (through `satisfies`/`as`/parens). This is the security boundary: the\n * default export is what the runtime registers, so it must be wrapped (and thus\n * split). A bare `export default { ... }` would ship a backend `execute` to the\n * client even if some *other* `defineToolkit(...)` exists elsewhere in the file.\n */\nfunction ensureDefaultExport(ast: t.File, filename: string | undefined): void {\n const def = ast.program.body.find(\n (stmt): stmt is t.ExportDefaultDeclaration =>\n t.isExportDefaultDeclaration(stmt),\n );\n if (!def) {\n throw new GenerativeCompileError(\"missing a default export\", filename);\n }\n if (!unwrapToToolkitCall(def.declaration)) {\n throw new GenerativeCompileError(\n `the default export must be ${TOOLKIT_WRAPPER}({ ... }) or ` +\n `${MCP_TOOLKIT_WRAPPER}({ ... }) (imported from \"@assistant-ui/react\"); ` +\n \"wrapping is required so a backend `execute` can't be authored in a way \" +\n \"that reaches the client\",\n filename,\n );\n }\n}\n\n/**\n * Unwraps a node through `satisfies`/`as`/parens to a call of the named function,\n * or returns `null`.\n */\nfunction unwrapToCall(node: t.Node, name: string): t.CallExpression | null {\n if (t.isTSSatisfiesExpression(node) || t.isTSAsExpression(node)) {\n return unwrapToCall(node.expression, name);\n }\n if (t.isParenthesizedExpression(node)) {\n return unwrapToCall(node.expression, name);\n }\n if (t.isCallExpression(node) && t.isIdentifier(node.callee, { name })) {\n return node;\n }\n return null;\n}\n\n/**\n * Collects the names bound to `new JSONGenerativeUI(...)` (e.g.\n * `const generative = new JSONGenerativeUI({ library })`). A toolkit entry that\n * calls a method on one of these is a generative tool whose halves the library\n * routes by export condition, so it passes through the toolkit pass untouched.\n */\nfunction collectGenerativeInstances(ast: t.File): Set<string> {\n const names = new Set<string>();\n for (const statement of ast.program.body) {\n if (!t.isVariableDeclaration(statement)) continue;\n for (const declaration of statement.declarations) {\n const { id, init } = declaration;\n if (\n t.isIdentifier(id) &&\n t.isNewExpression(init) &&\n t.isIdentifier(init.callee, { name: GENERATIVE_FACTORY })\n ) {\n names.add(id.name);\n }\n }\n }\n return names;\n}\n\ntype ToolkitStaticNames = readonly string[] | null;\ntype ToolkitSpreadNames = Map<string, ToolkitStaticNames>;\n\ninterface ToolkitNameContext {\n importedToolkitNamesByFile: Map<string, ToolkitStaticNames | undefined>;\n resolvingImportedToolkitNames: Set<string>;\n}\n\n/**\n * Collects the local names `unstable_interactableTool` is imported under from a\n * distribution package, so toolkit entries calling it can be recognized\n * (and a same-named local function can't smuggle an arbitrary call through).\n */\nfunction collectInteractableToolImports(ast: t.File): Set<string> {\n const names = new Set<string>();\n for (const statement of ast.program.body) {\n if (!t.isImportDeclaration(statement)) continue;\n if (!packageNameFromSpecifier(statement.source.value)) continue;\n for (const specifier of statement.specifiers) {\n if (\n t.isImportSpecifier(specifier) &&\n t.isIdentifier(specifier.imported, { name: INTERACTABLE_TOOL_FACTORY })\n ) {\n names.add(specifier.local.name);\n }\n }\n }\n return names;\n}\n\nfunction createToolkitNameContext(): ToolkitNameContext {\n return {\n importedToolkitNamesByFile: new Map(),\n resolvingImportedToolkitNames: new Set(),\n };\n}\n\n/**\n * The inline config of an `unstable_interactableTool({ ... })` toolkit entry, or `null`\n * when the entry is some other expression.\n */\nfunction interactableToolConfig(\n value: t.Node,\n imports: Set<string>,\n): t.ObjectExpression | null {\n return t.isCallExpression(value) &&\n t.isIdentifier(value.callee) &&\n imports.has(value.callee.name) &&\n t.isObjectExpression(value.arguments[0])\n ? value.arguments[0]\n : null;\n}\n\n/**\n * Toolkit identifiers that are safe to spread into a `defineToolkit({ ... })`,\n * paired with the static tool names they contain. A `null` name list means the\n * spread is safe, but its names are not statically known for duplicate checks.\n *\n * Two kinds qualify:\n *\n * - A local variable whose initializer is visible to this compiler pass: a\n * `defineToolkit(...)` binding is compiled in-place before a later spread\n * reads it, and `defineMcpToolkit(...)` entries can't contain executable code.\n * - The default import of another `\"use generative\"` module: that module is\n * split per-target by its own compiler pass, so spreading its default-exported\n * toolkit can't leak a backend `execute` to the client. Only the default\n * export crosses the generative-module boundary, so named imports don't\n * qualify — they would be `undefined` once that module is build-split.\n */\nfunction collectToolkitSpreadNames(\n ast: t.File,\n filename: string | undefined,\n context: ToolkitNameContext,\n): ToolkitSpreadNames {\n const spreadNames: ToolkitSpreadNames = new Map();\n const localToolkitCalls = new Map<string, t.CallExpression>();\n\n for (const statement of ast.program.body) {\n if (t.isVariableDeclaration(statement)) {\n for (const declaration of statement.declarations) {\n const { id, init } = declaration;\n if (t.isIdentifier(id) && init) {\n const toolkitCall = unwrapToToolkitCall(init);\n if (toolkitCall) localToolkitCalls.set(id.name, toolkitCall);\n }\n }\n continue;\n }\n\n if (t.isImportDeclaration(statement)) {\n const defaultSpecifier = statement.specifiers.find(\n (specifier): specifier is t.ImportDefaultSpecifier =>\n t.isImportDefaultSpecifier(specifier),\n );\n if (!defaultSpecifier) continue;\n\n const names = getGenerativeImportToolkitNames(\n statement.source.value,\n filename,\n context,\n );\n if (names !== undefined) {\n spreadNames.set(defaultSpecifier.local.name, names);\n }\n }\n }\n\n const resolveLocal = (name: string): ToolkitStaticNames | undefined => {\n if (spreadNames.has(name)) return spreadNames.get(name);\n\n const call = localToolkitCalls.get(name);\n if (!call) return undefined;\n\n const object = t.isObjectExpression(call.arguments[0])\n ? call.arguments[0]\n : null;\n const names = object\n ? collectToolkitObjectNames(object, spreadNames)\n : null;\n const publicNames = uniqueToolkitNames(names);\n\n spreadNames.set(name, publicNames);\n return publicNames;\n };\n\n for (const name of localToolkitCalls.keys()) {\n resolveLocal(name);\n }\n\n return spreadNames;\n}\n\nconst MODULE_EXTENSIONS = [\n \".ts\",\n \".tsx\",\n \".mts\",\n \".cts\",\n \".js\",\n \".jsx\",\n \".mjs\",\n \".cjs\",\n] as const;\n\n/** Extensions a specifier may carry that actually map to a TS source file. */\nconst REWRITABLE_JS_EXTENSIONS = new Set([\".js\", \".jsx\", \".mjs\", \".cjs\"]);\n\n/**\n * Reads the static tool names from the default export of an imported\n * `\"use generative\"` module. Relative specifiers and `tsconfig` path aliases\n * (e.g. `@/tools`) are resolved; anything else (a bare package, an unresolvable\n * alias) is treated as non-generative, and thus an unsafe spread.\n */\nfunction getGenerativeImportToolkitNames(\n source: string,\n filename: string | undefined,\n context: ToolkitNameContext,\n): ToolkitStaticNames | undefined {\n const cleanFilename = cleanAbsoluteFilename(filename);\n if (!cleanFilename) return undefined;\n\n const resolved = resolveImportedModuleFile(source, cleanFilename);\n if (!resolved) return undefined;\n\n if (context.importedToolkitNamesByFile.has(resolved)) {\n return context.importedToolkitNamesByFile.get(resolved);\n }\n if (context.resolvingImportedToolkitNames.has(resolved)) return null;\n\n let code: string;\n try {\n code = readFileSync(resolved, \"utf8\");\n } catch {\n context.importedToolkitNamesByFile.set(resolved, undefined);\n return undefined;\n }\n\n if (!isGenerativeModule(code)) {\n context.importedToolkitNamesByFile.set(resolved, undefined);\n return undefined;\n }\n\n context.resolvingImportedToolkitNames.add(resolved);\n try {\n const importedAst = parse(code, {\n sourceType: \"module\",\n plugins: [\"typescript\", \"jsx\", \"explicitResourceManagement\"],\n });\n const names = getDefaultExportToolkitNames(importedAst, resolved, context);\n context.importedToolkitNamesByFile.set(resolved, names);\n return names;\n } catch (error) {\n if (error instanceof GenerativeCompileError) throw error;\n context.importedToolkitNamesByFile.set(resolved, null);\n return null;\n } finally {\n context.resolvingImportedToolkitNames.delete(resolved);\n }\n}\n\nfunction getDefaultExportToolkitNames(\n ast: t.File,\n filename: string | undefined,\n context: ToolkitNameContext,\n): ToolkitStaticNames {\n const def = ast.program.body.find(\n (stmt): stmt is t.ExportDefaultDeclaration =>\n t.isExportDefaultDeclaration(stmt),\n );\n if (!def) return null;\n\n const toolkitCall = unwrapToToolkitCall(def.declaration);\n if (!toolkitCall || !t.isObjectExpression(toolkitCall.arguments[0])) {\n return null;\n }\n\n const spreadNames = collectToolkitSpreadNames(ast, filename, context);\n return uniqueToolkitNames(\n collectToolkitObjectNames(toolkitCall.arguments[0], spreadNames),\n );\n}\n\n/** Resolves an import specifier (relative or `tsconfig`-aliased) to a file on disk. */\nfunction resolveImportedModuleFile(\n source: string,\n fromFilename: string,\n): string | null {\n if (source.startsWith(\".\")) {\n const base = nodePath.resolve(nodePath.dirname(fromFilename), source);\n return resolveModuleFileAtPath(base);\n }\n return resolveAliasImport(source, fromFilename);\n}\n\n/**\n * Resolves a candidate module path, trying TS/JS extensions then index files. A\n * specifier may carry a `.js`-family extension that maps to a `.ts`/`.tsx`\n * source (TypeScript's `bundler`/`nodenext` resolution), so the extension is\n * dropped before probing.\n */\nfunction resolveModuleFileAtPath(base: string): string | null {\n const ext = nodePath.extname(base);\n if (ext && existsSync(base)) return base;\n\n const stem = REWRITABLE_JS_EXTENSIONS.has(ext)\n ? base.slice(0, -ext.length)\n : base;\n\n for (const candidateExt of MODULE_EXTENSIONS) {\n const candidate = `${stem}${candidateExt}`;\n if (existsSync(candidate)) return candidate;\n }\n for (const candidateExt of MODULE_EXTENSIONS) {\n const candidate = nodePath.join(base, `index${candidateExt}`);\n if (existsSync(candidate)) return candidate;\n }\n return null;\n}\n\ninterface TsconfigAliases {\n /** Absolute directory that `paths` targets resolve against. */\n baseDir: string;\n paths: Record<string, string[]>;\n}\n\n/** Resolves a `tsconfig` path alias (e.g. `@/tools/x`) to a file on disk. */\nfunction resolveAliasImport(\n source: string,\n fromFilename: string,\n): string | null {\n const tsconfig = loadTsconfigAliases(nodePath.dirname(fromFilename));\n if (!tsconfig) return null;\n\n // TypeScript matches the most specific key first: an exact (wildcard-free) key\n // beats a wildcard one, and a longer static prefix beats a shorter one.\n const patterns = Object.entries(tsconfig.paths).sort(\n ([a], [b]) => aliasSpecificity(b) - aliasSpecificity(a),\n );\n\n for (const [pattern, targets] of patterns) {\n const matched = matchAliasPattern(pattern, source);\n if (matched === null) continue;\n\n for (const target of targets) {\n const specifier = substituteAliasWildcard(target, matched);\n const file = resolveModuleFileAtPath(\n nodePath.resolve(tsconfig.baseDir, specifier),\n );\n if (file) return file;\n }\n }\n return null;\n}\n\n/** Ranks a `paths` key: an exact key outranks any wildcard; longer prefixes win. */\nfunction aliasSpecificity(pattern: string): number {\n const star = pattern.indexOf(\"*\");\n return star === -1 ? pattern.length + 1 : star;\n}\n\n/** Substitutes the single `*` in a `paths` target with the matched text. */\nfunction substituteAliasWildcard(target: string, matched: string): string {\n const star = target.indexOf(\"*\");\n if (star === -1) return target;\n return target.slice(0, star) + matched + target.slice(star + 1);\n}\n\n/**\n * Matches an import specifier against a `tsconfig` `paths` key. Returns the text\n * captured by the key's `*` (or `\"\"` for an exact, wildcard-free key), or `null`\n * when the specifier doesn't match.\n */\nfunction matchAliasPattern(pattern: string, source: string): string | null {\n const star = pattern.indexOf(\"*\");\n if (star === -1) return pattern === source ? \"\" : null;\n\n const prefix = pattern.slice(0, star);\n const suffix = pattern.slice(star + 1);\n if (\n source.length >= prefix.length + suffix.length &&\n source.startsWith(prefix) &&\n source.endsWith(suffix)\n ) {\n return source.slice(prefix.length, source.length - suffix.length);\n }\n return null;\n}\n\n/**\n * Memoizes resolved aliases per start directory. The compiler runs once per\n * file across a build, so without this every aliased spread re-walks and\n * re-parses the same `tsconfig.json`. Process-lifetime, like\n * `checkedCorePackageJsonPaths`.\n */\nconst tsconfigAliasesByDir = new Map<string, TsconfigAliases | null>();\n\n/** Walks up from a directory to the nearest `tsconfig.json` that declares `paths`. */\nfunction loadTsconfigAliases(fromDir: string): TsconfigAliases | null {\n const cached = tsconfigAliasesByDir.get(fromDir);\n if (cached !== undefined) return cached;\n\n let aliases: TsconfigAliases | null = null;\n let dir = fromDir;\n for (;;) {\n const tsconfigPath = nodePath.join(dir, \"tsconfig.json\");\n if (existsSync(tsconfigPath)) {\n aliases = readTsconfigAliases(tsconfigPath, new Set());\n if (aliases) break;\n }\n const parent = nodePath.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n tsconfigAliasesByDir.set(fromDir, aliases);\n return aliases;\n}\n\n/** Reads `baseUrl`/`paths` from a tsconfig, following a single `extends` chain. */\nfunction readTsconfigAliases(\n tsconfigPath: string,\n seen: Set<string>,\n): TsconfigAliases | null {\n if (seen.has(tsconfigPath)) return null;\n seen.add(tsconfigPath);\n\n let config: {\n extends?: string | string[];\n compilerOptions?: { baseUrl?: string; paths?: Record<string, string[]> };\n } | null;\n try {\n config = parseJsonc(readFileSync(tsconfigPath, \"utf8\"));\n } catch {\n return null;\n }\n if (!config) return null;\n\n const configDir = nodePath.dirname(tsconfigPath);\n const { baseUrl, paths } = config.compilerOptions ?? {};\n\n if (paths) {\n return {\n baseDir: baseUrl ? nodePath.resolve(configDir, baseUrl) : configDir,\n paths,\n };\n }\n\n // `extends` may be a string or (TS 5.0+) a string array; later entries take\n // precedence, so try them last-first. Parsed from untrusted JSONC, so the\n // array case is a real runtime shape, not just a type.\n const extendsList = Array.isArray(config.extends)\n ? config.extends\n : config.extends\n ? [config.extends]\n : [];\n for (let i = extendsList.length - 1; i >= 0; i--) {\n const entry = extendsList[i];\n if (typeof entry !== \"string\") continue;\n const extended = resolveExtendedTsconfig(entry, configDir);\n if (extended) {\n const aliases = readTsconfigAliases(extended, seen);\n if (aliases) return aliases;\n }\n }\n return null;\n}\n\n/** Resolves a tsconfig `extends` value (relative path or installed package). */\nfunction resolveExtendedTsconfig(\n extendsValue: string,\n configDir: string,\n): string | null {\n if (extendsValue.startsWith(\".\")) {\n const base = nodePath.resolve(configDir, extendsValue);\n const candidates =\n nodePath.extname(base) === \".json\" ? [base] : [`${base}.json`, base];\n return candidates.find((candidate) => existsSync(candidate)) ?? null;\n }\n try {\n return createRequire(nodePath.join(configDir, \"package.json\")).resolve(\n extendsValue.endsWith(\".json\") ? extendsValue : `${extendsValue}.json`,\n );\n } catch {\n return null;\n }\n}\n\n/** Parses JSON with `//` and block comments and trailing commas stripped (tsconfig is JSONC). */\nfunction parseJsonc(text: string): any {\n const withoutComments = text.replace(\n /\"(?:[^\"\\\\]|\\\\.)*\"|\\/\\/[^\\n\\r]*|\\/\\*[\\s\\S]*?\\*\\//g,\n (match) => (match.startsWith('\"') ? match : \"\"),\n );\n const withoutTrailingCommas = withoutComments.replace(/,(\\s*[}\\]])/g, \"$1\");\n return JSON.parse(withoutTrailingCommas);\n}\n\nfunction unwrapToToolkitCall(node: t.Node): t.CallExpression | null {\n return (\n unwrapToCall(node, TOOLKIT_WRAPPER) ??\n unwrapToCall(node, MCP_TOOLKIT_WRAPPER)\n );\n}\n\nfunction collectToolkitObjectNames(\n object: t.ObjectExpression,\n toolkitSpreadNames: ToolkitSpreadNames,\n): ToolkitStaticNames {\n const names: string[] = [];\n\n for (const entry of object.properties) {\n const entryNames = toolkitEntryNames(entry, toolkitSpreadNames);\n if (!entryNames) return null;\n names.push(...entryNames);\n }\n\n return names;\n}\n\nfunction uniqueToolkitNames(names: ToolkitStaticNames): ToolkitStaticNames {\n return names ? [...new Set(names)] : names;\n}\n\nfunction toolkitEntryNames(\n entry: t.ObjectExpression[\"properties\"][number],\n toolkitSpreadNames: ToolkitSpreadNames,\n): ToolkitStaticNames {\n if (t.isSpreadElement(entry)) {\n if (t.isIdentifier(entry.argument)) {\n return toolkitSpreadNames.get(entry.argument.name) ?? null;\n }\n\n const directMcpToolkit = unwrapToCall(entry.argument, MCP_TOOLKIT_WRAPPER);\n if (\n directMcpToolkit &&\n t.isObjectExpression(directMcpToolkit.arguments[0])\n ) {\n return collectToolkitObjectNames(\n directMcpToolkit.arguments[0],\n toolkitSpreadNames,\n );\n }\n\n return null;\n }\n\n if (t.isObjectProperty(entry) || t.isObjectMethod(entry)) {\n const name = memberName(entry.key, entry.computed);\n return name ? [name] : [];\n }\n\n return [];\n}\n\nfunction warnDuplicateToolkitNames(\n object: t.ObjectExpression,\n toolkitSpreadNames: ToolkitSpreadNames,\n filename: string | undefined,\n): void {\n const names = collectToolkitObjectNames(object, toolkitSpreadNames);\n if (!names) return;\n\n const seen = new Set<string>();\n const warned = new Set<string>();\n for (const name of names) {\n if (seen.has(name)) {\n if (!warned.has(name)) {\n console.warn(\n new GenerativeCompileError(\n `Duplicate tool name \"${name}\" while composing toolkits. ` +\n \"JavaScript object spread keeps the last definition.\",\n filename,\n ).message,\n );\n warned.add(name);\n }\n continue;\n }\n seen.add(name);\n }\n}\n\nfunction isSafeToolkitSpread(\n entry: t.SpreadElement,\n toolkitSpreadNames: ToolkitSpreadNames,\n): boolean {\n if (t.isIdentifier(entry.argument)) {\n return toolkitSpreadNames.has(entry.argument.name);\n }\n\n const directMcpToolkit = unwrapToCall(entry.argument, MCP_TOOLKIT_WRAPPER);\n return (\n !!directMcpToolkit && t.isObjectExpression(directMcpToolkit.arguments[0])\n );\n}\n\n/** The `JSONGenerativeUI` methods that produce a split-by-condition tool. */\nconst GENERATIVE_TOOL_METHODS = new Set([\"present\", \"promptUser\"]);\n\n/**\n * Whether a toolkit entry's value is a call to a tool-producing method on a\n * collected `JSONGenerativeUI` instance (`generative.present()`), which passes\n * through. The method name is checked too, so a typo like `generative.presnt()`\n * is a compile error here rather than a pass-through that fails at runtime.\n */\nfunction isGenerativeToolEntry(value: t.Node, instances: Set<string>): boolean {\n return (\n t.isCallExpression(value) &&\n t.isMemberExpression(value.callee) &&\n !value.callee.computed &&\n t.isIdentifier(value.callee.object) &&\n instances.has(value.callee.object.name) &&\n t.isIdentifier(value.callee.property) &&\n GENERATIVE_TOOL_METHODS.has(value.callee.property.name)\n );\n}\n\n/**\n * Splits a `defineGenerativeComponents({ ... })` library for a build target:\n * a component's `render` (and the client imports it alone uses) is dropped on\n * the server; `properties`/`description` stay on both, since they drive the tool\n * schema either way. Mutates the object in place.\n */\nfunction compileComponents(\n object: t.ObjectExpression,\n target: Target,\n flags: TargetFlags,\n filename: string | undefined,\n): void {\n for (const entry of object.properties) {\n const value = entryValue(entry);\n if (!value) {\n throw new GenerativeCompileError(\n `each component in ${COMPONENTS_WRAPPER}() must be an inline object ` +\n \"literal (`name: { ... }`) so its `render` can be routed\",\n filename,\n );\n }\n if (!findMember(value, \"render\")) continue;\n // The client keeps `render` (and so needs the module marked `\"use client\"`);\n // the server drops it, since only the schema reaches the model there.\n if (target === \"client\") flags.keptRender = true;\n else removeMember(value, \"render\");\n }\n}\n\n/**\n * Splits a `defineToolkit({ ... })` for a build target. Each inline tool is\n * routed by inferred type (see the per-entry logic); a generative entry like\n * `generative.present()` passes through, the library having already split it.\n * Mutates the object in place and records outcomes in {@link TargetFlags}.\n */\nfunction compileToolkit(\n object: t.ObjectExpression,\n target: Target,\n instances: Set<string>,\n interactableToolImports: Set<string>,\n toolkitSpreadNames: ToolkitSpreadNames,\n flags: TargetFlags,\n filename: string | undefined,\n): void {\n // Split builds compile both targets; emit target-independent warnings from\n // the client pass so each duplicate is logged once.\n if (target === \"client\") {\n warnDuplicateToolkitNames(object, toolkitSpreadNames, filename);\n }\n\n const nextProperties: t.ObjectExpression[\"properties\"] = [];\n\n for (const entry of object.properties) {\n const value = entryValue(entry);\n if (!value) {\n if (\n t.isSpreadElement(entry) &&\n isSafeToolkitSpread(entry, toolkitSpreadNames)\n ) {\n nextProperties.push(entry);\n continue;\n }\n // A generative tool (`generative.present()`) is split by the library's\n // export conditions, so it is safe to keep verbatim. Anything else — a\n // method or opaque call like `makeTool()` — can't be analyzed, so its\n // `execute` could reach the client unstripped.\n const raw = entryRawValue(entry);\n if (raw && isGenerativeToolEntry(raw, instances)) {\n nextProperties.push(entry);\n continue;\n }\n const config =\n raw && interactableToolConfig(raw, interactableToolImports);\n if (config) {\n if (target === \"client\") flags.keptRender = true;\n else removeMember(config, \"render\");\n nextProperties.push(entry);\n continue;\n }\n throw new GenerativeCompileError(\n \"each tool must be an inline object literal (`name: { ... }`) or a \" +\n \"compiler-visible toolkit spread / generative tool (e.g. \" +\n \"`...defineMcpToolkit(...)`, `...baseToolkit`, \" +\n \"`generative.present()`, or `unstable_interactableTool(...)`) so its \" +\n \"`execute` can be routed\",\n filename,\n );\n }\n\n // Nature is inferred from `execute` (see inferToolType), not an authored\n // `type`. The resolved type is written back below so the runtime keeps it.\n const execute = findMember(value, \"execute\");\n const isStub = execute ? executeIsStubTool(execute) : false;\n const isExternal = execute ? executeIsExternalTool(execute) : false;\n const type = inferToolType(value, filename);\n const hasRender = !!findMember(value, \"render\");\n const hasRenderText = !!findMember(value, \"renderText\");\n\n if (type === \"frontend\" && !hasRender && !hasRenderText) {\n throw new GenerativeCompileError(\n \"a frontend tool must declare a `render` or `renderText` \" +\n \"(it has no server execute to show otherwise)\",\n filename,\n );\n }\n\n if (type === \"human\" && !hasRender) {\n throw new GenerativeCompileError(\n \"a human tool must declare a `render` so it can collect input\",\n filename,\n );\n }\n\n if (type === \"provider\" && execute) {\n const toolName = t.isObjectProperty(entry)\n ? memberName(entry.key, entry.computed)\n : undefined;\n applyProviderToolConfig(value, execute, toolName, filename);\n }\n\n if (isExternal) {\n if (!hasRender && !hasRenderText) {\n throw new GenerativeCompileError(\n \"an external tool must declare a `render` or `renderText` \" +\n \"(assistant-ui only renders calls for tools defined elsewhere)\",\n filename,\n );\n }\n if (target === \"server\") continue;\n stripExternalToolMetadata(value);\n }\n\n if (target === \"client\") {\n // A non-stub frontend execute stays (its `\"use client\"` marker is no longer needed\n // once the module is client); backend, sentinel, and stub executes are dropped.\n if (execute && type === \"frontend\" && !isStub) stripUseClient(execute);\n else if (execute) removeMember(value, \"execute\");\n if (hasRender || hasRenderText) flags.keptRender = true;\n } else {\n // server: render is never needed; only a non-external backend execute survives.\n if (hasRender) removeMember(value, \"render\");\n if (hasRenderText) removeMember(value, \"renderText\");\n if (execute) {\n if (type === \"backend\" && !isExternal) flags.keptBackendExecute = true;\n else removeMember(value, \"execute\");\n }\n }\n\n setToolType(value, type);\n setBackendDefault(value, target, type);\n nextProperties.push(entry);\n }\n\n object.properties = nextProperties;\n}\n\nfunction applyProviderToolConfig(\n object: t.ObjectExpression,\n execute: t.ObjectProperty | t.ObjectMethod,\n toolName: string | undefined,\n filename: string | undefined,\n): void {\n if (\n !t.isObjectProperty(execute) ||\n !t.isCallExpression(execute.value) ||\n execute.value.arguments.length !== 1 ||\n !t.isObjectExpression(execute.value.arguments[0])\n ) {\n throw new GenerativeCompileError(\n \"`providerTool(...)` must receive an inline object literal\",\n filename,\n );\n }\n\n const existingNames = new Set(\n object.properties.flatMap((prop) => {\n if (!t.isObjectProperty(prop) && !t.isObjectMethod(prop)) return [];\n const name = memberName(prop.key, prop.computed);\n return name ? [name] : [];\n }),\n );\n const configNames = new Set<string>();\n\n for (const prop of execute.value.arguments[0].properties) {\n if (!t.isObjectProperty(prop)) {\n throw new GenerativeCompileError(\n \"`providerTool(...)` config can only contain object properties\",\n filename,\n );\n }\n const name = memberName(prop.key, prop.computed);\n if (!name) {\n throw new GenerativeCompileError(\n \"`providerTool(...)` config can only contain static property names\",\n filename,\n );\n }\n if (\n t.isFunctionExpression(prop.value) ||\n t.isArrowFunctionExpression(prop.value)\n ) {\n throw new GenerativeCompileError(\n \"`providerTool(...)` config cannot contain function-valued properties\",\n filename,\n );\n }\n if (existingNames.has(name) || configNames.has(name)) {\n const toolLabel = toolName ? ` for \"${toolName}\"` : \"\";\n throw new GenerativeCompileError(\n `\\`providerTool(...)\\` config${toolLabel} duplicates \"${name}\"`,\n filename,\n );\n }\n configNames.add(name);\n object.properties.push(prop);\n }\n}\n\ntype Entry = t.ObjectExpression[\"properties\"][number];\n\n/** The raw AST value of an entry (any expression), or null for spreads/methods. */\nfunction entryRawValue(entry: Entry): t.Expression | null {\n if (t.isObjectProperty(entry) && t.isExpression(entry.value)) {\n return entry.value;\n }\n return null;\n}\n\nfunction entryValue(entry: Entry): t.ObjectExpression | null {\n if (t.isObjectProperty(entry) && t.isObjectExpression(entry.value)) {\n return entry.value;\n }\n return null;\n}\n\n/** A member of an entry object: `render`/`execute`/`type`, as property or method. */\nfunction findMember(\n object: t.ObjectExpression,\n name: string,\n): t.ObjectProperty | t.ObjectMethod | undefined {\n return object.properties.find(\n (p): p is t.ObjectProperty | t.ObjectMethod =>\n (t.isObjectProperty(p) || t.isObjectMethod(p)) &&\n memberName(p.key, p.computed) === name,\n );\n}\n\nfunction removeMember(object: t.ObjectExpression, name: string): void {\n object.properties = object.properties.filter(\n (p) =>\n !(\n (t.isObjectProperty(p) || t.isObjectMethod(p)) &&\n memberName(p.key, p.computed) === name\n ),\n );\n}\n\n/** The `BlockStatement` body of an `execute` member, if it has one. */\nfunction executeBody(\n member: t.ObjectProperty | t.ObjectMethod,\n): t.BlockStatement | undefined {\n if (t.isObjectMethod(member)) return member.body;\n const value = member.value;\n if (\n (t.isArrowFunctionExpression(value) || t.isFunctionExpression(value)) &&\n t.isBlockStatement(value.body)\n ) {\n return value.body;\n }\n return undefined;\n}\n\n/** Whether an `execute` opts into the client via a leading `\"use client\"`. */\nfunction executeIsClient(member: t.ObjectProperty | t.ObjectMethod): boolean {\n return !!executeBody(member)?.directives.some(\n (d) => d.value.value === \"use client\",\n );\n}\n\nfunction executeIsSentinel(\n member: t.ObjectProperty | t.ObjectMethod,\n name: string,\n): boolean {\n return (\n t.isObjectProperty(member) &&\n t.isCallExpression(member.value) &&\n t.isIdentifier(member.value.callee, { name })\n );\n}\n\n/** Whether an `execute` is the human-in-the-loop sentinel. */\nfunction executeIsHumanTool(\n member: t.ObjectProperty | t.ObjectMethod,\n): boolean {\n return (\n executeIsSentinel(member, \"humanTool\") ||\n executeIsSentinel(member, \"hitlTool\") ||\n executeIsSentinel(member, \"hitl\")\n );\n}\n\n/** Whether an `execute` is the provider-tool sentinel. */\nfunction executeIsProviderTool(\n member: t.ObjectProperty | t.ObjectMethod,\n): boolean {\n return executeIsSentinel(member, \"providerTool\");\n}\n\n/** Whether an `execute` is the local override sentinel. */\nfunction executeIsStubTool(member: t.ObjectProperty | t.ObjectMethod): boolean {\n return executeIsSentinel(member, \"stubTool\");\n}\n\n/** Whether an `execute` is the externally-defined backend tool sentinel. */\nfunction executeIsExternalTool(\n member: t.ObjectProperty | t.ObjectMethod,\n): boolean {\n return executeIsSentinel(member, \"externalTool\");\n}\n\n/** Drops the `\"use client\"` directive from an `execute` body (kept frontend). */\nfunction stripUseClient(member: t.ObjectProperty | t.ObjectMethod): void {\n const body = executeBody(member);\n if (body) {\n body.directives = body.directives.filter(\n (d) => d.value.value !== \"use client\",\n );\n }\n}\n\n/**\n * The tool's nature, inferred from its (mandatory) `execute` rather than an\n * authored `type`: `humanTool()` → `human`; `providerTool(...)` → `provider`;\n * `stubTool()` → `frontend`; `externalTool()` → `backend`; `\"use client\"` →\n * `frontend`; otherwise `backend`.\n * The loader writes the result back as a `type` field (see {@link setToolType})\n * so the runtime keeps it.\n */\nfunction inferToolType(\n object: t.ObjectExpression,\n filename: string | undefined,\n): ToolType {\n const execute = findMember(object, \"execute\");\n if (!execute) {\n throw new GenerativeCompileError(\n \"every tool must declare an `execute`; use `humanTool()` for a \" +\n \"human-in-the-loop tool\",\n filename,\n );\n }\n if (executeIsHumanTool(execute)) return \"human\";\n if (executeIsProviderTool(execute)) return \"provider\";\n if (executeIsStubTool(execute)) return \"frontend\";\n if (executeIsExternalTool(execute)) return \"backend\";\n return executeIsClient(execute) ? \"frontend\" : \"backend\";\n}\n\nfunction stripExternalToolMetadata(object: t.ObjectExpression): void {\n // Mirror BackendTool's forbidden metadata fields: execute is stripped by the\n // main routing loop, while streamCall is also removed because there is no\n // assistant-ui executor to stream from.\n removeMember(object, \"description\");\n removeMember(object, \"parameters\");\n removeMember(object, \"disabled\");\n removeMember(object, \"toModelOutput\");\n removeMember(object, \"experimental_onSchemaValidationError\");\n removeMember(object, \"providerOptions\");\n removeMember(object, \"streamCall\");\n}\n\n/** Writes the resolved `type` back onto the tool object (replacing any author's). */\nfunction setToolType(object: t.ObjectExpression, type: ToolType): void {\n removeMember(object, \"type\");\n // Append (not prepend) so the inferred type wins over any earlier spread.\n object.properties.push(\n t.objectProperty(t.identifier(\"type\"), t.stringLiteral(type)),\n );\n}\n\nfunction setBackendDefault(\n object: t.ObjectExpression,\n target: Target,\n type: ToolType,\n): void {\n // Always strip any hand-authored marker first; only re-add it for client\n // frontend/human tools whose schema is already known by the backend.\n removeMember(object, \"unstable_backendDefault\");\n if (target !== \"client\" || (type !== \"frontend\" && type !== \"human\")) return;\n\n object.properties.push(\n t.objectProperty(\n t.identifier(\"unstable_backendDefault\"),\n t.objectExpression([\n t.objectProperty(t.identifier(\"parameters\"), t.booleanLiteral(true)),\n ]),\n ),\n );\n}\n\nfunction memberName(\n key: t.Node,\n computed: boolean | undefined,\n): string | undefined {\n if (computed) return undefined;\n if (t.isIdentifier(key)) return key.name;\n if (t.isStringLiteral(key)) return key.value;\n return undefined;\n}\n\n/**\n * Removes declarations and import specifiers left unreferenced after region\n * removal, to a fixpoint (a dropped helper frees what it used). Keeps exports,\n * side-effect imports, and possibly-side-effectful initializers.\n */\nfunction pruneUnused(ast: t.File): void {\n const hadSpecifiers = new WeakSet<t.ImportDeclaration>();\n for (const stmt of ast.program.body) {\n if (t.isImportDeclaration(stmt) && stmt.specifiers.length > 0) {\n hadSpecifiers.add(stmt);\n }\n }\n\n let removedSomething = true;\n while (removedSomething) {\n removedSomething = false;\n traverse(ast, {\n Program(path: NodePath<t.Program>) {\n path.scope.crawl();\n const isUnused = (name: string): boolean => {\n const binding = path.scope.getBinding(name);\n return !!binding && !binding.referenced;\n };\n\n path.node.body = path.node.body.filter((stmt) => {\n if (\n (t.isFunctionDeclaration(stmt) || t.isClassDeclaration(stmt)) &&\n stmt.id &&\n isUnused(stmt.id.name)\n ) {\n removedSomething = true;\n return false;\n }\n if (t.isVariableDeclaration(stmt)) {\n stmt.declarations = stmt.declarations.filter((decl) => {\n // Handles destructuring too: drop the declarator only when *every*\n // bound name is unused (else a `const { a } = server` survives and\n // keeps a server import in the client graph). Restricted to plain\n // patterns so a default/computed-key side effect isn't dropped.\n const names = Object.keys(t.getBindingIdentifiers(decl.id));\n if (\n names.length > 0 &&\n isPlainPattern(decl.id) &&\n isRemovableInit(decl.init) &&\n names.every(isUnused)\n ) {\n removedSomething = true;\n return false;\n }\n return true;\n });\n if (stmt.declarations.length === 0) return false;\n }\n return true;\n });\n path.stop();\n },\n });\n }\n\n traverse(ast, {\n Program(path: NodePath<t.Program>) {\n path.scope.crawl();\n for (const stmt of path.node.body) {\n if (!t.isImportDeclaration(stmt)) continue;\n stmt.specifiers = stmt.specifiers.filter((spec) => {\n const binding = path.scope.getBinding(spec.local.name);\n return binding ? binding.referenced : true;\n });\n }\n path.node.body = path.node.body.filter(\n (stmt) =>\n !(\n t.isImportDeclaration(stmt) &&\n stmt.specifiers.length === 0 &&\n hadSpecifiers.has(stmt)\n ),\n );\n path.stop();\n },\n });\n}\n\n/**\n * Whether a binding pattern is side-effect-free to drop: a plain identifier, or\n * an object/array pattern of plain bindings — no default values\n * (`{ a = expr }`) or computed keys (`{ [expr]: a }`), which would evaluate (and\n * thus could have side effects) at destructuring time.\n */\nfunction isPlainPattern(node: t.Node): boolean {\n if (t.isIdentifier(node)) return true;\n if (t.isObjectPattern(node)) {\n return node.properties.every((p) =>\n t.isRestElement(p)\n ? isPlainPattern(p.argument)\n : !p.computed && isPlainPattern(p.value),\n );\n }\n if (t.isArrayPattern(node)) {\n return node.elements.every((el) => el == null || isPlainPattern(el));\n }\n return false; // AssignmentPattern (default), member expr, etc.\n}\n\n/** Whether a variable initializer is safe to drop (no observable side effects). */\nfunction isRemovableInit(node: t.Expression | null | undefined): boolean {\n if (node == null) return true;\n if (t.isTSAsExpression(node) || t.isTSSatisfiesExpression(node)) {\n return isRemovableInit(node.expression);\n }\n // Containers are removable only if every element is — a nested call (e.g.\n // `[track()]`) has an observable side effect that dropping would lose.\n if (t.isArrayExpression(node)) {\n return node.elements.every(\n (el) => el == null || (t.isExpression(el) && isRemovableInit(el)),\n );\n }\n if (t.isObjectExpression(node)) {\n return node.properties.every(\n (p) =>\n t.isObjectProperty(p) &&\n !p.computed &&\n t.isExpression(p.value) &&\n isRemovableInit(p.value),\n );\n }\n if (t.isTemplateLiteral(node)) {\n return node.expressions.every(\n (e) => t.isExpression(e) && isRemovableInit(e),\n );\n }\n return (\n t.isArrowFunctionExpression(node) ||\n t.isFunctionExpression(node) ||\n t.isClassExpression(node) ||\n t.isIdentifier(node) ||\n // non-computed only — `obj[fn()]` could hide a side-effectful key\n (t.isMemberExpression(node) && !node.computed) ||\n t.isJSXElement(node) ||\n t.isJSXFragment(node) ||\n t.isLiteral(node)\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"compile.js","names":["pkgJson.version"],"sources":["../src/compile.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport * as nodePath from \"node:path\";\nimport { parse } from \"@babel/parser\";\nimport _traverse, { type NodePath } from \"@babel/traverse\";\nimport _generate from \"@babel/generator\";\nimport * as t from \"@babel/types\";\nimport { satisfies } from \"semver\";\nimport { DIRECTIVE, type Target } from \"./constants\";\nimport pkgJson from \"../package.json\" with { type: \"json\" };\n\n// @babel/traverse and @babel/generator are CJS; their default export is the\n// function itself under some interop and `{ default }` under others.\nconst traverse = (\n typeof _traverse === \"function\" ? _traverse : (_traverse as any).default\n) as typeof _traverse;\nconst generate = (\n typeof _generate === \"function\" ? _generate : (_generate as any).default\n) as typeof _generate;\n\nexport type ToolType = \"frontend\" | \"backend\" | \"human\" | \"provider\";\n\n/** The required wrapper around a toolkit's tools (stripped at build time). */\nconst TOOLKIT_WRAPPER = \"defineToolkit\";\n/** The helper that produces MCP-only toolkit fragments. */\nconst MCP_TOOLKIT_WRAPPER = \"defineMcpToolkit\";\n/** The required wrapper around a generative-UI library (stripped at build time). */\nconst COMPONENTS_WRAPPER = \"defineGenerativeComponents\";\n/** The core package whose metadata declares supported compiler versions. */\nconst CORE_PACKAGE = \"@assistant-ui/core\";\n/** This package, checked against core's compatibility range. */\nconst COMPILER_PACKAGE = \"@assistant-ui/x-generative-compiler\";\n/** Packages that re-export core's generative markers. */\nconst DISTRIBUTION_PACKAGES = [\n CORE_PACKAGE,\n \"@assistant-ui/react\",\n \"@assistant-ui/react-native\",\n \"@assistant-ui/react-ink\",\n] as const;\n/** Package that exports the generative UI runtime split by export condition. */\nconst GENERATIVE_UI_PACKAGE = \"@assistant-ui/react-generative-ui\";\n/**\n * The class whose instances expose split-by-condition tools (`present()`,\n * `promptUser()`). A toolkit entry that calls a method on one of these passes\n * through untouched — the library, not this compiler, routes its halves.\n */\nconst GENERATIVE_FACTORY = \"JSONGenerativeUI\";\n/**\n * The factory producing an interactable's complete tool entry. Unlike\n * `JSONGenerativeUI`, its package has no per-target builds, so this compiler\n * splits the inline config: the client keeps `render`, the server drops it.\n * The factory's own `execute` is internal and client-safe (frontend tool).\n */\nconst INTERACTABLE_TOOL_FACTORY = \"unstable_interactableTool\";\n\n/** Mutable per-build outcomes the toolkit pass reports back for directive/guard injection. */\ninterface TargetFlags {\n /** A `render` survived on a client build (→ emit `\"use client\"`). */\n keptRender: boolean;\n /** A backend `execute` survived on a server build (→ emit `import \"server-only\"`). */\n keptBackendExecute: boolean;\n}\n\nexport interface CompileOptions {\n /** Which build target to emit. */\n target: Target;\n /** Source filename, used for error messages and source maps. */\n filename?: string;\n /** Emit a source map alongside the code. */\n sourceMaps?: boolean;\n /**\n * Whether the `server` target prepends `import \"server-only\"` when it keeps a\n * backend `execute`. Defaults to `true` (the Next.js/RSC convention, where the\n * guard fires via the `react-server` condition). Set `false` for bundlers\n * without a `react-server` layer (e.g. a Vite/TanStack Start `ssr` build),\n * where the split is already structural and importing `server-only` would\n * throw — see the Vite integration.\n */\n injectServerOnly?: boolean;\n}\n\nexport interface CompileResult {\n code: string;\n map?: object | null;\n}\n\n/** Thrown when a `\"use generative\"` file violates an authoring constraint. */\nexport class GenerativeCompileError extends Error {\n constructor(message: string, filename?: string) {\n super(\n `[assistant-ui/use-generative]${filename ? ` ${filename}:` : \"\"} ${message}`,\n );\n this.name = \"GenerativeCompileError\";\n }\n}\n\n/** Whether a source string opts into generative compilation via the directive. */\nexport function isGenerativeModule(code: string): boolean {\n // The directive must be a leading statement, preceded only by an optional BOM,\n // whitespace, and line/block comments. Scanned linearly — a regex over the\n // comment prefix is prone to catastrophic backtracking on crafted input.\n let i = code.charCodeAt(0) === 0xfeff ? 1 : 0;\n for (;;) {\n while (i < code.length && /\\s/.test(code[i]!)) i++;\n if (code.startsWith(\"//\", i)) {\n const nl = code.indexOf(\"\\n\", i);\n if (nl === -1) return false;\n i = nl + 1;\n } else if (code.startsWith(\"/*\", i)) {\n const end = code.indexOf(\"*/\", i + 2);\n if (end === -1) return false;\n i = end + 2;\n } else {\n break;\n }\n }\n\n const quote = code[i];\n if (quote !== '\"' && quote !== \"'\") return false;\n\n const directiveStart = i + 1;\n if (!code.startsWith(DIRECTIVE, directiveStart)) return false;\n\n const directiveEnd = directiveStart + DIRECTIVE.length;\n if (code[directiveEnd] !== quote) return false;\n\n return hasDirectiveTerminator(code, directiveEnd + 1);\n}\n\nfunction hasDirectiveTerminator(code: string, start: number): boolean {\n let i = start;\n let sawLineTerminator = false;\n for (;;) {\n if (i >= code.length) return true;\n\n const char = code.charCodeAt(i);\n if (isSemicolon(char)) return true;\n if (isLineTerminator(char)) {\n sawLineTerminator = true;\n i++;\n continue;\n }\n\n if (code.startsWith(\"//\", i)) {\n const lineEnd = nextLineTerminatorIndex(code, i + 2);\n if (lineEnd === -1) return true;\n sawLineTerminator = true;\n i = lineEnd + 1;\n continue;\n }\n\n if (code.startsWith(\"/*\", i)) {\n const end = code.indexOf(\"*/\", i + 2);\n if (end === -1) return false;\n sawLineTerminator ||= containsLineTerminator(code, i + 2, end);\n i = end + 2;\n continue;\n }\n\n if (/\\s/.test(code[i]!)) {\n i++;\n continue;\n }\n\n return sawLineTerminator && !startsExpressionContinuation(code, i);\n }\n}\n\nfunction nextLineTerminatorIndex(code: string, start: number): number {\n for (let i = start; i < code.length; i++) {\n if (isLineTerminator(code.charCodeAt(i))) return i;\n }\n return -1;\n}\n\nfunction containsLineTerminator(\n code: string,\n start: number,\n end: number,\n): boolean {\n for (let i = start; i < end; i++) {\n if (isLineTerminator(code.charCodeAt(i))) return true;\n }\n return false;\n}\n\nfunction startsExpressionContinuation(code: string, start: number): boolean {\n switch (code[start]) {\n case \".\":\n case \"+\":\n case \"-\":\n case \"*\":\n case \"/\":\n case \"%\":\n case \"<\":\n case \">\":\n case \"=\":\n case \"!\":\n case \"&\":\n case \"|\":\n case \"^\":\n case \"?\":\n case \":\":\n case \",\":\n case \"[\":\n case \"(\":\n case \"`\":\n return true;\n }\n\n return (\n startsKeywordContinuation(code, start, \"as\") ||\n startsKeywordContinuation(code, start, \"in\") ||\n startsKeywordContinuation(code, start, \"instanceof\") ||\n startsKeywordContinuation(code, start, \"satisfies\")\n );\n}\n\nfunction startsKeywordContinuation(\n code: string,\n start: number,\n keyword: string,\n): boolean {\n if (!code.startsWith(keyword, start)) return false;\n const next = code[start + keyword.length];\n return next === undefined || !/[\\p{ID_Continue}$]/u.test(next);\n}\n\nfunction isSemicolon(char: number): boolean {\n return char === 59;\n}\n\nfunction isLineTerminator(char: number): boolean {\n return char === 10 || char === 13 || char === 0x2028 || char === 0x2029;\n}\n\n/**\n * Rewrites a `\"use generative\"` module for a single build target, keeping only the\n * regions that target needs and pruning the imports the dropped regions used.\n */\nexport function compileGenerative(\n code: string,\n options: CompileOptions,\n): CompileResult {\n const { target, filename } = options;\n\n const ast = parse(code, {\n sourceType: \"module\",\n plugins: [\"typescript\", \"jsx\", \"explicitResourceManagement\"],\n });\n\n if (!ast.program.directives.some((d) => d.value.value === DIRECTIVE)) {\n throw new GenerativeCompileError(\n `missing \"${DIRECTIVE}\" directive`,\n filename,\n );\n }\n\n ensureCompilerCompatibleWithCore(ast, filename);\n\n // A module may hold several `defineToolkit(...)` / `defineGenerativeComponents(...)`\n // calls anywhere (e.g. a library built inside `new JSONGenerativeUI(...)` plus\n // the toolkit that exposes it). Tools may reference a `JSONGenerativeUI`\n // instance's `present()`/`promptUser()`, which the library — not this compiler —\n // splits across builds via export conditions; collect those instance names so\n // such entries pass through.\n ensureDefaultExport(ast, filename);\n const generativeInstances = collectGenerativeInstances(ast);\n const interactableToolImports = collectInteractableToolImports(ast);\n const toolkitSpreadNames = collectToolkitSpreadNames(\n ast,\n filename,\n createToolkitNameContext(),\n );\n\n const flags: TargetFlags = { keptRender: false, keptBackendExecute: false };\n\n traverse(ast, {\n CallExpression(path: NodePath<t.CallExpression>) {\n const callee = path.node.callee;\n const object = t.isObjectExpression(path.node.arguments[0])\n ? path.node.arguments[0]\n : null;\n\n if (t.isIdentifier(callee, { name: COMPONENTS_WRAPPER })) {\n if (!object) {\n throw new GenerativeCompileError(\n `${COMPONENTS_WRAPPER}() takes an inline object literal of components`,\n filename,\n );\n }\n compileComponents(object, target, flags, filename);\n // Unwrap the authoring helper to the bare library object so its import\n // can be pruned.\n path.replaceWith(object);\n path.skip();\n return;\n }\n\n if (t.isIdentifier(callee, { name: TOOLKIT_WRAPPER })) {\n if (!object) {\n throw new GenerativeCompileError(\n `${TOOLKIT_WRAPPER}() takes an inline object literal of tools`,\n filename,\n );\n }\n compileToolkit(\n object,\n target,\n generativeInstances,\n interactableToolImports,\n toolkitSpreadNames,\n flags,\n filename,\n );\n path.replaceWith(object);\n path.skip();\n }\n },\n });\n\n const { keptRender, keptBackendExecute } = flags;\n\n pruneUnused(ast);\n\n // Replace the module directives with the target-appropriate one.\n ast.program.directives = ast.program.directives.filter(\n (d) => d.value.value !== DIRECTIVE && d.value.value !== \"use client\",\n );\n if (target === \"client\" && keptRender) {\n ast.program.directives.unshift(\n t.directive(t.directiveLiteral(\"use client\")),\n );\n }\n if (\n target === \"server\" &&\n keptBackendExecute &&\n (options.injectServerOnly ?? true)\n ) {\n ast.program.body.unshift(\n t.importDeclaration([], t.stringLiteral(\"server-only\")),\n );\n }\n\n const result = generate(\n ast,\n {\n sourceMaps: options.sourceMaps ?? false,\n filename,\n jsescOption: { minimal: true },\n },\n code,\n );\n\n return { code: result.code, map: result.map };\n}\n\ninterface PackageJson {\n name?: string;\n version?: string;\n optionalDevDependencies?: Record<string, string>;\n}\n\nconst checkedCorePackageJsonPaths = new Set<string>();\n\n// This compiler's own version, inlined from package.json at build time. Read via\n// an import (not by walking the filesystem at runtime) so the literal survives\n// being bundled into a host package like `@assistant-ui/metro`, where no\n// standalone `@assistant-ui/x-generative-compiler` sits on disk to walk up to.\nconst COMPILER_VERSION = pkgJson.version;\n\nfunction ensureCompilerCompatibleWithCore(\n ast: t.File,\n filename: string | undefined,\n): void {\n const corePackageJsonPath = resolveCorePackageJson(ast, filename);\n if (\n !corePackageJsonPath ||\n checkedCorePackageJsonPaths.has(corePackageJsonPath)\n ) {\n return;\n }\n\n const corePackageJson = readPackageJson(corePackageJsonPath);\n const range = corePackageJson?.optionalDevDependencies?.[COMPILER_PACKAGE];\n if (!range) {\n checkedCorePackageJsonPaths.add(corePackageJsonPath);\n return;\n }\n\n let compatible = false;\n try {\n compatible = satisfies(COMPILER_VERSION, range, {\n includePrerelease: true,\n });\n } catch {\n throw new GenerativeCompileError(\n `${CORE_PACKAGE}@${corePackageJson.version ?? \"unknown\"} declares an ` +\n `invalid optionalDevDependencies range for ${COMPILER_PACKAGE}: ` +\n JSON.stringify(range),\n filename,\n );\n }\n\n if (!compatible) {\n throw new GenerativeCompileError(\n `${CORE_PACKAGE}@${corePackageJson.version ?? \"unknown\"} requires ` +\n `${COMPILER_PACKAGE} ${range}, but the current compiler is ` +\n `${COMPILER_VERSION}. Update @assistant-ui/next, @assistant-ui/vite, ` +\n \"or @assistant-ui/metro so their compiler satisfies the core package's \" +\n \"optionalDevDependencies range.\",\n filename,\n );\n }\n\n checkedCorePackageJsonPaths.add(corePackageJsonPath);\n}\n\nfunction resolveCorePackageJson(\n ast: t.File,\n filename: string | undefined,\n): string | null {\n for (const packageName of collectImportedDistributionPackages(ast)) {\n const packageJsonPath = resolvePackageJson(packageName, filename);\n if (!packageJsonPath) continue;\n if (packageName === CORE_PACKAGE) return packageJsonPath;\n\n const corePackageJsonPath = resolvePackageJson(\n CORE_PACKAGE,\n packageJsonPath,\n );\n if (corePackageJsonPath) return corePackageJsonPath;\n }\n\n return null;\n}\n\nfunction collectImportedDistributionPackages(ast: t.File): Set<string> {\n const packages = new Set<string>();\n\n for (const statement of ast.program.body) {\n const source =\n (t.isImportDeclaration(statement) ||\n t.isExportNamedDeclaration(statement) ||\n t.isExportAllDeclaration(statement)) &&\n statement.source\n ? statement.source.value\n : null;\n if (!source) continue;\n\n const packageName = packageNameFromSpecifier(source);\n if (packageName) packages.add(packageName);\n }\n\n return packages;\n}\n\nfunction packageNameFromSpecifier(specifier: string): string | null {\n for (const packageName of DISTRIBUTION_PACKAGES) {\n if (specifier === packageName || specifier.startsWith(`${packageName}/`)) {\n return packageName;\n }\n }\n\n return null;\n}\n\nfunction resolvePackageJson(\n packageName: string,\n filename: string | undefined,\n): string | null {\n const requirePath = normalizeRequirePath(filename);\n const require = createRequire(requirePath);\n\n try {\n return findPackageJson(require.resolve(packageName), packageName);\n } catch {\n return findPackageJsonFromNodeModules(packageName, requirePath);\n }\n}\n\nfunction normalizeRequirePath(filename: string | undefined): string {\n return cleanAbsoluteFilename(filename) ?? import.meta.url;\n}\n\n/** Strips a `?query`/`#hash` suffix and returns the path only if it is absolute. */\nfunction cleanAbsoluteFilename(filename: string | undefined): string | null {\n if (!filename) return null;\n const clean = filename.split(/[?#]/, 1)[0]!;\n return nodePath.isAbsolute(clean) ? clean : null;\n}\n\nfunction findPackageJson(\n fromPathOrUrl: string,\n packageName: string,\n): string | null {\n let current = nodePath.dirname(\n fromPathOrUrl.startsWith(\"file:\")\n ? new URL(fromPathOrUrl).pathname\n : nodePath.resolve(fromPathOrUrl),\n );\n\n for (;;) {\n const packageJsonPath = nodePath.join(current, \"package.json\");\n const packageJson = readPackageJson(packageJsonPath);\n if (packageJson?.name === packageName) return packageJsonPath;\n\n const parent = nodePath.dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n}\n\nfunction findPackageJsonFromNodeModules(\n packageName: string,\n fromPathOrUrl: string,\n): string | null {\n const parts = packageName.split(\"/\");\n let current = nodePath.dirname(\n fromPathOrUrl.startsWith(\"file:\")\n ? new URL(fromPathOrUrl).pathname\n : nodePath.resolve(fromPathOrUrl),\n );\n\n for (;;) {\n const packageJsonPath = nodePath.join(\n current,\n \"node_modules\",\n ...parts,\n \"package.json\",\n );\n const packageJson = readPackageJson(packageJsonPath);\n if (packageJson?.name === packageName) return packageJsonPath;\n\n const parent = nodePath.dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n}\n\nfunction readPackageJson(packageJsonPath: string): PackageJson | null {\n if (!existsSync(packageJsonPath)) return null;\n try {\n return JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as PackageJson;\n } catch (error) {\n throw new GenerativeCompileError(\n `could not parse package metadata at ${packageJsonPath}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n}\n\n/**\n * Errors unless the module's default export is the toolkit — a `defineToolkit(...)`\n * call (through `satisfies`/`as`/parens). This is the security boundary: the\n * default export is what the runtime registers, so it must be wrapped (and thus\n * split). A bare `export default { ... }` would ship a backend `execute` to the\n * client even if some *other* `defineToolkit(...)` exists elsewhere in the file.\n */\nfunction ensureDefaultExport(ast: t.File, filename: string | undefined): void {\n const def = ast.program.body.find(\n (stmt): stmt is t.ExportDefaultDeclaration =>\n t.isExportDefaultDeclaration(stmt),\n );\n if (!def) {\n throw new GenerativeCompileError(\"missing a default export\", filename);\n }\n if (!unwrapToToolkitCall(def.declaration)) {\n throw new GenerativeCompileError(\n `the default export must be ${TOOLKIT_WRAPPER}({ ... }) or ` +\n `${MCP_TOOLKIT_WRAPPER}({ ... }) (imported from \"@assistant-ui/react\"); ` +\n \"wrapping is required so a backend `execute` can't be authored in a way \" +\n \"that reaches the client\",\n filename,\n );\n }\n}\n\n/**\n * Unwraps a node through `satisfies`/`as`/parens to a call of the named function,\n * or returns `null`.\n */\nfunction unwrapToCall(node: t.Node, name: string): t.CallExpression | null {\n if (t.isTSSatisfiesExpression(node) || t.isTSAsExpression(node)) {\n return unwrapToCall(node.expression, name);\n }\n if (t.isParenthesizedExpression(node)) {\n return unwrapToCall(node.expression, name);\n }\n if (t.isCallExpression(node) && t.isIdentifier(node.callee, { name })) {\n return node;\n }\n return null;\n}\n\n/**\n * Collects the names bound to `new JSONGenerativeUI(...)` (e.g.\n * `const generative = new JSONGenerativeUI({ library })`). A toolkit entry that\n * calls a method on one of these is a generative tool whose halves the library\n * routes by export condition, so it passes through the toolkit pass untouched.\n */\nfunction collectGenerativeInstances(ast: t.File): Set<string> {\n const names = new Set<string>();\n const generativeFactories = collectGenerativeFactoryImports(ast);\n for (const statement of ast.program.body) {\n const variableDeclaration = t.isVariableDeclaration(statement)\n ? statement\n : t.isExportNamedDeclaration(statement) &&\n t.isVariableDeclaration(statement.declaration)\n ? statement.declaration\n : null;\n if (!variableDeclaration) continue;\n for (const declaration of variableDeclaration.declarations) {\n const { id, init } = declaration;\n if (\n t.isIdentifier(id) &&\n t.isNewExpression(init) &&\n t.isIdentifier(init.callee) &&\n generativeFactories.has(init.callee.name)\n ) {\n names.add(id.name);\n }\n }\n }\n return names;\n}\n\nfunction collectGenerativeFactoryImports(ast: t.File): Set<string> {\n const names = new Set<string>();\n for (const statement of ast.program.body) {\n if (\n !t.isImportDeclaration(statement) ||\n statement.source.value !== GENERATIVE_UI_PACKAGE\n ) {\n continue;\n }\n\n for (const specifier of statement.specifiers) {\n if (\n t.isImportSpecifier(specifier) &&\n t.isIdentifier(specifier.imported, { name: GENERATIVE_FACTORY })\n ) {\n names.add(specifier.local.name);\n }\n }\n }\n return names;\n}\n\ntype ToolkitStaticNames = readonly string[] | null;\ntype ToolkitSpreadNames = Map<string, ToolkitStaticNames>;\n\ninterface ToolkitNameContext {\n importedToolkitNamesByFile: Map<string, ToolkitStaticNames | undefined>;\n resolvingImportedToolkitNames: Set<string>;\n}\n\n/**\n * Collects the local names `unstable_interactableTool` is imported under from a\n * distribution package, so toolkit entries calling it can be recognized\n * (and a same-named local function can't smuggle an arbitrary call through).\n */\nfunction collectInteractableToolImports(ast: t.File): Set<string> {\n const names = new Set<string>();\n for (const statement of ast.program.body) {\n if (!t.isImportDeclaration(statement)) continue;\n if (!packageNameFromSpecifier(statement.source.value)) continue;\n for (const specifier of statement.specifiers) {\n if (\n t.isImportSpecifier(specifier) &&\n t.isIdentifier(specifier.imported, { name: INTERACTABLE_TOOL_FACTORY })\n ) {\n names.add(specifier.local.name);\n }\n }\n }\n return names;\n}\n\nfunction createToolkitNameContext(): ToolkitNameContext {\n return {\n importedToolkitNamesByFile: new Map(),\n resolvingImportedToolkitNames: new Set(),\n };\n}\n\n/**\n * The inline config of an `unstable_interactableTool({ ... })` toolkit entry, or `null`\n * when the entry is some other expression.\n */\nfunction interactableToolConfig(\n value: t.Node,\n imports: Set<string>,\n): t.ObjectExpression | null {\n return t.isCallExpression(value) &&\n t.isIdentifier(value.callee) &&\n imports.has(value.callee.name) &&\n t.isObjectExpression(value.arguments[0])\n ? value.arguments[0]\n : null;\n}\n\n/**\n * Toolkit identifiers that are safe to spread into a `defineToolkit({ ... })`,\n * paired with the static tool names they contain. A `null` name list means the\n * spread is safe, but its names are not statically known for duplicate checks.\n *\n * Two kinds qualify:\n *\n * - A local variable whose initializer is visible to this compiler pass: a\n * `defineToolkit(...)` binding is compiled in-place before a later spread\n * reads it, and `defineMcpToolkit(...)` entries can't contain executable code.\n * - The default import of another `\"use generative\"` module: that module is\n * split per-target by its own compiler pass, so spreading its default-exported\n * toolkit can't leak a backend `execute` to the client. Only the default\n * export crosses the generative-module boundary, so named imports don't\n * qualify — they would be `undefined` once that module is build-split.\n */\nfunction collectToolkitSpreadNames(\n ast: t.File,\n filename: string | undefined,\n context: ToolkitNameContext,\n): ToolkitSpreadNames {\n const spreadNames: ToolkitSpreadNames = new Map();\n const localToolkitCalls = new Map<string, t.CallExpression>();\n\n for (const statement of ast.program.body) {\n if (t.isVariableDeclaration(statement)) {\n for (const declaration of statement.declarations) {\n const { id, init } = declaration;\n if (t.isIdentifier(id) && init) {\n const toolkitCall = unwrapToToolkitCall(init);\n if (toolkitCall) localToolkitCalls.set(id.name, toolkitCall);\n }\n }\n continue;\n }\n\n if (t.isImportDeclaration(statement)) {\n const defaultSpecifier = statement.specifiers.find(\n (specifier): specifier is t.ImportDefaultSpecifier =>\n t.isImportDefaultSpecifier(specifier),\n );\n if (!defaultSpecifier) continue;\n\n const names = getGenerativeImportToolkitNames(\n statement.source.value,\n filename,\n context,\n );\n if (names !== undefined) {\n spreadNames.set(defaultSpecifier.local.name, names);\n }\n }\n }\n\n const resolveLocal = (name: string): ToolkitStaticNames | undefined => {\n if (spreadNames.has(name)) return spreadNames.get(name);\n\n const call = localToolkitCalls.get(name);\n if (!call) return undefined;\n\n const object = t.isObjectExpression(call.arguments[0])\n ? call.arguments[0]\n : null;\n const names = object\n ? collectToolkitObjectNames(object, spreadNames)\n : null;\n const publicNames = uniqueToolkitNames(names);\n\n spreadNames.set(name, publicNames);\n return publicNames;\n };\n\n for (const name of localToolkitCalls.keys()) {\n resolveLocal(name);\n }\n\n return spreadNames;\n}\n\nconst MODULE_EXTENSIONS = [\n \".ts\",\n \".tsx\",\n \".mts\",\n \".cts\",\n \".js\",\n \".jsx\",\n \".mjs\",\n \".cjs\",\n] as const;\n\n/** Extensions a specifier may carry that actually map to a TS source file. */\nconst REWRITABLE_JS_EXTENSIONS = new Set([\".js\", \".jsx\", \".mjs\", \".cjs\"]);\n\n/**\n * Reads the static tool names from the default export of an imported\n * `\"use generative\"` module. Relative specifiers and `tsconfig` path aliases\n * (e.g. `@/tools`) are resolved; anything else (a bare package, an unresolvable\n * alias) is treated as non-generative, and thus an unsafe spread.\n */\nfunction getGenerativeImportToolkitNames(\n source: string,\n filename: string | undefined,\n context: ToolkitNameContext,\n): ToolkitStaticNames | undefined {\n const cleanFilename = cleanAbsoluteFilename(filename);\n if (!cleanFilename) return undefined;\n\n const resolved = resolveImportedModuleFile(source, cleanFilename);\n if (!resolved) return undefined;\n\n if (context.importedToolkitNamesByFile.has(resolved)) {\n return context.importedToolkitNamesByFile.get(resolved);\n }\n if (context.resolvingImportedToolkitNames.has(resolved)) return null;\n\n let code: string;\n try {\n code = readFileSync(resolved, \"utf8\");\n } catch {\n context.importedToolkitNamesByFile.set(resolved, undefined);\n return undefined;\n }\n\n if (!isGenerativeModule(code)) {\n context.importedToolkitNamesByFile.set(resolved, undefined);\n return undefined;\n }\n\n context.resolvingImportedToolkitNames.add(resolved);\n try {\n const importedAst = parse(code, {\n sourceType: \"module\",\n plugins: [\"typescript\", \"jsx\", \"explicitResourceManagement\"],\n });\n const names = getDefaultExportToolkitNames(importedAst, resolved, context);\n context.importedToolkitNamesByFile.set(resolved, names);\n return names;\n } catch (error) {\n if (error instanceof GenerativeCompileError) throw error;\n context.importedToolkitNamesByFile.set(resolved, null);\n return null;\n } finally {\n context.resolvingImportedToolkitNames.delete(resolved);\n }\n}\n\nfunction getDefaultExportToolkitNames(\n ast: t.File,\n filename: string | undefined,\n context: ToolkitNameContext,\n): ToolkitStaticNames {\n const def = ast.program.body.find(\n (stmt): stmt is t.ExportDefaultDeclaration =>\n t.isExportDefaultDeclaration(stmt),\n );\n if (!def) return null;\n\n const toolkitCall = unwrapToToolkitCall(def.declaration);\n if (!toolkitCall || !t.isObjectExpression(toolkitCall.arguments[0])) {\n return null;\n }\n\n const spreadNames = collectToolkitSpreadNames(ast, filename, context);\n return uniqueToolkitNames(\n collectToolkitObjectNames(toolkitCall.arguments[0], spreadNames),\n );\n}\n\n/** Resolves an import specifier (relative or `tsconfig`-aliased) to a file on disk. */\nfunction resolveImportedModuleFile(\n source: string,\n fromFilename: string,\n): string | null {\n if (source.startsWith(\".\")) {\n const base = nodePath.resolve(nodePath.dirname(fromFilename), source);\n return resolveModuleFileAtPath(base);\n }\n return resolveAliasImport(source, fromFilename);\n}\n\n/**\n * Resolves a candidate module path, trying TS/JS extensions then index files. A\n * specifier may carry a `.js`-family extension that maps to a `.ts`/`.tsx`\n * source (TypeScript's `bundler`/`nodenext` resolution), so the extension is\n * dropped before probing.\n */\nfunction resolveModuleFileAtPath(base: string): string | null {\n const ext = nodePath.extname(base);\n if (ext && existsSync(base)) return base;\n\n const stem = REWRITABLE_JS_EXTENSIONS.has(ext)\n ? base.slice(0, -ext.length)\n : base;\n\n for (const candidateExt of MODULE_EXTENSIONS) {\n const candidate = `${stem}${candidateExt}`;\n if (existsSync(candidate)) return candidate;\n }\n for (const candidateExt of MODULE_EXTENSIONS) {\n const candidate = nodePath.join(base, `index${candidateExt}`);\n if (existsSync(candidate)) return candidate;\n }\n return null;\n}\n\ninterface TsconfigAliases {\n /** Absolute directory that `paths` targets resolve against. */\n baseDir: string;\n paths: Record<string, string[]>;\n}\n\n/** Resolves a `tsconfig` path alias (e.g. `@/tools/x`) to a file on disk. */\nfunction resolveAliasImport(\n source: string,\n fromFilename: string,\n): string | null {\n const tsconfig = loadTsconfigAliases(nodePath.dirname(fromFilename));\n if (!tsconfig) return null;\n\n // TypeScript matches the most specific key first: an exact (wildcard-free) key\n // beats a wildcard one, and a longer static prefix beats a shorter one.\n const patterns = Object.entries(tsconfig.paths).sort(\n ([a], [b]) => aliasSpecificity(b) - aliasSpecificity(a),\n );\n\n for (const [pattern, targets] of patterns) {\n const matched = matchAliasPattern(pattern, source);\n if (matched === null) continue;\n\n for (const target of targets) {\n const specifier = substituteAliasWildcard(target, matched);\n const file = resolveModuleFileAtPath(\n nodePath.resolve(tsconfig.baseDir, specifier),\n );\n if (file) return file;\n }\n }\n return null;\n}\n\n/** Ranks a `paths` key: an exact key outranks any wildcard; longer prefixes win. */\nfunction aliasSpecificity(pattern: string): number {\n const star = pattern.indexOf(\"*\");\n return star === -1 ? pattern.length + 1 : star;\n}\n\n/** Substitutes the single `*` in a `paths` target with the matched text. */\nfunction substituteAliasWildcard(target: string, matched: string): string {\n const star = target.indexOf(\"*\");\n if (star === -1) return target;\n return target.slice(0, star) + matched + target.slice(star + 1);\n}\n\n/**\n * Matches an import specifier against a `tsconfig` `paths` key. Returns the text\n * captured by the key's `*` (or `\"\"` for an exact, wildcard-free key), or `null`\n * when the specifier doesn't match.\n */\nfunction matchAliasPattern(pattern: string, source: string): string | null {\n const star = pattern.indexOf(\"*\");\n if (star === -1) return pattern === source ? \"\" : null;\n\n const prefix = pattern.slice(0, star);\n const suffix = pattern.slice(star + 1);\n if (\n source.length >= prefix.length + suffix.length &&\n source.startsWith(prefix) &&\n source.endsWith(suffix)\n ) {\n return source.slice(prefix.length, source.length - suffix.length);\n }\n return null;\n}\n\n/**\n * Memoizes resolved aliases per start directory. The compiler runs once per\n * file across a build, so without this every aliased spread re-walks and\n * re-parses the same `tsconfig.json`. Process-lifetime, like\n * `checkedCorePackageJsonPaths`.\n */\nconst tsconfigAliasesByDir = new Map<string, TsconfigAliases | null>();\n\n/** Walks up from a directory to the nearest `tsconfig.json` that declares `paths`. */\nfunction loadTsconfigAliases(fromDir: string): TsconfigAliases | null {\n const cached = tsconfigAliasesByDir.get(fromDir);\n if (cached !== undefined) return cached;\n\n let aliases: TsconfigAliases | null = null;\n let dir = fromDir;\n for (;;) {\n const tsconfigPath = nodePath.join(dir, \"tsconfig.json\");\n if (existsSync(tsconfigPath)) {\n aliases = readTsconfigAliases(tsconfigPath, new Set());\n if (aliases) break;\n }\n const parent = nodePath.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n tsconfigAliasesByDir.set(fromDir, aliases);\n return aliases;\n}\n\n/** Reads `baseUrl`/`paths` from a tsconfig, following a single `extends` chain. */\nfunction readTsconfigAliases(\n tsconfigPath: string,\n seen: Set<string>,\n): TsconfigAliases | null {\n if (seen.has(tsconfigPath)) return null;\n seen.add(tsconfigPath);\n\n let config: {\n extends?: string | string[];\n compilerOptions?: { baseUrl?: string; paths?: Record<string, string[]> };\n } | null;\n try {\n config = parseJsonc(readFileSync(tsconfigPath, \"utf8\"));\n } catch {\n return null;\n }\n if (!config) return null;\n\n const configDir = nodePath.dirname(tsconfigPath);\n const { baseUrl, paths } = config.compilerOptions ?? {};\n\n if (paths) {\n return {\n baseDir: baseUrl ? nodePath.resolve(configDir, baseUrl) : configDir,\n paths,\n };\n }\n\n // `extends` may be a string or (TS 5.0+) a string array; later entries take\n // precedence, so try them last-first. Parsed from untrusted JSONC, so the\n // array case is a real runtime shape, not just a type.\n const extendsList = Array.isArray(config.extends)\n ? config.extends\n : config.extends\n ? [config.extends]\n : [];\n for (let i = extendsList.length - 1; i >= 0; i--) {\n const entry = extendsList[i];\n if (typeof entry !== \"string\") continue;\n const extended = resolveExtendedTsconfig(entry, configDir);\n if (extended) {\n const aliases = readTsconfigAliases(extended, seen);\n if (aliases) return aliases;\n }\n }\n return null;\n}\n\n/** Resolves a tsconfig `extends` value (relative path or installed package). */\nfunction resolveExtendedTsconfig(\n extendsValue: string,\n configDir: string,\n): string | null {\n if (extendsValue.startsWith(\".\")) {\n const base = nodePath.resolve(configDir, extendsValue);\n const candidates =\n nodePath.extname(base) === \".json\" ? [base] : [`${base}.json`, base];\n return candidates.find((candidate) => existsSync(candidate)) ?? null;\n }\n try {\n return createRequire(nodePath.join(configDir, \"package.json\")).resolve(\n extendsValue.endsWith(\".json\") ? extendsValue : `${extendsValue}.json`,\n );\n } catch {\n return null;\n }\n}\n\n/** Parses JSON with `//` and block comments and trailing commas stripped (tsconfig is JSONC). */\nfunction parseJsonc(text: string): any {\n const withoutComments = text.replace(\n /\"(?:[^\"\\\\]|\\\\.)*\"|\\/\\/[^\\n\\r]*|\\/\\*[\\s\\S]*?\\*\\//g,\n (match) => (match.startsWith('\"') ? match : \"\"),\n );\n const withoutTrailingCommas = withoutComments.replace(/,(\\s*[}\\]])/g, \"$1\");\n return JSON.parse(withoutTrailingCommas);\n}\n\nfunction unwrapToToolkitCall(node: t.Node): t.CallExpression | null {\n return (\n unwrapToCall(node, TOOLKIT_WRAPPER) ??\n unwrapToCall(node, MCP_TOOLKIT_WRAPPER)\n );\n}\n\nfunction collectToolkitObjectNames(\n object: t.ObjectExpression,\n toolkitSpreadNames: ToolkitSpreadNames,\n): ToolkitStaticNames {\n const names: string[] = [];\n\n for (const entry of object.properties) {\n const entryNames = toolkitEntryNames(entry, toolkitSpreadNames);\n if (!entryNames) return null;\n names.push(...entryNames);\n }\n\n return names;\n}\n\nfunction uniqueToolkitNames(names: ToolkitStaticNames): ToolkitStaticNames {\n return names ? [...new Set(names)] : names;\n}\n\nfunction toolkitEntryNames(\n entry: t.ObjectExpression[\"properties\"][number],\n toolkitSpreadNames: ToolkitSpreadNames,\n): ToolkitStaticNames {\n if (t.isSpreadElement(entry)) {\n if (t.isIdentifier(entry.argument)) {\n return toolkitSpreadNames.get(entry.argument.name) ?? null;\n }\n\n const directMcpToolkit = unwrapToCall(entry.argument, MCP_TOOLKIT_WRAPPER);\n if (\n directMcpToolkit &&\n t.isObjectExpression(directMcpToolkit.arguments[0])\n ) {\n return collectToolkitObjectNames(\n directMcpToolkit.arguments[0],\n toolkitSpreadNames,\n );\n }\n\n return null;\n }\n\n if (t.isObjectProperty(entry) || t.isObjectMethod(entry)) {\n const name = memberName(entry.key, entry.computed);\n return name ? [name] : [];\n }\n\n return [];\n}\n\nfunction warnDuplicateToolkitNames(\n object: t.ObjectExpression,\n toolkitSpreadNames: ToolkitSpreadNames,\n filename: string | undefined,\n): void {\n const names = collectToolkitObjectNames(object, toolkitSpreadNames);\n if (!names) return;\n\n const seen = new Set<string>();\n const warned = new Set<string>();\n for (const name of names) {\n if (seen.has(name)) {\n if (!warned.has(name)) {\n console.warn(\n new GenerativeCompileError(\n `Duplicate tool name \"${name}\" while composing toolkits. ` +\n \"JavaScript object spread keeps the last definition.\",\n filename,\n ).message,\n );\n warned.add(name);\n }\n continue;\n }\n seen.add(name);\n }\n}\n\nfunction isSafeToolkitSpread(\n entry: t.SpreadElement,\n toolkitSpreadNames: ToolkitSpreadNames,\n): boolean {\n if (t.isIdentifier(entry.argument)) {\n return toolkitSpreadNames.has(entry.argument.name);\n }\n\n const directMcpToolkit = unwrapToCall(entry.argument, MCP_TOOLKIT_WRAPPER);\n return (\n !!directMcpToolkit && t.isObjectExpression(directMcpToolkit.arguments[0])\n );\n}\n\nfunction genericUnsafeToolkitEntryMessage(): string {\n return (\n \"each tool must be an inline object literal (`name: { ... }`) or a \" +\n \"compiler-visible toolkit spread / generative tool (e.g. \" +\n \"`...defineMcpToolkit(...)`, `...baseToolkit`, \" +\n \"`generative.present()`, or `unstable_interactableTool(...)`) so its \" +\n \"`execute` can be routed\"\n );\n}\n\nfunction describeUnsafeToolkitEntry(entry: Entry): string {\n if (!t.isObjectProperty(entry)) return genericUnsafeToolkitEntryMessage();\n\n const toolName = memberName(entry.key, entry.computed);\n const raw = entryRawValue(entry);\n if (!toolName || !raw) return genericUnsafeToolkitEntryMessage();\n\n return (\n `tool \"${toolName}\" cannot be \\`${generate(raw).code}\\`; use an inline ` +\n `object literal (\\`${toolName}: { ... }\\`) or a compiler-visible toolkit ` +\n \"spread / generative tool so its `execute` can be routed\"\n );\n}\n\n/** The `JSONGenerativeUI` methods that produce a split-by-condition tool. */\nconst GENERATIVE_TOOL_METHODS = new Set([\"present\", \"promptUser\"]);\n\n/**\n * Whether a toolkit entry's value is a call to a tool-producing method on a\n * collected `JSONGenerativeUI` instance (`generative.present()`), which passes\n * through. The method name is checked too, so a typo like `generative.presnt()`\n * is a compile error here rather than a pass-through that fails at runtime.\n */\nfunction isGenerativeToolEntry(value: t.Node, instances: Set<string>): boolean {\n return (\n t.isCallExpression(value) &&\n t.isMemberExpression(value.callee) &&\n !value.callee.computed &&\n t.isIdentifier(value.callee.object) &&\n instances.has(value.callee.object.name) &&\n t.isIdentifier(value.callee.property) &&\n GENERATIVE_TOOL_METHODS.has(value.callee.property.name)\n );\n}\n\n/**\n * Splits a `defineGenerativeComponents({ ... })` library for a build target:\n * a component's `render` (and the client imports it alone uses) is dropped on\n * the server; `properties`/`description` stay on both, since they drive the tool\n * schema either way. Mutates the object in place.\n */\nfunction compileComponents(\n object: t.ObjectExpression,\n target: Target,\n flags: TargetFlags,\n filename: string | undefined,\n): void {\n for (const entry of object.properties) {\n const value = entryValue(entry);\n if (!value) {\n throw new GenerativeCompileError(\n `each component in ${COMPONENTS_WRAPPER}() must be an inline object ` +\n \"literal (`name: { ... }`) so its `render` can be routed\",\n filename,\n );\n }\n if (!findMember(value, \"render\")) continue;\n // The client keeps `render` (and so needs the module marked `\"use client\"`);\n // the server drops it, since only the schema reaches the model there.\n if (target === \"client\") flags.keptRender = true;\n else removeMember(value, \"render\");\n }\n}\n\n/**\n * Splits a `defineToolkit({ ... })` for a build target. Each inline tool is\n * routed by inferred type (see the per-entry logic); a generative entry like\n * `generative.present()` passes through, the library having already split it.\n * Mutates the object in place and records outcomes in {@link TargetFlags}.\n */\nfunction compileToolkit(\n object: t.ObjectExpression,\n target: Target,\n instances: Set<string>,\n interactableToolImports: Set<string>,\n toolkitSpreadNames: ToolkitSpreadNames,\n flags: TargetFlags,\n filename: string | undefined,\n): void {\n // Split builds compile both targets; emit target-independent warnings from\n // the client pass so each duplicate is logged once.\n if (target === \"client\") {\n warnDuplicateToolkitNames(object, toolkitSpreadNames, filename);\n }\n\n const nextProperties: t.ObjectExpression[\"properties\"] = [];\n\n for (const entry of object.properties) {\n const value = entryValue(entry);\n if (!value) {\n if (\n t.isSpreadElement(entry) &&\n isSafeToolkitSpread(entry, toolkitSpreadNames)\n ) {\n nextProperties.push(entry);\n continue;\n }\n // A generative tool (`generative.present()`) is split by the library's\n // export conditions, so it is safe to keep verbatim. Anything else — a\n // method or opaque call like `makeTool()` — can't be analyzed, so its\n // `execute` could reach the client unstripped.\n const raw = entryRawValue(entry);\n if (raw && isGenerativeToolEntry(raw, instances)) {\n nextProperties.push(entry);\n continue;\n }\n const config =\n raw && interactableToolConfig(raw, interactableToolImports);\n if (config) {\n if (target === \"client\") flags.keptRender = true;\n else removeMember(config, \"render\");\n nextProperties.push(entry);\n continue;\n }\n throw new GenerativeCompileError(\n describeUnsafeToolkitEntry(entry),\n filename,\n );\n }\n\n // Nature is inferred from `execute` (see inferToolType), not an authored\n // `type`. The resolved type is written back below so the runtime keeps it.\n const toolName = t.isObjectProperty(entry)\n ? memberName(entry.key, entry.computed)\n : undefined;\n const execute = findMember(value, \"execute\");\n const isStub = execute ? executeIsStubTool(execute) : false;\n const isExternal = execute ? executeIsExternalTool(execute) : false;\n const type = inferToolType(value, toolName, filename);\n const hasRender = !!findMember(value, \"render\");\n const hasRenderText = !!findMember(value, \"renderText\");\n\n if (type === \"frontend\" && !hasRender && !hasRenderText) {\n throw new GenerativeCompileError(\n `${typedToolSubject(\"frontend\", toolName)} must declare a ` +\n \"`render` or `renderText` \" +\n \"(it has no server execute to show otherwise)\",\n filename,\n );\n }\n\n if (type === \"human\" && !hasRender) {\n throw new GenerativeCompileError(\n `${typedToolSubject(\"human\", toolName)} must declare a ` +\n \"`render` so it can collect input\",\n filename,\n );\n }\n\n if (type === \"provider\" && execute) {\n applyProviderToolConfig(value, execute, toolName, filename);\n }\n\n if (isExternal) {\n if (!hasRender && !hasRenderText) {\n throw new GenerativeCompileError(\n `${typedToolSubject(\"external\", toolName)} must declare a ` +\n \"`render` or `renderText` \" +\n \"(assistant-ui only renders calls for tools defined elsewhere)\",\n filename,\n );\n }\n if (target === \"server\") continue;\n stripExternalToolMetadata(value);\n }\n\n if (target === \"client\") {\n // A non-stub frontend execute stays (its `\"use client\"` marker is no longer needed\n // once the module is client); backend, sentinel, and stub executes are dropped.\n if (execute && type === \"frontend\" && !isStub) stripUseClient(execute);\n else if (execute) removeMember(value, \"execute\");\n if (hasRender || hasRenderText) flags.keptRender = true;\n } else {\n // server: render is never needed; only a non-external backend execute survives.\n if (hasRender) removeMember(value, \"render\");\n if (hasRenderText) removeMember(value, \"renderText\");\n if (execute) {\n if (type === \"backend\" && !isExternal) flags.keptBackendExecute = true;\n else removeMember(value, \"execute\");\n }\n }\n\n setToolType(value, type);\n setBackendDefault(value, target, type);\n nextProperties.push(entry);\n }\n\n object.properties = nextProperties;\n}\n\nfunction applyProviderToolConfig(\n object: t.ObjectExpression,\n execute: t.ObjectProperty | t.ObjectMethod,\n toolName: string | undefined,\n filename: string | undefined,\n): void {\n if (\n !t.isObjectProperty(execute) ||\n !t.isCallExpression(execute.value) ||\n execute.value.arguments.length !== 1 ||\n !t.isObjectExpression(execute.value.arguments[0])\n ) {\n throw new GenerativeCompileError(\n \"`providerTool(...)` must receive an inline object literal\",\n filename,\n );\n }\n\n const existingNames = new Set(\n object.properties.flatMap((prop) => {\n if (!t.isObjectProperty(prop) && !t.isObjectMethod(prop)) return [];\n const name = memberName(prop.key, prop.computed);\n return name ? [name] : [];\n }),\n );\n const configNames = new Set<string>();\n\n for (const prop of execute.value.arguments[0].properties) {\n if (!t.isObjectProperty(prop)) {\n throw new GenerativeCompileError(\n \"`providerTool(...)` config can only contain object properties\",\n filename,\n );\n }\n const name = memberName(prop.key, prop.computed);\n if (!name) {\n throw new GenerativeCompileError(\n \"`providerTool(...)` config can only contain static property names\",\n filename,\n );\n }\n if (\n t.isFunctionExpression(prop.value) ||\n t.isArrowFunctionExpression(prop.value)\n ) {\n throw new GenerativeCompileError(\n \"`providerTool(...)` config cannot contain function-valued properties\",\n filename,\n );\n }\n if (existingNames.has(name) || configNames.has(name)) {\n const toolLabel = toolName ? ` for \"${toolName}\"` : \"\";\n throw new GenerativeCompileError(\n `\\`providerTool(...)\\` config${toolLabel} duplicates \"${name}\"`,\n filename,\n );\n }\n configNames.add(name);\n object.properties.push(prop);\n }\n}\n\ntype Entry = t.ObjectExpression[\"properties\"][number];\n\n/** The raw AST value of an entry (any expression), or null for spreads/methods. */\nfunction entryRawValue(entry: Entry): t.Expression | null {\n if (t.isObjectProperty(entry) && t.isExpression(entry.value)) {\n return entry.value;\n }\n return null;\n}\n\nfunction entryValue(entry: Entry): t.ObjectExpression | null {\n if (t.isObjectProperty(entry) && t.isObjectExpression(entry.value)) {\n return entry.value;\n }\n return null;\n}\n\n/** A member of an entry object: `render`/`execute`/`type`, as property or method. */\nfunction findMember(\n object: t.ObjectExpression,\n name: string,\n): t.ObjectProperty | t.ObjectMethod | undefined {\n return object.properties.find(\n (p): p is t.ObjectProperty | t.ObjectMethod =>\n (t.isObjectProperty(p) || t.isObjectMethod(p)) &&\n memberName(p.key, p.computed) === name,\n );\n}\n\nfunction removeMember(object: t.ObjectExpression, name: string): void {\n object.properties = object.properties.filter(\n (p) =>\n !(\n (t.isObjectProperty(p) || t.isObjectMethod(p)) &&\n memberName(p.key, p.computed) === name\n ),\n );\n}\n\n/** The `BlockStatement` body of an `execute` member, if it has one. */\nfunction executeBody(\n member: t.ObjectProperty | t.ObjectMethod,\n): t.BlockStatement | undefined {\n if (t.isObjectMethod(member)) return member.body;\n const value = member.value;\n if (\n (t.isArrowFunctionExpression(value) || t.isFunctionExpression(value)) &&\n t.isBlockStatement(value.body)\n ) {\n return value.body;\n }\n return undefined;\n}\n\n/** Whether an `execute` opts into the client via a leading `\"use client\"`. */\nfunction executeIsClient(member: t.ObjectProperty | t.ObjectMethod): boolean {\n return !!executeBody(member)?.directives.some(\n (d) => d.value.value === \"use client\",\n );\n}\n\nfunction executeIsSentinel(\n member: t.ObjectProperty | t.ObjectMethod,\n name: string,\n): boolean {\n return (\n t.isObjectProperty(member) &&\n t.isCallExpression(member.value) &&\n t.isIdentifier(member.value.callee, { name })\n );\n}\n\n/** Whether an `execute` is the human-in-the-loop sentinel. */\nfunction executeIsHumanTool(\n member: t.ObjectProperty | t.ObjectMethod,\n): boolean {\n return (\n executeIsSentinel(member, \"humanTool\") ||\n executeIsSentinel(member, \"hitlTool\") ||\n executeIsSentinel(member, \"hitl\")\n );\n}\n\n/** Whether an `execute` is the provider-tool sentinel. */\nfunction executeIsProviderTool(\n member: t.ObjectProperty | t.ObjectMethod,\n): boolean {\n return executeIsSentinel(member, \"providerTool\");\n}\n\n/** Whether an `execute` is the local override sentinel. */\nfunction executeIsStubTool(member: t.ObjectProperty | t.ObjectMethod): boolean {\n return executeIsSentinel(member, \"stubTool\");\n}\n\n/** Whether an `execute` is the externally-defined backend tool sentinel. */\nfunction executeIsExternalTool(\n member: t.ObjectProperty | t.ObjectMethod,\n): boolean {\n return executeIsSentinel(member, \"externalTool\");\n}\n\n/** Drops the `\"use client\"` directive from an `execute` body (kept frontend). */\nfunction stripUseClient(member: t.ObjectProperty | t.ObjectMethod): void {\n const body = executeBody(member);\n if (body) {\n body.directives = body.directives.filter(\n (d) => d.value.value !== \"use client\",\n );\n }\n}\n\n/**\n * The tool's nature, inferred from its (mandatory) `execute` rather than an\n * authored `type`: `humanTool()` → `human`; `providerTool(...)` → `provider`;\n * `stubTool()` → `frontend`; `externalTool()` → `backend`; `\"use client\"` →\n * `frontend`; otherwise `backend`.\n * The loader writes the result back as a `type` field (see {@link setToolType})\n * so the runtime keeps it.\n */\nfunction inferToolType(\n object: t.ObjectExpression,\n toolName: string | undefined,\n filename: string | undefined,\n): ToolType {\n const execute = findMember(object, \"execute\");\n if (!execute) {\n throw new GenerativeCompileError(\n `${toolSubject(toolName)} must declare an \\`execute\\`; use ` +\n \"`humanTool()` for a human-in-the-loop tool\",\n filename,\n );\n }\n if (executeIsHumanTool(execute)) return \"human\";\n if (executeIsProviderTool(execute)) return \"provider\";\n if (executeIsStubTool(execute)) return \"frontend\";\n if (executeIsExternalTool(execute)) return \"backend\";\n return executeIsClient(execute) ? \"frontend\" : \"backend\";\n}\n\nfunction toolSubject(toolName: string | undefined): string {\n return toolName ? `tool \"${toolName}\"` : \"every tool\";\n}\n\nfunction typedToolSubject(type: string, toolName: string | undefined): string {\n if (toolName) return `${type} tool \"${toolName}\"`;\n const article = /^[aeiou]/i.test(type) ? \"an\" : \"a\";\n return `${article} ${type} tool`;\n}\n\nfunction stripExternalToolMetadata(object: t.ObjectExpression): void {\n // Mirror BackendTool's forbidden metadata fields: execute is stripped by the\n // main routing loop, while streamCall is also removed because there is no\n // assistant-ui executor to stream from.\n removeMember(object, \"description\");\n removeMember(object, \"parameters\");\n removeMember(object, \"disabled\");\n removeMember(object, \"toModelOutput\");\n removeMember(object, \"experimental_onSchemaValidationError\");\n removeMember(object, \"providerOptions\");\n removeMember(object, \"streamCall\");\n}\n\n/** Writes the resolved `type` back onto the tool object (replacing any author's). */\nfunction setToolType(object: t.ObjectExpression, type: ToolType): void {\n removeMember(object, \"type\");\n // Append (not prepend) so the inferred type wins over any earlier spread.\n object.properties.push(\n t.objectProperty(t.identifier(\"type\"), t.stringLiteral(type)),\n );\n}\n\nfunction setBackendDefault(\n object: t.ObjectExpression,\n target: Target,\n type: ToolType,\n): void {\n // Always strip any hand-authored marker first; only re-add it for client\n // frontend/human tools whose schema is already known by the backend.\n removeMember(object, \"unstable_backendDefault\");\n if (target !== \"client\" || (type !== \"frontend\" && type !== \"human\")) return;\n\n object.properties.push(\n t.objectProperty(\n t.identifier(\"unstable_backendDefault\"),\n t.objectExpression([\n t.objectProperty(t.identifier(\"parameters\"), t.booleanLiteral(true)),\n ]),\n ),\n );\n}\n\nfunction memberName(\n key: t.Node,\n computed: boolean | undefined,\n): string | undefined {\n if (computed) return undefined;\n if (t.isIdentifier(key)) return key.name;\n if (t.isStringLiteral(key)) return key.value;\n return undefined;\n}\n\n/**\n * Removes declarations and import specifiers left unreferenced after region\n * removal, to a fixpoint (a dropped helper frees what it used). Keeps exports,\n * side-effect imports, and possibly-side-effectful initializers.\n */\nfunction pruneUnused(ast: t.File): void {\n const hadSpecifiers = new WeakSet<t.ImportDeclaration>();\n for (const stmt of ast.program.body) {\n if (t.isImportDeclaration(stmt) && stmt.specifiers.length > 0) {\n hadSpecifiers.add(stmt);\n }\n }\n\n let removedSomething = true;\n while (removedSomething) {\n removedSomething = false;\n traverse(ast, {\n Program(path: NodePath<t.Program>) {\n path.scope.crawl();\n const isUnused = (name: string): boolean => {\n const binding = path.scope.getBinding(name);\n return !!binding && !binding.referenced;\n };\n\n path.node.body = path.node.body.filter((stmt) => {\n if (\n (t.isFunctionDeclaration(stmt) || t.isClassDeclaration(stmt)) &&\n stmt.id &&\n isUnused(stmt.id.name)\n ) {\n removedSomething = true;\n return false;\n }\n if (t.isVariableDeclaration(stmt)) {\n stmt.declarations = stmt.declarations.filter((decl) => {\n // Handles destructuring too: drop the declarator only when *every*\n // bound name is unused (else a `const { a } = server` survives and\n // keeps a server import in the client graph). Restricted to plain\n // patterns so a default/computed-key side effect isn't dropped.\n const names = Object.keys(t.getBindingIdentifiers(decl.id));\n if (\n names.length > 0 &&\n isPlainPattern(decl.id) &&\n isRemovableInit(decl.init) &&\n names.every(isUnused)\n ) {\n removedSomething = true;\n return false;\n }\n return true;\n });\n if (stmt.declarations.length === 0) return false;\n }\n return true;\n });\n path.stop();\n },\n });\n }\n\n traverse(ast, {\n Program(path: NodePath<t.Program>) {\n path.scope.crawl();\n for (const stmt of path.node.body) {\n if (!t.isImportDeclaration(stmt)) continue;\n stmt.specifiers = stmt.specifiers.filter((spec) => {\n const binding = path.scope.getBinding(spec.local.name);\n return binding ? binding.referenced : true;\n });\n }\n path.node.body = path.node.body.filter(\n (stmt) =>\n !(\n t.isImportDeclaration(stmt) &&\n stmt.specifiers.length === 0 &&\n hadSpecifiers.has(stmt)\n ),\n );\n path.stop();\n },\n });\n}\n\n/**\n * Whether a binding pattern is side-effect-free to drop: a plain identifier, or\n * an object/array pattern of plain bindings — no default values\n * (`{ a = expr }`) or computed keys (`{ [expr]: a }`), which would evaluate (and\n * thus could have side effects) at destructuring time.\n */\nfunction isPlainPattern(node: t.Node): boolean {\n if (t.isIdentifier(node)) return true;\n if (t.isObjectPattern(node)) {\n return node.properties.every((p) =>\n t.isRestElement(p)\n ? isPlainPattern(p.argument)\n : !p.computed && isPlainPattern(p.value),\n );\n }\n if (t.isArrayPattern(node)) {\n return node.elements.every((el) => el == null || isPlainPattern(el));\n }\n return false; // AssignmentPattern (default), member expr, etc.\n}\n\n/** Whether a variable initializer is safe to drop (no observable side effects). */\nfunction isRemovableInit(node: t.Expression | null | undefined): boolean {\n if (node == null) return true;\n if (t.isTSAsExpression(node) || t.isTSSatisfiesExpression(node)) {\n return isRemovableInit(node.expression);\n }\n // Containers are removable only if every element is — a nested call (e.g.\n // `[track()]`) has an observable side effect that dropping would lose.\n if (t.isArrayExpression(node)) {\n return node.elements.every(\n (el) => el == null || (t.isExpression(el) && isRemovableInit(el)),\n );\n }\n if (t.isObjectExpression(node)) {\n return node.properties.every(\n (p) =>\n t.isObjectProperty(p) &&\n !p.computed &&\n t.isExpression(p.value) &&\n isRemovableInit(p.value),\n );\n }\n if (t.isTemplateLiteral(node)) {\n return node.expressions.every(\n (e) => t.isExpression(e) && isRemovableInit(e),\n );\n }\n return (\n t.isArrowFunctionExpression(node) ||\n t.isFunctionExpression(node) ||\n t.isClassExpression(node) ||\n t.isIdentifier(node) ||\n // non-computed only — `obj[fn()]` could hide a side-effectful key\n (t.isMemberExpression(node) && !node.computed) ||\n t.isJSXElement(node) ||\n t.isJSXFragment(node) ||\n t.isLiteral(node)\n );\n}\n"],"mappings":"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"}
|
package/dist/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/x-generative-compiler",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.8",
|
|
5
5
|
"description": "Internal: the framework-agnostic \"use generative\" compiler that splits a colocated tool (schema + server-only execute + client-only render) into per-target builds. Shared by @assistant-ui/next and @assistant-ui/vite.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"assistant-ui",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@types/node": "^26.0.0",
|
|
42
42
|
"@types/semver": "^7.7.1",
|
|
43
43
|
"vitest": "^4.1.9",
|
|
44
|
-
"@assistant-ui/x-buildutils": "0.0.
|
|
44
|
+
"@assistant-ui/x-buildutils": "0.0.17"
|
|
45
45
|
},
|
|
46
46
|
"publishConfig": {
|
|
47
47
|
"access": "public",
|
package/src/compile.test.ts
CHANGED
|
@@ -358,6 +358,21 @@ export default defineToolkit({
|
|
|
358
358
|
expect(code).not.toContain("defineGenerativeComponents");
|
|
359
359
|
});
|
|
360
360
|
|
|
361
|
+
it("allows an exported module-scope JSONGenerativeUI instance", () => {
|
|
362
|
+
const src = `"use generative";
|
|
363
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
364
|
+
import { JSONGenerativeUI } from "@assistant-ui/react-generative-ui";
|
|
365
|
+
export const ui = new JSONGenerativeUI({ library: {} });
|
|
366
|
+
export default defineToolkit({ present: ui.present() });`;
|
|
367
|
+
|
|
368
|
+
expect(compileGenerative(src, { target: "server" }).code).toContain(
|
|
369
|
+
"ui.present()",
|
|
370
|
+
);
|
|
371
|
+
expect(compileGenerative(src, { target: "client" }).code).toContain(
|
|
372
|
+
"ui.present()",
|
|
373
|
+
);
|
|
374
|
+
});
|
|
375
|
+
|
|
361
376
|
it("rejects an unknown method on a JSONGenerativeUI instance", () => {
|
|
362
377
|
const src = `"use generative";
|
|
363
378
|
import { defineToolkit } from "@assistant-ui/react";
|
|
@@ -369,6 +384,37 @@ export default defineToolkit({ present: ui.notARealMethod() });`;
|
|
|
369
384
|
);
|
|
370
385
|
});
|
|
371
386
|
|
|
387
|
+
it("allows an aliased JSONGenerativeUI import", () => {
|
|
388
|
+
const src = `"use generative";
|
|
389
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
390
|
+
import { JSONGenerativeUI as GenUI } from "@assistant-ui/react-generative-ui";
|
|
391
|
+
const ui = new GenUI({ library: {} });
|
|
392
|
+
export default defineToolkit({ present: ui.present() });`;
|
|
393
|
+
|
|
394
|
+
expect(compileGenerative(src, { target: "server" }).code).toContain(
|
|
395
|
+
"ui.present()",
|
|
396
|
+
);
|
|
397
|
+
expect(compileGenerative(src, { target: "client" }).code).toContain(
|
|
398
|
+
"ui.present()",
|
|
399
|
+
);
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
it("does not trust a local class named JSONGenerativeUI", () => {
|
|
403
|
+
const src = `"use generative";
|
|
404
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
405
|
+
class JSONGenerativeUI {
|
|
406
|
+
present() {
|
|
407
|
+
return makeTool();
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
const ui = new JSONGenerativeUI();
|
|
411
|
+
export default defineToolkit({ present: ui.present() });`;
|
|
412
|
+
|
|
413
|
+
expect(() => compileGenerative(src, { target: "server" })).toThrow(
|
|
414
|
+
/tool "present" cannot be `ui\.present\(\)`/,
|
|
415
|
+
);
|
|
416
|
+
});
|
|
417
|
+
|
|
372
418
|
it("rejects a method call on an unknown (non-JSONGenerativeUI) object", () => {
|
|
373
419
|
const src = `"use generative";
|
|
374
420
|
import { defineToolkit } from "@assistant-ui/react";
|
|
@@ -1163,7 +1209,16 @@ export default defineToolkit({
|
|
|
1163
1209
|
`"use generative";\nimport { defineToolkit, externalTool } from "@assistant-ui/react";\nexport default defineToolkit({ search: { execute: externalTool() } });`,
|
|
1164
1210
|
{ target: "client" },
|
|
1165
1211
|
),
|
|
1166
|
-
).toThrow(/external tool must declare a `render` or `renderText`/);
|
|
1212
|
+
).toThrow(/external tool "search" must declare a `render` or `renderText`/);
|
|
1213
|
+
});
|
|
1214
|
+
|
|
1215
|
+
it("falls back to an unnamed external tool diagnostic for computed keys", () => {
|
|
1216
|
+
expect(() =>
|
|
1217
|
+
compileGenerative(
|
|
1218
|
+
`"use generative";\nimport { defineToolkit, externalTool } from "@assistant-ui/react";\nconst search = "search";\nexport default defineToolkit({ [search]: { execute: externalTool() } });`,
|
|
1219
|
+
{ target: "client" },
|
|
1220
|
+
),
|
|
1221
|
+
).toThrow(/an external tool must declare a `render` or `renderText`/);
|
|
1167
1222
|
});
|
|
1168
1223
|
});
|
|
1169
1224
|
|
|
@@ -1289,7 +1344,7 @@ export default { weather: { execute: async () => 1, render: () => null } };`;
|
|
|
1289
1344
|
`"use generative";\nimport { defineToolkit } from "@assistant-ui/react";\nexport default defineToolkit({ weather: makeTool() });`,
|
|
1290
1345
|
{ target: "server" },
|
|
1291
1346
|
),
|
|
1292
|
-
).toThrow(/
|
|
1347
|
+
).toThrow(/tool "weather" cannot be `makeTool\(\)`/);
|
|
1293
1348
|
});
|
|
1294
1349
|
|
|
1295
1350
|
it("requires a render for human tools", () => {
|
|
@@ -1298,7 +1353,16 @@ export default { weather: { execute: async () => 1, render: () => null } };`;
|
|
|
1298
1353
|
`"use generative";\nimport { defineToolkit, humanTool } from "@assistant-ui/react";\nexport default defineToolkit({ ask: { execute: humanTool() } });`,
|
|
1299
1354
|
{ target: "client" },
|
|
1300
1355
|
),
|
|
1301
|
-
).toThrow(/must declare a `render`/);
|
|
1356
|
+
).toThrow(/human tool "ask" must declare a `render`/);
|
|
1357
|
+
});
|
|
1358
|
+
|
|
1359
|
+
it("falls back to an unnamed human tool diagnostic for computed keys", () => {
|
|
1360
|
+
expect(() =>
|
|
1361
|
+
compileGenerative(
|
|
1362
|
+
`"use generative";\nimport { defineToolkit, humanTool } from "@assistant-ui/react";\nconst ask = "ask";\nexport default defineToolkit({ [ask]: { execute: humanTool() } });`,
|
|
1363
|
+
{ target: "client" },
|
|
1364
|
+
),
|
|
1365
|
+
).toThrow(/a human tool must declare a `render`/);
|
|
1302
1366
|
});
|
|
1303
1367
|
|
|
1304
1368
|
it("requires a render or renderText for frontend tools", () => {
|
|
@@ -1307,7 +1371,16 @@ export default { weather: { execute: async () => 1, render: () => null } };`;
|
|
|
1307
1371
|
`"use generative";\nimport { defineToolkit } from "@assistant-ui/react";\nexport default defineToolkit({ toast: { execute: async () => { "use client"; return 1; } } });`,
|
|
1308
1372
|
{ target: "client" },
|
|
1309
1373
|
),
|
|
1310
|
-
).toThrow(/must declare a `render` or `renderText`/);
|
|
1374
|
+
).toThrow(/frontend tool "toast" must declare a `render` or `renderText`/);
|
|
1375
|
+
});
|
|
1376
|
+
|
|
1377
|
+
it("falls back to an unnamed frontend tool diagnostic for computed keys", () => {
|
|
1378
|
+
expect(() =>
|
|
1379
|
+
compileGenerative(
|
|
1380
|
+
`"use generative";\nimport { defineToolkit } from "@assistant-ui/react";\nconst toast = "toast";\nexport default defineToolkit({ [toast]: { execute: async () => { "use client"; return 1; } } });`,
|
|
1381
|
+
{ target: "client" },
|
|
1382
|
+
),
|
|
1383
|
+
).toThrow(/a frontend tool must declare a `render` or `renderText`/);
|
|
1311
1384
|
});
|
|
1312
1385
|
|
|
1313
1386
|
it("requires every tool to declare an execute", () => {
|
|
@@ -1316,7 +1389,16 @@ export default { weather: { execute: async () => 1, render: () => null } };`;
|
|
|
1316
1389
|
`"use generative";\nimport { defineToolkit } from "@assistant-ui/react";\nexport default defineToolkit({ ask: { render: () => null } });`,
|
|
1317
1390
|
{ target: "client" },
|
|
1318
1391
|
),
|
|
1319
|
-
).toThrow(/must declare an `execute`/);
|
|
1392
|
+
).toThrow(/tool "ask" must declare an `execute`/);
|
|
1393
|
+
});
|
|
1394
|
+
|
|
1395
|
+
it("falls back to an unnamed execute diagnostic for computed keys", () => {
|
|
1396
|
+
expect(() =>
|
|
1397
|
+
compileGenerative(
|
|
1398
|
+
`"use generative";\nimport { defineToolkit } from "@assistant-ui/react";\nconst ask = "ask";\nexport default defineToolkit({ [ask]: { render: () => null } });`,
|
|
1399
|
+
{ target: "client" },
|
|
1400
|
+
),
|
|
1401
|
+
).toThrow(/every tool must declare an `execute`/);
|
|
1320
1402
|
});
|
|
1321
1403
|
|
|
1322
1404
|
it("infers `human` from execute: humanTool() and drops it on both builds", () => {
|
package/src/compile.ts
CHANGED
|
@@ -37,6 +37,8 @@ const DISTRIBUTION_PACKAGES = [
|
|
|
37
37
|
"@assistant-ui/react-native",
|
|
38
38
|
"@assistant-ui/react-ink",
|
|
39
39
|
] as const;
|
|
40
|
+
/** Package that exports the generative UI runtime split by export condition. */
|
|
41
|
+
const GENERATIVE_UI_PACKAGE = "@assistant-ui/react-generative-ui";
|
|
40
42
|
/**
|
|
41
43
|
* The class whose instances expose split-by-condition tools (`present()`,
|
|
42
44
|
* `promptUser()`). A toolkit entry that calls a method on one of these passes
|
|
@@ -600,14 +602,22 @@ function unwrapToCall(node: t.Node, name: string): t.CallExpression | null {
|
|
|
600
602
|
*/
|
|
601
603
|
function collectGenerativeInstances(ast: t.File): Set<string> {
|
|
602
604
|
const names = new Set<string>();
|
|
605
|
+
const generativeFactories = collectGenerativeFactoryImports(ast);
|
|
603
606
|
for (const statement of ast.program.body) {
|
|
604
|
-
|
|
605
|
-
|
|
607
|
+
const variableDeclaration = t.isVariableDeclaration(statement)
|
|
608
|
+
? statement
|
|
609
|
+
: t.isExportNamedDeclaration(statement) &&
|
|
610
|
+
t.isVariableDeclaration(statement.declaration)
|
|
611
|
+
? statement.declaration
|
|
612
|
+
: null;
|
|
613
|
+
if (!variableDeclaration) continue;
|
|
614
|
+
for (const declaration of variableDeclaration.declarations) {
|
|
606
615
|
const { id, init } = declaration;
|
|
607
616
|
if (
|
|
608
617
|
t.isIdentifier(id) &&
|
|
609
618
|
t.isNewExpression(init) &&
|
|
610
|
-
t.isIdentifier(init.callee
|
|
619
|
+
t.isIdentifier(init.callee) &&
|
|
620
|
+
generativeFactories.has(init.callee.name)
|
|
611
621
|
) {
|
|
612
622
|
names.add(id.name);
|
|
613
623
|
}
|
|
@@ -616,6 +626,28 @@ function collectGenerativeInstances(ast: t.File): Set<string> {
|
|
|
616
626
|
return names;
|
|
617
627
|
}
|
|
618
628
|
|
|
629
|
+
function collectGenerativeFactoryImports(ast: t.File): Set<string> {
|
|
630
|
+
const names = new Set<string>();
|
|
631
|
+
for (const statement of ast.program.body) {
|
|
632
|
+
if (
|
|
633
|
+
!t.isImportDeclaration(statement) ||
|
|
634
|
+
statement.source.value !== GENERATIVE_UI_PACKAGE
|
|
635
|
+
) {
|
|
636
|
+
continue;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
for (const specifier of statement.specifiers) {
|
|
640
|
+
if (
|
|
641
|
+
t.isImportSpecifier(specifier) &&
|
|
642
|
+
t.isIdentifier(specifier.imported, { name: GENERATIVE_FACTORY })
|
|
643
|
+
) {
|
|
644
|
+
names.add(specifier.local.name);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
return names;
|
|
649
|
+
}
|
|
650
|
+
|
|
619
651
|
type ToolkitStaticNames = readonly string[] | null;
|
|
620
652
|
type ToolkitSpreadNames = Map<string, ToolkitStaticNames>;
|
|
621
653
|
|
|
@@ -1151,6 +1183,30 @@ function isSafeToolkitSpread(
|
|
|
1151
1183
|
);
|
|
1152
1184
|
}
|
|
1153
1185
|
|
|
1186
|
+
function genericUnsafeToolkitEntryMessage(): string {
|
|
1187
|
+
return (
|
|
1188
|
+
"each tool must be an inline object literal (`name: { ... }`) or a " +
|
|
1189
|
+
"compiler-visible toolkit spread / generative tool (e.g. " +
|
|
1190
|
+
"`...defineMcpToolkit(...)`, `...baseToolkit`, " +
|
|
1191
|
+
"`generative.present()`, or `unstable_interactableTool(...)`) so its " +
|
|
1192
|
+
"`execute` can be routed"
|
|
1193
|
+
);
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
function describeUnsafeToolkitEntry(entry: Entry): string {
|
|
1197
|
+
if (!t.isObjectProperty(entry)) return genericUnsafeToolkitEntryMessage();
|
|
1198
|
+
|
|
1199
|
+
const toolName = memberName(entry.key, entry.computed);
|
|
1200
|
+
const raw = entryRawValue(entry);
|
|
1201
|
+
if (!toolName || !raw) return genericUnsafeToolkitEntryMessage();
|
|
1202
|
+
|
|
1203
|
+
return (
|
|
1204
|
+
`tool "${toolName}" cannot be \`${generate(raw).code}\`; use an inline ` +
|
|
1205
|
+
`object literal (\`${toolName}: { ... }\`) or a compiler-visible toolkit ` +
|
|
1206
|
+
"spread / generative tool so its `execute` can be routed"
|
|
1207
|
+
);
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1154
1210
|
/** The `JSONGenerativeUI` methods that produce a split-by-condition tool. */
|
|
1155
1211
|
const GENERATIVE_TOOL_METHODS = new Set(["present", "promptUser"]);
|
|
1156
1212
|
|
|
@@ -1252,27 +1308,27 @@ function compileToolkit(
|
|
|
1252
1308
|
continue;
|
|
1253
1309
|
}
|
|
1254
1310
|
throw new GenerativeCompileError(
|
|
1255
|
-
|
|
1256
|
-
"compiler-visible toolkit spread / generative tool (e.g. " +
|
|
1257
|
-
"`...defineMcpToolkit(...)`, `...baseToolkit`, " +
|
|
1258
|
-
"`generative.present()`, or `unstable_interactableTool(...)`) so its " +
|
|
1259
|
-
"`execute` can be routed",
|
|
1311
|
+
describeUnsafeToolkitEntry(entry),
|
|
1260
1312
|
filename,
|
|
1261
1313
|
);
|
|
1262
1314
|
}
|
|
1263
1315
|
|
|
1264
1316
|
// Nature is inferred from `execute` (see inferToolType), not an authored
|
|
1265
1317
|
// `type`. The resolved type is written back below so the runtime keeps it.
|
|
1318
|
+
const toolName = t.isObjectProperty(entry)
|
|
1319
|
+
? memberName(entry.key, entry.computed)
|
|
1320
|
+
: undefined;
|
|
1266
1321
|
const execute = findMember(value, "execute");
|
|
1267
1322
|
const isStub = execute ? executeIsStubTool(execute) : false;
|
|
1268
1323
|
const isExternal = execute ? executeIsExternalTool(execute) : false;
|
|
1269
|
-
const type = inferToolType(value, filename);
|
|
1324
|
+
const type = inferToolType(value, toolName, filename);
|
|
1270
1325
|
const hasRender = !!findMember(value, "render");
|
|
1271
1326
|
const hasRenderText = !!findMember(value, "renderText");
|
|
1272
1327
|
|
|
1273
1328
|
if (type === "frontend" && !hasRender && !hasRenderText) {
|
|
1274
1329
|
throw new GenerativeCompileError(
|
|
1275
|
-
"
|
|
1330
|
+
`${typedToolSubject("frontend", toolName)} must declare a ` +
|
|
1331
|
+
"`render` or `renderText` " +
|
|
1276
1332
|
"(it has no server execute to show otherwise)",
|
|
1277
1333
|
filename,
|
|
1278
1334
|
);
|
|
@@ -1280,22 +1336,21 @@ function compileToolkit(
|
|
|
1280
1336
|
|
|
1281
1337
|
if (type === "human" && !hasRender) {
|
|
1282
1338
|
throw new GenerativeCompileError(
|
|
1283
|
-
"
|
|
1339
|
+
`${typedToolSubject("human", toolName)} must declare a ` +
|
|
1340
|
+
"`render` so it can collect input",
|
|
1284
1341
|
filename,
|
|
1285
1342
|
);
|
|
1286
1343
|
}
|
|
1287
1344
|
|
|
1288
1345
|
if (type === "provider" && execute) {
|
|
1289
|
-
const toolName = t.isObjectProperty(entry)
|
|
1290
|
-
? memberName(entry.key, entry.computed)
|
|
1291
|
-
: undefined;
|
|
1292
1346
|
applyProviderToolConfig(value, execute, toolName, filename);
|
|
1293
1347
|
}
|
|
1294
1348
|
|
|
1295
1349
|
if (isExternal) {
|
|
1296
1350
|
if (!hasRender && !hasRenderText) {
|
|
1297
1351
|
throw new GenerativeCompileError(
|
|
1298
|
-
"
|
|
1352
|
+
`${typedToolSubject("external", toolName)} must declare a ` +
|
|
1353
|
+
"`render` or `renderText` " +
|
|
1299
1354
|
"(assistant-ui only renders calls for tools defined elsewhere)",
|
|
1300
1355
|
filename,
|
|
1301
1356
|
);
|
|
@@ -1512,13 +1567,14 @@ function stripUseClient(member: t.ObjectProperty | t.ObjectMethod): void {
|
|
|
1512
1567
|
*/
|
|
1513
1568
|
function inferToolType(
|
|
1514
1569
|
object: t.ObjectExpression,
|
|
1570
|
+
toolName: string | undefined,
|
|
1515
1571
|
filename: string | undefined,
|
|
1516
1572
|
): ToolType {
|
|
1517
1573
|
const execute = findMember(object, "execute");
|
|
1518
1574
|
if (!execute) {
|
|
1519
1575
|
throw new GenerativeCompileError(
|
|
1520
|
-
|
|
1521
|
-
"human-in-the-loop tool",
|
|
1576
|
+
`${toolSubject(toolName)} must declare an \`execute\`; use ` +
|
|
1577
|
+
"`humanTool()` for a human-in-the-loop tool",
|
|
1522
1578
|
filename,
|
|
1523
1579
|
);
|
|
1524
1580
|
}
|
|
@@ -1529,6 +1585,16 @@ function inferToolType(
|
|
|
1529
1585
|
return executeIsClient(execute) ? "frontend" : "backend";
|
|
1530
1586
|
}
|
|
1531
1587
|
|
|
1588
|
+
function toolSubject(toolName: string | undefined): string {
|
|
1589
|
+
return toolName ? `tool "${toolName}"` : "every tool";
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
function typedToolSubject(type: string, toolName: string | undefined): string {
|
|
1593
|
+
if (toolName) return `${type} tool "${toolName}"`;
|
|
1594
|
+
const article = /^[aeiou]/i.test(type) ? "an" : "a";
|
|
1595
|
+
return `${article} ${type} tool`;
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1532
1598
|
function stripExternalToolMetadata(object: t.ObjectExpression): void {
|
|
1533
1599
|
// Mirror BackendTool's forbidden metadata fields: execute is stripped by the
|
|
1534
1600
|
// main routing loop, while streamCall is also removed because there is no
|