@agent-native/core 0.75.2 → 0.75.4
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +46 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/durable-background.ts +29 -31
- package/corpus/core/src/agent/production-agent.ts +12 -13
- package/corpus/core/src/cli/sync-builder-starter-manifest.ts +36 -12
- package/corpus/core/src/deploy/build.ts +145 -57
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +6 -20
- package/corpus/templates/plan/app/components/plan/DocumentArea.tsx +45 -33
- package/corpus/templates/plan/changelog/2026-06-24-invalid-generated-recap-blocks-now-show-a-clear-warning-with.md +6 -0
- package/corpus/templates/plan/server/plan-content.ts +53 -3
- package/dist/agent/durable-background.d.ts +29 -24
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +29 -29
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +12 -13
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/sync-builder-starter-manifest.d.ts.map +1 -1
- package/dist/cli/sync-builder-starter-manifest.js +21 -10
- package/dist/cli/sync-builder-starter-manifest.js.map +1 -1
- package/dist/deploy/build.d.ts +57 -33
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +136 -57
- package/dist/deploy/build.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-builder-starter-manifest.d.ts","sourceRoot":"","sources":["../../src/cli/sync-builder-starter-manifest.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,gBAAgB,iCAAiC,CAAC;AAC/D,eAAO,MAAM,aAAa,SAAS,CAAC;AAEpC,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3C,wBAAgB,mBAAmB,CAAC,QAAQ,SAAgB,GAAG,MAAM,CAmBpE;AAED,wBAAgB,8BAA8B,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG;IACjE,WAAW,EAAE,WAAW,CAAC;IACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAwBA;
|
|
1
|
+
{"version":3,"file":"sync-builder-starter-manifest.d.ts","sourceRoot":"","sources":["../../src/cli/sync-builder-starter-manifest.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,gBAAgB,iCAAiC,CAAC;AAC/D,eAAO,MAAM,aAAa,SAAS,CAAC;AAEpC,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3C,wBAAgB,mBAAmB,CAAC,QAAQ,SAAgB,GAAG,MAAM,CAmBpE;AAED,wBAAgB,8BAA8B,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG;IACjE,WAAW,EAAE,WAAW,CAAC;IACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAwBA;AAsBD,wBAAgB,oBAAoB,CAClC,kBAAkB,EAAE,WAAW,EAC/B,oBAAoB,EAAE,WAAW,GAChC,WAAW,CAgCb;AAED,wBAAgB,wBAAwB,CACtC,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAChC,kBAAkB,EAAE,MAAM,GAAG,IAAI,GAChC,OAAO,CAKT;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,kBAAkB,EAAE,MAAM,GAAG,IAAI,GAChC,IAAI,CAQN;AAMD,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IAChD,sBAAsB,EAAE,MAAM,CAAC;IAC/B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,yBAAyB,CA6C5B;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAC5D,OAAO,EAAE,OAAO,GAAG,UAAU,CAAC;IAC9B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CA0CA;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAmChE"}
|
|
@@ -37,6 +37,21 @@ export function generateStandaloneChatManifest(repoRoot) {
|
|
|
37
37
|
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
+
function mergePackageJsonRecords(canonical, starter, starterPinnedKeys = []) {
|
|
41
|
+
const merged = { ...(canonical ?? {}) };
|
|
42
|
+
for (const [key, value] of Object.entries(starter ?? {})) {
|
|
43
|
+
if (!(key in merged)) {
|
|
44
|
+
merged[key] = value;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
for (const key of starterPinnedKeys) {
|
|
48
|
+
const pinned = starter?.[key];
|
|
49
|
+
if (pinned) {
|
|
50
|
+
merged[key] = pinned;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return merged;
|
|
54
|
+
}
|
|
40
55
|
export function mergeStarterManifest(starterPackageJson, canonicalPackageJson) {
|
|
41
56
|
const merged = structuredClone(canonicalPackageJson);
|
|
42
57
|
merged.name = starterPackageJson.name ?? STARTER_APP_NAME;
|
|
@@ -49,16 +64,12 @@ export function mergeStarterManifest(starterPackageJson, canonicalPackageJson) {
|
|
|
49
64
|
if (starterPackageJson.private !== undefined) {
|
|
50
65
|
merged.private = starterPackageJson.private;
|
|
51
66
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
merged.
|
|
57
|
-
|
|
58
|
-
...(starterDeps["@agent-native/core"]
|
|
59
|
-
? { "@agent-native/core": starterDeps["@agent-native/core"] }
|
|
60
|
-
: {}),
|
|
61
|
-
};
|
|
67
|
+
if (typeof starterPackageJson.packageManager === "string") {
|
|
68
|
+
merged.packageManager = starterPackageJson.packageManager;
|
|
69
|
+
}
|
|
70
|
+
merged.dependencies = mergePackageJsonRecords(canonicalPackageJson.dependencies, starterPackageJson.dependencies, ["@agent-native/core"]);
|
|
71
|
+
merged.devDependencies = mergePackageJsonRecords(canonicalPackageJson.devDependencies, starterPackageJson.devDependencies);
|
|
72
|
+
merged.scripts = mergePackageJsonRecords(canonicalPackageJson.scripts, starterPackageJson.scripts);
|
|
62
73
|
return merged;
|
|
63
74
|
}
|
|
64
75
|
export function workspaceFileSyncChanged(existingWorkspace, canonicalWorkspace) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-builder-starter-manifest.js","sourceRoot":"","sources":["../../src/cli/sync-builder-starter-manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { _postProcessStandalone } from \"./create.js\";\n\nexport const STARTER_APP_NAME = \"builder-agent-native-starter\";\nexport const CHAT_TEMPLATE = \"chat\";\n\ntype PackageJson = Record<string, unknown>;\n\nexport function findAgentNativeRoot(startDir = process.cwd()): string {\n let dir = path.resolve(startDir);\n for (let i = 0; i < 12; i++) {\n const chatPackageJson = path.join(\n dir,\n \"templates\",\n CHAT_TEMPLATE,\n \"package.json\",\n );\n if (fs.existsSync(chatPackageJson)) {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error(\n \"Could not find agent-native repo root (expected templates/chat/package.json).\",\n );\n}\n\nexport function generateStandaloneChatManifest(repoRoot?: string): {\n packageJson: PackageJson;\n pnpmWorkspaceYaml: string | null;\n} {\n const root = repoRoot ?? findAgentNativeRoot();\n const chatTemplateDir = path.join(root, \"templates\", CHAT_TEMPLATE);\n const tempDir = fs.mkdtempSync(\n path.join(os.tmpdir(), \"an-builder-starter-sync-\"),\n );\n\n try {\n fs.cpSync(chatTemplateDir, tempDir, { recursive: true });\n _postProcessStandalone(STARTER_APP_NAME, tempDir, CHAT_TEMPLATE);\n\n const packageJson = JSON.parse(\n fs.readFileSync(path.join(tempDir, \"package.json\"), \"utf-8\"),\n ) as PackageJson;\n\n const workspacePath = path.join(tempDir, \"pnpm-workspace.yaml\");\n const pnpmWorkspaceYaml = fs.existsSync(workspacePath)\n ? fs.readFileSync(workspacePath, \"utf-8\")\n : null;\n\n return { packageJson, pnpmWorkspaceYaml };\n } finally {\n fs.rmSync(tempDir, { recursive: true, force: true });\n }\n}\n\nexport function mergeStarterManifest(\n starterPackageJson: PackageJson,\n canonicalPackageJson: PackageJson,\n): PackageJson {\n const merged = structuredClone(canonicalPackageJson) as PackageJson;\n\n merged.name = starterPackageJson.name ?? STARTER_APP_NAME;\n if (typeof starterPackageJson.displayName === \"string\") {\n merged.displayName = starterPackageJson.displayName;\n }\n if (typeof starterPackageJson.description === \"string\") {\n merged.description = starterPackageJson.description;\n }\n if (starterPackageJson.private !== undefined) {\n merged.private = starterPackageJson.private;\n }\n\n const starterDeps =\n (starterPackageJson.dependencies as Record<string, string> | undefined) ??\n {};\n const canonicalDeps =\n (canonicalPackageJson.dependencies as Record<string, string> | undefined) ??\n {};\n merged.dependencies = {\n ...canonicalDeps,\n ...(starterDeps[\"@agent-native/core\"]\n ? { \"@agent-native/core\": starterDeps[\"@agent-native/core\"] }\n : {}),\n };\n\n return merged;\n}\n\nexport function workspaceFileSyncChanged(\n existingWorkspace: string | null,\n canonicalWorkspace: string | null,\n): boolean {\n if (canonicalWorkspace === null) {\n return existingWorkspace !== null;\n }\n return existingWorkspace !== canonicalWorkspace;\n}\n\nexport function applyWorkspaceFileSync(\n targetPath: string,\n canonicalWorkspace: string | null,\n): void {\n if (canonicalWorkspace === null) {\n if (fs.existsSync(targetPath)) {\n fs.unlinkSync(targetPath);\n }\n return;\n }\n fs.writeFileSync(targetPath, canonicalWorkspace);\n}\n\nfunction stableJson(value: unknown): string {\n return `${JSON.stringify(value, null, 2)}\\n`;\n}\n\nexport type SyncStarterManifestResult = {\n changed: boolean;\n packageJson: PackageJson;\n pnpmWorkspaceYaml: string | null;\n};\n\nexport function syncStarterManifestFiles(options: {\n starterPackageJsonPath: string;\n starterPnpmWorkspacePath?: string;\n repoRoot?: string;\n write?: boolean;\n}): SyncStarterManifestResult {\n const { packageJson: canonical, pnpmWorkspaceYaml } =\n generateStandaloneChatManifest(options.repoRoot);\n\n const starterPackageJson = JSON.parse(\n fs.readFileSync(options.starterPackageJsonPath, \"utf-8\"),\n ) as PackageJson;\n const mergedPackageJson = mergeStarterManifest(starterPackageJson, canonical);\n\n let workspaceChanged = false;\n const existingWorkspace =\n options.starterPnpmWorkspacePath &&\n fs.existsSync(options.starterPnpmWorkspacePath)\n ? fs.readFileSync(options.starterPnpmWorkspacePath, \"utf-8\")\n : null;\n\n workspaceChanged = workspaceFileSyncChanged(\n existingWorkspace,\n pnpmWorkspaceYaml,\n );\n\n const packageChanged =\n stableJson(starterPackageJson) !== stableJson(mergedPackageJson);\n const changed = packageChanged || workspaceChanged;\n\n if (options.write && changed) {\n if (packageChanged) {\n fs.writeFileSync(\n options.starterPackageJsonPath,\n stableJson(mergedPackageJson),\n );\n }\n if (workspaceChanged && options.starterPnpmWorkspacePath) {\n applyWorkspaceFileSync(\n options.starterPnpmWorkspacePath,\n pnpmWorkspaceYaml,\n );\n }\n }\n\n return {\n changed,\n packageJson: mergedPackageJson,\n pnpmWorkspaceYaml,\n };\n}\n\nexport function parseSyncStarterManifestArgs(argv: string[]): {\n command: \"merge\" | \"generate\";\n starterPackageJsonPath?: string;\n starterPnpmWorkspacePath?: string;\n write: boolean;\n repoRoot?: string;\n} {\n const [commandRaw, ...rest] = argv;\n const command = commandRaw === \"generate\" ? \"generate\" : \"merge\";\n let starterPackageJsonPath: string | undefined;\n let starterPnpmWorkspacePath: string | undefined;\n let write = false;\n let repoRoot: string | undefined;\n\n for (let i = 0; i < rest.length; i++) {\n const arg = rest[i];\n if (arg === \"--write\") {\n write = true;\n continue;\n }\n if (arg === \"--starter-package-json\") {\n starterPackageJsonPath = rest[++i];\n continue;\n }\n if (arg === \"--starter-pnpm-workspace\") {\n starterPnpmWorkspacePath = rest[++i];\n continue;\n }\n if (arg === \"--repo-root\") {\n repoRoot = rest[++i];\n continue;\n }\n throw new Error(`Unknown argument: ${arg}`);\n }\n\n if (command === \"merge\" && !starterPackageJsonPath) {\n throw new Error(\n \"merge requires --starter-package-json <path> [--starter-pnpm-workspace <path>] [--write] [--repo-root <path>]\",\n );\n }\n\n return {\n command,\n starterPackageJsonPath,\n starterPnpmWorkspacePath,\n write,\n repoRoot,\n };\n}\n\nexport function runSyncStarterManifestCli(argv: string[]): number {\n const args = parseSyncStarterManifestArgs(argv);\n\n if (args.command === \"generate\") {\n const { packageJson, pnpmWorkspaceYaml } = generateStandaloneChatManifest(\n args.repoRoot,\n );\n process.stdout.write(stableJson(packageJson));\n if (pnpmWorkspaceYaml) {\n process.stdout.write(\"\\n--- pnpm-workspace.yaml ---\\n\");\n process.stdout.write(pnpmWorkspaceYaml);\n }\n return 0;\n }\n\n const result = syncStarterManifestFiles({\n starterPackageJsonPath: args.starterPackageJsonPath!,\n starterPnpmWorkspacePath: args.starterPnpmWorkspacePath,\n repoRoot: args.repoRoot,\n write: args.write,\n });\n\n if (result.changed) {\n console.log(\n args.write\n ? \"Updated builder-agent-native-starter manifest from templates/chat.\"\n : \"builder-agent-native-starter manifest is out of date with templates/chat.\",\n );\n return args.write ? 0 : 1;\n }\n\n console.log(\n \"builder-agent-native-starter manifest already matches templates/chat.\",\n );\n return 0;\n}\n\nconst isDirectRun =\n process.argv[1] &&\n path.resolve(process.argv[1]) ===\n path.resolve(fileURLToPath(import.meta.url));\n\nif (isDirectRun) {\n const exitCode = runSyncStarterManifestCli(process.argv.slice(2));\n process.exit(exitCode);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sync-builder-starter-manifest.js","sourceRoot":"","sources":["../../src/cli/sync-builder-starter-manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { _postProcessStandalone } from \"./create.js\";\n\nexport const STARTER_APP_NAME = \"builder-agent-native-starter\";\nexport const CHAT_TEMPLATE = \"chat\";\n\ntype PackageJson = Record<string, unknown>;\n\nexport function findAgentNativeRoot(startDir = process.cwd()): string {\n let dir = path.resolve(startDir);\n for (let i = 0; i < 12; i++) {\n const chatPackageJson = path.join(\n dir,\n \"templates\",\n CHAT_TEMPLATE,\n \"package.json\",\n );\n if (fs.existsSync(chatPackageJson)) {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error(\n \"Could not find agent-native repo root (expected templates/chat/package.json).\",\n );\n}\n\nexport function generateStandaloneChatManifest(repoRoot?: string): {\n packageJson: PackageJson;\n pnpmWorkspaceYaml: string | null;\n} {\n const root = repoRoot ?? findAgentNativeRoot();\n const chatTemplateDir = path.join(root, \"templates\", CHAT_TEMPLATE);\n const tempDir = fs.mkdtempSync(\n path.join(os.tmpdir(), \"an-builder-starter-sync-\"),\n );\n\n try {\n fs.cpSync(chatTemplateDir, tempDir, { recursive: true });\n _postProcessStandalone(STARTER_APP_NAME, tempDir, CHAT_TEMPLATE);\n\n const packageJson = JSON.parse(\n fs.readFileSync(path.join(tempDir, \"package.json\"), \"utf-8\"),\n ) as PackageJson;\n\n const workspacePath = path.join(tempDir, \"pnpm-workspace.yaml\");\n const pnpmWorkspaceYaml = fs.existsSync(workspacePath)\n ? fs.readFileSync(workspacePath, \"utf-8\")\n : null;\n\n return { packageJson, pnpmWorkspaceYaml };\n } finally {\n fs.rmSync(tempDir, { recursive: true, force: true });\n }\n}\n\nfunction mergePackageJsonRecords(\n canonical: Record<string, string> | undefined,\n starter: Record<string, string> | undefined,\n starterPinnedKeys: string[] = [],\n): Record<string, string> {\n const merged = { ...(canonical ?? {}) };\n for (const [key, value] of Object.entries(starter ?? {})) {\n if (!(key in merged)) {\n merged[key] = value;\n }\n }\n for (const key of starterPinnedKeys) {\n const pinned = starter?.[key];\n if (pinned) {\n merged[key] = pinned;\n }\n }\n return merged;\n}\n\nexport function mergeStarterManifest(\n starterPackageJson: PackageJson,\n canonicalPackageJson: PackageJson,\n): PackageJson {\n const merged = structuredClone(canonicalPackageJson) as PackageJson;\n\n merged.name = starterPackageJson.name ?? STARTER_APP_NAME;\n if (typeof starterPackageJson.displayName === \"string\") {\n merged.displayName = starterPackageJson.displayName;\n }\n if (typeof starterPackageJson.description === \"string\") {\n merged.description = starterPackageJson.description;\n }\n if (starterPackageJson.private !== undefined) {\n merged.private = starterPackageJson.private;\n }\n if (typeof starterPackageJson.packageManager === \"string\") {\n merged.packageManager = starterPackageJson.packageManager;\n }\n\n merged.dependencies = mergePackageJsonRecords(\n canonicalPackageJson.dependencies as Record<string, string> | undefined,\n starterPackageJson.dependencies as Record<string, string> | undefined,\n [\"@agent-native/core\"],\n );\n merged.devDependencies = mergePackageJsonRecords(\n canonicalPackageJson.devDependencies as Record<string, string> | undefined,\n starterPackageJson.devDependencies as Record<string, string> | undefined,\n );\n merged.scripts = mergePackageJsonRecords(\n canonicalPackageJson.scripts as Record<string, string> | undefined,\n starterPackageJson.scripts as Record<string, string> | undefined,\n );\n\n return merged;\n}\n\nexport function workspaceFileSyncChanged(\n existingWorkspace: string | null,\n canonicalWorkspace: string | null,\n): boolean {\n if (canonicalWorkspace === null) {\n return existingWorkspace !== null;\n }\n return existingWorkspace !== canonicalWorkspace;\n}\n\nexport function applyWorkspaceFileSync(\n targetPath: string,\n canonicalWorkspace: string | null,\n): void {\n if (canonicalWorkspace === null) {\n if (fs.existsSync(targetPath)) {\n fs.unlinkSync(targetPath);\n }\n return;\n }\n fs.writeFileSync(targetPath, canonicalWorkspace);\n}\n\nfunction stableJson(value: unknown): string {\n return `${JSON.stringify(value, null, 2)}\\n`;\n}\n\nexport type SyncStarterManifestResult = {\n changed: boolean;\n packageJson: PackageJson;\n pnpmWorkspaceYaml: string | null;\n};\n\nexport function syncStarterManifestFiles(options: {\n starterPackageJsonPath: string;\n starterPnpmWorkspacePath?: string;\n repoRoot?: string;\n write?: boolean;\n}): SyncStarterManifestResult {\n const { packageJson: canonical, pnpmWorkspaceYaml } =\n generateStandaloneChatManifest(options.repoRoot);\n\n const starterPackageJson = JSON.parse(\n fs.readFileSync(options.starterPackageJsonPath, \"utf-8\"),\n ) as PackageJson;\n const mergedPackageJson = mergeStarterManifest(starterPackageJson, canonical);\n\n let workspaceChanged = false;\n const existingWorkspace =\n options.starterPnpmWorkspacePath &&\n fs.existsSync(options.starterPnpmWorkspacePath)\n ? fs.readFileSync(options.starterPnpmWorkspacePath, \"utf-8\")\n : null;\n\n workspaceChanged = workspaceFileSyncChanged(\n existingWorkspace,\n pnpmWorkspaceYaml,\n );\n\n const packageChanged =\n stableJson(starterPackageJson) !== stableJson(mergedPackageJson);\n const changed = packageChanged || workspaceChanged;\n\n if (options.write && changed) {\n if (packageChanged) {\n fs.writeFileSync(\n options.starterPackageJsonPath,\n stableJson(mergedPackageJson),\n );\n }\n if (workspaceChanged && options.starterPnpmWorkspacePath) {\n applyWorkspaceFileSync(\n options.starterPnpmWorkspacePath,\n pnpmWorkspaceYaml,\n );\n }\n }\n\n return {\n changed,\n packageJson: mergedPackageJson,\n pnpmWorkspaceYaml,\n };\n}\n\nexport function parseSyncStarterManifestArgs(argv: string[]): {\n command: \"merge\" | \"generate\";\n starterPackageJsonPath?: string;\n starterPnpmWorkspacePath?: string;\n write: boolean;\n repoRoot?: string;\n} {\n const [commandRaw, ...rest] = argv;\n const command = commandRaw === \"generate\" ? \"generate\" : \"merge\";\n let starterPackageJsonPath: string | undefined;\n let starterPnpmWorkspacePath: string | undefined;\n let write = false;\n let repoRoot: string | undefined;\n\n for (let i = 0; i < rest.length; i++) {\n const arg = rest[i];\n if (arg === \"--write\") {\n write = true;\n continue;\n }\n if (arg === \"--starter-package-json\") {\n starterPackageJsonPath = rest[++i];\n continue;\n }\n if (arg === \"--starter-pnpm-workspace\") {\n starterPnpmWorkspacePath = rest[++i];\n continue;\n }\n if (arg === \"--repo-root\") {\n repoRoot = rest[++i];\n continue;\n }\n throw new Error(`Unknown argument: ${arg}`);\n }\n\n if (command === \"merge\" && !starterPackageJsonPath) {\n throw new Error(\n \"merge requires --starter-package-json <path> [--starter-pnpm-workspace <path>] [--write] [--repo-root <path>]\",\n );\n }\n\n return {\n command,\n starterPackageJsonPath,\n starterPnpmWorkspacePath,\n write,\n repoRoot,\n };\n}\n\nexport function runSyncStarterManifestCli(argv: string[]): number {\n const args = parseSyncStarterManifestArgs(argv);\n\n if (args.command === \"generate\") {\n const { packageJson, pnpmWorkspaceYaml } = generateStandaloneChatManifest(\n args.repoRoot,\n );\n process.stdout.write(stableJson(packageJson));\n if (pnpmWorkspaceYaml) {\n process.stdout.write(\"\\n--- pnpm-workspace.yaml ---\\n\");\n process.stdout.write(pnpmWorkspaceYaml);\n }\n return 0;\n }\n\n const result = syncStarterManifestFiles({\n starterPackageJsonPath: args.starterPackageJsonPath!,\n starterPnpmWorkspacePath: args.starterPnpmWorkspacePath,\n repoRoot: args.repoRoot,\n write: args.write,\n });\n\n if (result.changed) {\n console.log(\n args.write\n ? \"Updated builder-agent-native-starter manifest from templates/chat.\"\n : \"builder-agent-native-starter manifest is out of date with templates/chat.\",\n );\n return args.write ? 0 : 1;\n }\n\n console.log(\n \"builder-agent-native-starter manifest already matches templates/chat.\",\n );\n return 0;\n}\n\nconst isDirectRun =\n process.argv[1] &&\n path.resolve(process.argv[1]) ===\n path.resolve(fileURLToPath(import.meta.url));\n\nif (isDirectRun) {\n const exitCode = runSyncStarterManifestCli(process.argv.slice(2));\n process.exit(exitCode);\n}\n"]}
|
package/dist/deploy/build.d.ts
CHANGED
|
@@ -58,46 +58,70 @@ export declare function findInstalledResvgPackages(nodeModulesRoots: string[]):
|
|
|
58
58
|
*/
|
|
59
59
|
export declare function isDurableBackgroundDeployEnabled(): boolean;
|
|
60
60
|
/**
|
|
61
|
-
* Single-template Netlify build: emit
|
|
62
|
-
* the chat `_process-run` worker runs on Netlify's
|
|
63
|
-
*
|
|
61
|
+
* Single-template Netlify build: emit an async (background) function INSIDE the
|
|
62
|
+
* scanned functions dir so the chat `_process-run` worker runs on Netlify's
|
|
63
|
+
* 15-min async function instead of the synchronous `/*` catch-all.
|
|
64
64
|
* Additive + flag-gated (see `isDurableBackgroundDeployEnabled`).
|
|
65
65
|
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
66
|
+
* GROUNDED IN THE REAL NETLIFY BUILD OUTPUT (verified from a local Nitro build):
|
|
67
|
+
* - Nitro's `netlify` preset emits exactly ONE function source at
|
|
68
|
+
* `.netlify/functions-internal/server/`. `server.mjs` re-exports `main.mjs`
|
|
69
|
+
* and declares `export const config = { path: "/*", excludedPath:
|
|
70
|
+
* ["/.netlify/*"], preferStatic: true, ... }`. Nitro writes NO `netlify.toml`
|
|
71
|
+
* and NO `[[redirects]]`; the `/*` catch-all is an IN-CODE Functions-API-v2
|
|
72
|
+
* `config.path`.
|
|
73
|
+
* - The generated `.netlify/netlify.toml` sets
|
|
74
|
+
* `functionsDirectory = ".netlify/functions-internal"`. Netlify scans EXACTLY
|
|
75
|
+
* that dir; functions placed anywhere else (e.g. `.netlify/functions/`, which
|
|
76
|
+
* is the BUILD OUTPUT dir where `@netlify/build` later writes the zipped
|
|
77
|
+
* functions + `manifest.json`) are NEVER deployed.
|
|
78
|
+
* - On Netlify CI, `@netlify/build` reads each scanned function's
|
|
79
|
+
* `export const config`, zips it, and materializes
|
|
80
|
+
* `.netlify/functions/manifest.json` with `routes` derived from each
|
|
81
|
+
* `config.path`. So per-file `export const config` (including `background` and
|
|
82
|
+
* `path`) IS honored — the `server` manifest entry's `routes: [{ pattern:
|
|
83
|
+
* "/*" }]` came straight from `server.mjs`'s `config.path`.
|
|
84
|
+
*
|
|
85
|
+
* THEREFORE we:
|
|
86
|
+
* 1. Emit the background function INTO the scanned dir
|
|
87
|
+
* (`.netlify/functions-internal/server-agent-background/`), sharing the same
|
|
88
|
+
* built `main.mjs` bundle, so Netlify discovers it and honors its config.
|
|
89
|
+
* 2. Give its `export const config` BOTH `background: true` (→ async invoke,
|
|
90
|
+
* immediate 202, 15-min budget) AND `path: AGENT_CHAT_PROCESS_RUN_PATH` (so
|
|
91
|
+
* it claims that exact path at function-matching time, which Netlify
|
|
92
|
+
* evaluates BEFORE redirects — step 10 vs 11 in the request chain).
|
|
93
|
+
* 3. PATCH the Nitro `server` function's own `server.mjs` so its catch-all
|
|
94
|
+
* `config.path: "/*"` EXCLUDES `AGENT_CHAT_PROCESS_RUN_PATH` (append it to
|
|
95
|
+
* `excludedPath`). Netlify does NOT define a winner when two serverless
|
|
96
|
+
* functions both match a path; rather than rely on that undocumented order,
|
|
97
|
+
* we make the match UNAMBIGUOUS — only the background function matches
|
|
98
|
+
* `_process-run`, and `server` matches everything else exactly as before.
|
|
99
|
+
* 4. Set `globalThis.__AGENT_NATIVE_BACKGROUND_RUNTIME__ = true` at cold start
|
|
71
100
|
* (read back by `isInBackgroundFunctionRuntime()` so the worker takes the
|
|
72
101
|
* ~13-min soft-timeout). A `globalThis` flag — NOT `process.env` — keeps the
|
|
73
102
|
* no-env-mutation guard satisfied and carries no cross-request state.
|
|
74
|
-
* 2. Declares `export const config = { background: true }` with NO `path`. With
|
|
75
|
-
* no custom `path`, Netlify exposes the function at the DEFAULT url
|
|
76
|
-
* `/.netlify/functions/server-agent-background` and `background:true` makes
|
|
77
|
-
* it ASYNC (immediate HTTP 202 ack, 15-min budget). The foreground POST
|
|
78
|
-
* self-dispatches to that direct url
|
|
79
|
-
* (`resolveAgentChatProcessRunDispatchPath`), BYPASSING Nitro's `/*`
|
|
80
|
-
* catch-all entirely.
|
|
81
|
-
* 3. REWRITES the incoming request path to `AGENT_CHAT_PROCESS_RUN_PATH` before
|
|
82
|
-
* delegating to the Nitro handler (`./main.mjs` default export — a Netlify
|
|
83
|
-
* v2 / Web-standard `async (Request) => Response` handler), so the Nitro
|
|
84
|
-
* router dispatches it to the `_process-run` plugin. Method, ALL headers
|
|
85
|
-
* (critically the HMAC `Authorization: Bearer` the plugin verifies) and the
|
|
86
|
-
* body are preserved by cloning the incoming `Request` with only its URL
|
|
87
|
-
* pathname rewritten.
|
|
88
103
|
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
104
|
+
* With a real `config.path` the function is reachable at that path directly, so
|
|
105
|
+
* the foreground POSTs to `AGENT_CHAT_PROCESS_RUN_PATH`
|
|
106
|
+
* (`resolveAgentChatProcessRunDispatchPath`) and the request entry no longer
|
|
107
|
+
* needs to rewrite the path — it already arrives at the framework route. We keep
|
|
108
|
+
* a defensive normalize-to-PROCESS_RUN_PATH in the entry anyway (cheap, and it
|
|
109
|
+
* makes the function correct even if reached via its default function url).
|
|
110
|
+
*
|
|
111
|
+
* WHY THIS BEATS ALL THREE PRIOR FAILURES:
|
|
112
|
+
* - Attempts 1 & 2 emitted into `functions-internal` (correct dir) with a
|
|
113
|
+
* `config.path` but did NOT exclude that path from the `server` `/*`
|
|
114
|
+
* catch-all. Two functions matched `_process-run`; the order is undocumented
|
|
115
|
+
* and the catch-all `server` (priority 0, synchronous) won → SYNC 401, not a
|
|
116
|
+
* 202. We now exclude the path from `server`, so only the async function
|
|
117
|
+
* matches.
|
|
118
|
+
* - Attempt 3 emitted a standalone function into `.netlify/functions/` — the
|
|
119
|
+
* OUTPUT dir, which Netlify does not scan — so it never entered the manifest
|
|
120
|
+
* → 404. We now emit into the SCANNED `functions-internal` dir.
|
|
97
121
|
*
|
|
98
|
-
* Safety net regardless of Netlify routing nuance: if the
|
|
99
|
-
*
|
|
100
|
-
*
|
|
122
|
+
* Safety net regardless of Netlify routing nuance: if the dispatch fast-fails
|
|
123
|
+
* (e.g. the function was not emitted), the foreground handler degrades to an
|
|
124
|
+
* inline 40s synchronous run (see production-agent.ts).
|
|
101
125
|
*/
|
|
102
126
|
export declare function emitSingleTemplateNetlifyBackgroundFunction(projectCwd: string): void;
|
|
103
127
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/deploy/build.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;GAYG;AAOH,OAAO,EAML,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAC;AA+B7B,eAAO,MAAM,6BAA6B,UAiBzC,CAAC;AAuBF,wBAAgB,wCAAwC,CACtD,WAAW,EAAE,MAAM,EAAE,GACpB,MAAM,CAaR;AAgBD,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAgBvE,wBAAgB,yCAAyC,CACvD,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,EACjB,WAAW,SAAK,GACf,IAAI,CAQN;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,EAAE,EACzB,WAAW,EAAE,MAAM,EAAE,EACrB,kBAAkB,GAAE,MAAM,EAAO,EACjC,OAAO,GAAE,gBAAgB,EAAO,EAChC,aAAa,GAAE,oBAAoB,GAAG,IAAW,EACjD,mBAAmB,GAAE,MAAM,EAAO,EAClC,gBAAgB,SAAmC,GAClD,MAAM,CAskBR;AAyXD,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAE9C;AAkHD,wBAAgB,OAAO,CACrB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,iBAAiB,cAAoB,QAoCtC;AAuBD,KAAK,0BAA0B,GAAG,OAAO,GAAG,KAAK,CAAC;AAQlD,wBAAgB,qCAAqC,CACnD,YAAY,GAAE,MAAM,CAAC,QAA2B,EAChD,QAAQ,GAAE,MAAM,CAAC,YAA2B,EAC5C,UAAU,GAAE,0BAA0B,GAAG,IAAgD,GACxF,OAAO,CAOT;AAqED,wBAAgB,gCAAgC,CAC9C,gBAAgB,EAAE,MAAM,EAAE,GACzB,MAAM,GAAG,IAAI,CA8Bf;AAED,wBAAgB,0BAA0B,CACxC,gBAAgB,EAAE,MAAM,EAAE,GACzB,KAAK,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAqCpD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gCAAgC,IAAI,OAAO,CAK1D;AAED
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/deploy/build.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;GAYG;AAOH,OAAO,EAML,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAC;AA+B7B,eAAO,MAAM,6BAA6B,UAiBzC,CAAC;AAuBF,wBAAgB,wCAAwC,CACtD,WAAW,EAAE,MAAM,EAAE,GACpB,MAAM,CAaR;AAgBD,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAgBvE,wBAAgB,yCAAyC,CACvD,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,EACjB,WAAW,SAAK,GACf,IAAI,CAQN;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,EAAE,EACzB,WAAW,EAAE,MAAM,EAAE,EACrB,kBAAkB,GAAE,MAAM,EAAO,EACjC,OAAO,GAAE,gBAAgB,EAAO,EAChC,aAAa,GAAE,oBAAoB,GAAG,IAAW,EACjD,mBAAmB,GAAE,MAAM,EAAO,EAClC,gBAAgB,SAAmC,GAClD,MAAM,CAskBR;AAyXD,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAE9C;AAkHD,wBAAgB,OAAO,CACrB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,iBAAiB,cAAoB,QAoCtC;AAuBD,KAAK,0BAA0B,GAAG,OAAO,GAAG,KAAK,CAAC;AAQlD,wBAAgB,qCAAqC,CACnD,YAAY,GAAE,MAAM,CAAC,QAA2B,EAChD,QAAQ,GAAE,MAAM,CAAC,YAA2B,EAC5C,UAAU,GAAE,0BAA0B,GAAG,IAAgD,GACxF,OAAO,CAOT;AAqED,wBAAgB,gCAAgC,CAC9C,gBAAgB,EAAE,MAAM,EAAE,GACzB,MAAM,GAAG,IAAI,CA8Bf;AAED,wBAAgB,0BAA0B,CACxC,gBAAgB,EAAE,MAAM,EAAE,GACzB,KAAK,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAqCpD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gCAAgC,IAAI,OAAO,CAK1D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACH,wBAAgB,2CAA2C,CACzD,UAAU,EAAE,MAAM,GACjB,IAAI,CA8FN;AA2QD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,gBAAgB,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,UAAU,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,GAAG,CAAC;IACX,KAAK,EAAE,eAAe,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA+Bf"}
|
package/dist/deploy/build.js
CHANGED
|
@@ -1252,46 +1252,70 @@ export function isDurableBackgroundDeployEnabled() {
|
|
|
1252
1252
|
return !(v === "0" || v === "false" || v === "no" || v === "off");
|
|
1253
1253
|
}
|
|
1254
1254
|
/**
|
|
1255
|
-
* Single-template Netlify build: emit
|
|
1256
|
-
* the chat `_process-run` worker runs on Netlify's
|
|
1257
|
-
*
|
|
1255
|
+
* Single-template Netlify build: emit an async (background) function INSIDE the
|
|
1256
|
+
* scanned functions dir so the chat `_process-run` worker runs on Netlify's
|
|
1257
|
+
* 15-min async function instead of the synchronous `/*` catch-all.
|
|
1258
1258
|
* Additive + flag-gated (see `isDurableBackgroundDeployEnabled`).
|
|
1259
1259
|
*
|
|
1260
|
-
*
|
|
1261
|
-
*
|
|
1262
|
-
*
|
|
1263
|
-
*
|
|
1264
|
-
*
|
|
1260
|
+
* GROUNDED IN THE REAL NETLIFY BUILD OUTPUT (verified from a local Nitro build):
|
|
1261
|
+
* - Nitro's `netlify` preset emits exactly ONE function source at
|
|
1262
|
+
* `.netlify/functions-internal/server/`. `server.mjs` re-exports `main.mjs`
|
|
1263
|
+
* and declares `export const config = { path: "/*", excludedPath:
|
|
1264
|
+
* ["/.netlify/*"], preferStatic: true, ... }`. Nitro writes NO `netlify.toml`
|
|
1265
|
+
* and NO `[[redirects]]`; the `/*` catch-all is an IN-CODE Functions-API-v2
|
|
1266
|
+
* `config.path`.
|
|
1267
|
+
* - The generated `.netlify/netlify.toml` sets
|
|
1268
|
+
* `functionsDirectory = ".netlify/functions-internal"`. Netlify scans EXACTLY
|
|
1269
|
+
* that dir; functions placed anywhere else (e.g. `.netlify/functions/`, which
|
|
1270
|
+
* is the BUILD OUTPUT dir where `@netlify/build` later writes the zipped
|
|
1271
|
+
* functions + `manifest.json`) are NEVER deployed.
|
|
1272
|
+
* - On Netlify CI, `@netlify/build` reads each scanned function's
|
|
1273
|
+
* `export const config`, zips it, and materializes
|
|
1274
|
+
* `.netlify/functions/manifest.json` with `routes` derived from each
|
|
1275
|
+
* `config.path`. So per-file `export const config` (including `background` and
|
|
1276
|
+
* `path`) IS honored — the `server` manifest entry's `routes: [{ pattern:
|
|
1277
|
+
* "/*" }]` came straight from `server.mjs`'s `config.path`.
|
|
1278
|
+
*
|
|
1279
|
+
* THEREFORE we:
|
|
1280
|
+
* 1. Emit the background function INTO the scanned dir
|
|
1281
|
+
* (`.netlify/functions-internal/server-agent-background/`), sharing the same
|
|
1282
|
+
* built `main.mjs` bundle, so Netlify discovers it and honors its config.
|
|
1283
|
+
* 2. Give its `export const config` BOTH `background: true` (→ async invoke,
|
|
1284
|
+
* immediate 202, 15-min budget) AND `path: AGENT_CHAT_PROCESS_RUN_PATH` (so
|
|
1285
|
+
* it claims that exact path at function-matching time, which Netlify
|
|
1286
|
+
* evaluates BEFORE redirects — step 10 vs 11 in the request chain).
|
|
1287
|
+
* 3. PATCH the Nitro `server` function's own `server.mjs` so its catch-all
|
|
1288
|
+
* `config.path: "/*"` EXCLUDES `AGENT_CHAT_PROCESS_RUN_PATH` (append it to
|
|
1289
|
+
* `excludedPath`). Netlify does NOT define a winner when two serverless
|
|
1290
|
+
* functions both match a path; rather than rely on that undocumented order,
|
|
1291
|
+
* we make the match UNAMBIGUOUS — only the background function matches
|
|
1292
|
+
* `_process-run`, and `server` matches everything else exactly as before.
|
|
1293
|
+
* 4. Set `globalThis.__AGENT_NATIVE_BACKGROUND_RUNTIME__ = true` at cold start
|
|
1265
1294
|
* (read back by `isInBackgroundFunctionRuntime()` so the worker takes the
|
|
1266
1295
|
* ~13-min soft-timeout). A `globalThis` flag — NOT `process.env` — keeps the
|
|
1267
1296
|
* no-env-mutation guard satisfied and carries no cross-request state.
|
|
1268
|
-
* 2. Declares `export const config = { background: true }` with NO `path`. With
|
|
1269
|
-
* no custom `path`, Netlify exposes the function at the DEFAULT url
|
|
1270
|
-
* `/.netlify/functions/server-agent-background` and `background:true` makes
|
|
1271
|
-
* it ASYNC (immediate HTTP 202 ack, 15-min budget). The foreground POST
|
|
1272
|
-
* self-dispatches to that direct url
|
|
1273
|
-
* (`resolveAgentChatProcessRunDispatchPath`), BYPASSING Nitro's `/*`
|
|
1274
|
-
* catch-all entirely.
|
|
1275
|
-
* 3. REWRITES the incoming request path to `AGENT_CHAT_PROCESS_RUN_PATH` before
|
|
1276
|
-
* delegating to the Nitro handler (`./main.mjs` default export — a Netlify
|
|
1277
|
-
* v2 / Web-standard `async (Request) => Response` handler), so the Nitro
|
|
1278
|
-
* router dispatches it to the `_process-run` plugin. Method, ALL headers
|
|
1279
|
-
* (critically the HMAC `Authorization: Bearer` the plugin verifies) and the
|
|
1280
|
-
* body are preserved by cloning the incoming `Request` with only its URL
|
|
1281
|
-
* pathname rewritten.
|
|
1282
1297
|
*
|
|
1283
|
-
*
|
|
1284
|
-
*
|
|
1285
|
-
*
|
|
1286
|
-
*
|
|
1287
|
-
*
|
|
1288
|
-
*
|
|
1289
|
-
*
|
|
1290
|
-
*
|
|
1298
|
+
* With a real `config.path` the function is reachable at that path directly, so
|
|
1299
|
+
* the foreground POSTs to `AGENT_CHAT_PROCESS_RUN_PATH`
|
|
1300
|
+
* (`resolveAgentChatProcessRunDispatchPath`) and the request entry no longer
|
|
1301
|
+
* needs to rewrite the path — it already arrives at the framework route. We keep
|
|
1302
|
+
* a defensive normalize-to-PROCESS_RUN_PATH in the entry anyway (cheap, and it
|
|
1303
|
+
* makes the function correct even if reached via its default function url).
|
|
1304
|
+
*
|
|
1305
|
+
* WHY THIS BEATS ALL THREE PRIOR FAILURES:
|
|
1306
|
+
* - Attempts 1 & 2 emitted into `functions-internal` (correct dir) with a
|
|
1307
|
+
* `config.path` but did NOT exclude that path from the `server` `/*`
|
|
1308
|
+
* catch-all. Two functions matched `_process-run`; the order is undocumented
|
|
1309
|
+
* and the catch-all `server` (priority 0, synchronous) won → SYNC 401, not a
|
|
1310
|
+
* 202. We now exclude the path from `server`, so only the async function
|
|
1311
|
+
* matches.
|
|
1312
|
+
* - Attempt 3 emitted a standalone function into `.netlify/functions/` — the
|
|
1313
|
+
* OUTPUT dir, which Netlify does not scan — so it never entered the manifest
|
|
1314
|
+
* → 404. We now emit into the SCANNED `functions-internal` dir.
|
|
1291
1315
|
*
|
|
1292
|
-
* Safety net regardless of Netlify routing nuance: if the
|
|
1293
|
-
*
|
|
1294
|
-
*
|
|
1316
|
+
* Safety net regardless of Netlify routing nuance: if the dispatch fast-fails
|
|
1317
|
+
* (e.g. the function was not emitted), the foreground handler degrades to an
|
|
1318
|
+
* inline 40s synchronous run (see production-agent.ts).
|
|
1295
1319
|
*/
|
|
1296
1320
|
export function emitSingleTemplateNetlifyBackgroundFunction(projectCwd) {
|
|
1297
1321
|
const internalDir = path.join(projectCwd, ".netlify", "functions-internal");
|
|
@@ -1304,16 +1328,20 @@ export function emitSingleTemplateNetlifyBackgroundFunction(projectCwd) {
|
|
|
1304
1328
|
return;
|
|
1305
1329
|
}
|
|
1306
1330
|
const backgroundName = AGENT_BACKGROUND_FUNCTION_NAME;
|
|
1307
|
-
// Emit
|
|
1308
|
-
//
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1331
|
+
// Emit INTO the SCANNED functions dir (functions-internal) so Netlify discovers
|
|
1332
|
+
// the function and honors its `export const config`. `.netlify/functions/` is
|
|
1333
|
+
// the build OUTPUT dir (where @netlify/build writes the zip + manifest) and is
|
|
1334
|
+
// NOT scanned — emitting there is why the standalone attempt 404'd.
|
|
1335
|
+
const dest = path.join(internalDir, backgroundName);
|
|
1312
1336
|
fs.rmSync(dest, { recursive: true, force: true });
|
|
1313
1337
|
copyDir(serverDir, dest);
|
|
1314
|
-
// Drop the original Nitro `/*` entry so our
|
|
1315
|
-
//
|
|
1338
|
+
// Drop the original Nitro `/*` entry so our entry is the entrypoint and the
|
|
1339
|
+
// copied bundle does NOT re-register the catch-all `config.path`.
|
|
1316
1340
|
fs.rmSync(path.join(dest, "server.mjs"), { force: true });
|
|
1341
|
+
// Make the `server` `/*` catch-all NOT match the process-run path, so only the
|
|
1342
|
+
// async background function matches it (function-vs-function path order is
|
|
1343
|
+
// undocumented on Netlify — don't rely on it).
|
|
1344
|
+
excludeProcessRunPathFromServerCatchAll(serverDir);
|
|
1317
1345
|
const processRunPath = JSON.stringify(AGENT_CHAT_PROCESS_RUN_PATH);
|
|
1318
1346
|
const entry = `// Mark this isolate as the durable background runtime BEFORE the handler
|
|
1319
1347
|
// bundle is imported, so isInBackgroundFunctionRuntime() reliably returns true
|
|
@@ -1331,12 +1359,13 @@ let cachedHandler;
|
|
|
1331
1359
|
|
|
1332
1360
|
// Netlify v2 invokes this as (request, context). The Nitro netlify handler is a
|
|
1333
1361
|
// Web-standard \`async (Request) => Response\` (see nitro/presets/netlify/runtime).
|
|
1334
|
-
//
|
|
1335
|
-
//
|
|
1336
|
-
//
|
|
1337
|
-
//
|
|
1338
|
-
//
|
|
1339
|
-
//
|
|
1362
|
+
// Because this function declares \`config.path = PROCESS_RUN_PATH\`, Netlify routes
|
|
1363
|
+
// that exact path here and the request already arrives as PROCESS_RUN_PATH — no
|
|
1364
|
+
// rewrite is needed. We still NORMALIZE the pathname to PROCESS_RUN_PATH so the
|
|
1365
|
+
// function stays correct even if it is ever reached via its default function url
|
|
1366
|
+
// (/.netlify/functions/${backgroundName}). Method, ALL headers (the HMAC
|
|
1367
|
+
// Authorization: Bearer MUST survive — the plugin verifies it) and the body are
|
|
1368
|
+
// preserved by cloning the incoming Request with only its URL pathname set.
|
|
1340
1369
|
export default async function handler(request) {
|
|
1341
1370
|
cachedHandler ??= (await import("./main.mjs")).default;
|
|
1342
1371
|
const url = new URL(request.url);
|
|
@@ -1357,24 +1386,74 @@ export const config = {
|
|
|
1357
1386
|
name: "agent background handler",
|
|
1358
1387
|
generator: "agent-native build",
|
|
1359
1388
|
// background: true makes Netlify invoke this ASYNCHRONOUSLY (immediate HTTP
|
|
1360
|
-
// 202 ack) with the 15-minute budget
|
|
1361
|
-
//
|
|
1362
|
-
//
|
|
1363
|
-
//
|
|
1364
|
-
// catch-all
|
|
1365
|
-
//
|
|
1366
|
-
// build/functions/configuration.
|
|
1389
|
+
// 202 ack) with the 15-minute budget (Netlify docs:
|
|
1390
|
+
// build/functions/background-functions + build/functions/api). path claims the
|
|
1391
|
+
// process-run route directly; Netlify evaluates serverless functions BEFORE
|
|
1392
|
+
// redirects (request-chain step 10 vs 11), and we exclude this path from the
|
|
1393
|
+
// \`server\` /* catch-all so only THIS function matches it — no ambiguous
|
|
1394
|
+
// function-vs-function order.
|
|
1367
1395
|
background: true,
|
|
1396
|
+
path: PROCESS_RUN_PATH,
|
|
1368
1397
|
nodeBundler: "none",
|
|
1369
1398
|
includedFiles: ["**"],
|
|
1370
1399
|
preferStatic: false,
|
|
1371
1400
|
};
|
|
1372
1401
|
`;
|
|
1373
1402
|
fs.writeFileSync(path.join(dest, `${backgroundName}.mjs`), entry);
|
|
1374
|
-
console.log(`[build] Emitted
|
|
1375
|
-
`
|
|
1376
|
-
|
|
1377
|
-
`Netlify async
|
|
1403
|
+
console.log(`[build] Emitted durable-background function "${backgroundName}" into the ` +
|
|
1404
|
+
`scanned dir .netlify/functions-internal with config { background:true, ` +
|
|
1405
|
+
`path:"${AGENT_CHAT_PROCESS_RUN_PATH}" } and excluded that path from the ` +
|
|
1406
|
+
`server /* catch-all. REQUIRES real-deploy verification of Netlify async ` +
|
|
1407
|
+
`(202) invocation — see docs/design/durable-agent-runs.md.`);
|
|
1408
|
+
}
|
|
1409
|
+
/**
|
|
1410
|
+
* Append `AGENT_CHAT_PROCESS_RUN_PATH` to the Nitro `server` function's
|
|
1411
|
+
* `config.excludedPath` so its `/*` catch-all does NOT match the process-run
|
|
1412
|
+
* path. That guarantees the async background function (which declares
|
|
1413
|
+
* `config.path = AGENT_CHAT_PROCESS_RUN_PATH`) is the ONLY function that matches
|
|
1414
|
+
* that path — Netlify does not define a winner when two serverless functions
|
|
1415
|
+
* both match, so we make the match unambiguous instead of relying on order.
|
|
1416
|
+
*
|
|
1417
|
+
* The Nitro-generated `server/server.mjs` is small and deterministic:
|
|
1418
|
+
* export { default } from "./main.mjs";
|
|
1419
|
+
* export const config = { ... excludedPath: ["/.netlify/*"], ... };
|
|
1420
|
+
* We parse the `excludedPath: [...]` array literal and add our path if absent.
|
|
1421
|
+
* If the shape ever changes and we can't find/parse it, we log and leave the
|
|
1422
|
+
* file untouched (the inline-40s fallback still keeps chat working).
|
|
1423
|
+
*/
|
|
1424
|
+
function excludeProcessRunPathFromServerCatchAll(serverDir) {
|
|
1425
|
+
const serverEntry = path.join(serverDir, "server.mjs");
|
|
1426
|
+
if (!fs.existsSync(serverEntry)) {
|
|
1427
|
+
console.warn("[build] Durable-background: server/server.mjs not found; cannot exclude " +
|
|
1428
|
+
`${AGENT_CHAT_PROCESS_RUN_PATH} from the /* catch-all.`);
|
|
1429
|
+
return;
|
|
1430
|
+
}
|
|
1431
|
+
const original = fs.readFileSync(serverEntry, "utf8");
|
|
1432
|
+
if (original.includes(AGENT_CHAT_PROCESS_RUN_PATH)) {
|
|
1433
|
+
// Already excluded (idempotent — emit may run on a re-used output tree).
|
|
1434
|
+
return;
|
|
1435
|
+
}
|
|
1436
|
+
const excludedPathRe = /excludedPath:\s*\[([^\]]*)\]/;
|
|
1437
|
+
const match = original.match(excludedPathRe);
|
|
1438
|
+
const quotedPath = JSON.stringify(AGENT_CHAT_PROCESS_RUN_PATH);
|
|
1439
|
+
if (match) {
|
|
1440
|
+
const existing = match[1].trim();
|
|
1441
|
+
const next = existing
|
|
1442
|
+
? `excludedPath: [${existing.replace(/,\s*$/, "")}, ${quotedPath}]`
|
|
1443
|
+
: `excludedPath: [${quotedPath}]`;
|
|
1444
|
+
fs.writeFileSync(serverEntry, original.replace(excludedPathRe, next));
|
|
1445
|
+
return;
|
|
1446
|
+
}
|
|
1447
|
+
// No existing `excludedPath` — inject one into the config object. Match the
|
|
1448
|
+
// `path: "/*"` line and add `excludedPath` right after it.
|
|
1449
|
+
const pathLineRe = /(path:\s*("\/\*"|'\/\*'),?)/;
|
|
1450
|
+
if (pathLineRe.test(original)) {
|
|
1451
|
+
fs.writeFileSync(serverEntry, original.replace(pathLineRe, `$1\n excludedPath: [${quotedPath}],`));
|
|
1452
|
+
return;
|
|
1453
|
+
}
|
|
1454
|
+
console.warn("[build] Durable-background: could not locate excludedPath/path in " +
|
|
1455
|
+
"server/server.mjs; leaving the /* catch-all unchanged (the background " +
|
|
1456
|
+
"function may be shadowed — the inline-40s fallback still applies).");
|
|
1378
1457
|
}
|
|
1379
1458
|
function copyInstalledLibsqlNativePackages(serverDir) {
|
|
1380
1459
|
if (!serverDir || !fs.existsSync(serverDir))
|