@agent-native/core 0.74.0 → 0.75.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/corpus/core/CHANGELOG.md +44 -0
  2. package/corpus/core/package.json +1 -1
  3. package/corpus/core/src/agent/durable-background.ts +48 -0
  4. package/corpus/core/src/agent/production-agent.ts +37 -4
  5. package/corpus/core/src/cli/skills.ts +15 -11
  6. package/corpus/core/src/deploy/build.ts +54 -19
  7. package/corpus/core/src/deploy/workspace-deploy.ts +12 -6
  8. package/corpus/core/src/templates/default/_gitignore +1 -0
  9. package/corpus/core/src/templates/headless/_gitignore +1 -0
  10. package/corpus/core/src/templates/workspace-root/_gitignore +1 -0
  11. package/corpus/templates/clips/actions/list-recordings.ts +21 -0
  12. package/corpus/templates/clips/app/components/library/library-layout.tsx +21 -2
  13. package/corpus/templates/clips/app/hooks/use-library.ts +18 -0
  14. package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +7 -5
  15. package/dist/agent/durable-background.d.ts +25 -0
  16. package/dist/agent/durable-background.d.ts.map +1 -1
  17. package/dist/agent/durable-background.js +43 -0
  18. package/dist/agent/durable-background.js.map +1 -1
  19. package/dist/agent/production-agent.d.ts.map +1 -1
  20. package/dist/agent/production-agent.js +36 -5
  21. package/dist/agent/production-agent.js.map +1 -1
  22. package/dist/cli/skills.d.ts +1 -1
  23. package/dist/cli/skills.d.ts.map +1 -1
  24. package/dist/cli/skills.js +15 -11
  25. package/dist/cli/skills.js.map +1 -1
  26. package/dist/deploy/build.d.ts +27 -11
  27. package/dist/deploy/build.d.ts.map +1 -1
  28. package/dist/deploy/build.js +54 -19
  29. package/dist/deploy/build.js.map +1 -1
  30. package/dist/deploy/workspace-deploy.js +12 -6
  31. package/dist/deploy/workspace-deploy.js.map +1 -1
  32. package/dist/templates/default/_gitignore +1 -0
  33. package/dist/templates/headless/_gitignore +1 -0
  34. package/dist/templates/workspace-root/_gitignore +1 -0
  35. package/package.json +1 -1
  36. package/src/templates/default/_gitignore +1 -0
  37. package/src/templates/headless/_gitignore +1 -0
  38. package/src/templates/workspace-root/_gitignore +1 -0
@@ -42,8 +42,19 @@ export declare function findInstalledResvgPackages(nodeModulesRoots: string[]):
42
42
  /**
43
43
  * Deploy-time gate for emitting the second `-background` Netlify function.
44
44
  * Reads the same env flag the runtime gate uses
45
- * (`AGENT_CHAT_DURABLE_BACKGROUND`). Off by default — when off, the deploy
46
- * emits exactly one function (today's behavior, byte-for-byte).
45
+ * (`AGENT_CHAT_DURABLE_BACKGROUND`).
46
+ *
47
+ * DEFAULT-ON, matching the runtime gate (`isFlagEnabled` in
48
+ * durable-background.ts): unset/empty/unknown means enabled; an app opts OUT
49
+ * only with an explicit falsy value (`false`/`0`/`no`/`off`). This is what
50
+ * actually emits the 15-min `-background` function so the `_process-run`
51
+ * dispatch lands on it (async 202 → the worker runs with the real 15-min budget
52
+ * → its ~13-min soft-timeout fits). The deploy gate and runtime gate MUST agree:
53
+ * if the deploy emitted no `-background` function but the runtime still routed
54
+ * the worker into the ~13-min timeout regime, the worker would overshoot the
55
+ * ~60s synchronous wall and re-dispatch in a loop. (The runtime now also guards
56
+ * the ~13-min budget on the real function name via `isInBackgroundFunctionRuntime`,
57
+ * so a missing emit degrades to clean 40s-chunked runs rather than the loop.)
47
58
  */
48
59
  export declare function isDurableBackgroundDeployEnabled(): boolean;
49
60
  /**
@@ -57,15 +68,20 @@ export declare function isDurableBackgroundDeployEnabled(): boolean;
57
68
  * that directory to a sibling `<...>-background` function and write an entry
58
69
  * with a `config.path` of the process-run route.
59
70
  *
60
- * ⚠️ REAL-DEPLOY VERIFICATION REQUIRED. Whether Netlify routes
61
- * `/_agent-native/agent-chat/_process-run` to this `-background` function (and
62
- * invokes it asynchronously with the 15-min budget) vs the synchronous Nitro
63
- * function cannot be verified in this environment Nitro owns the primary
64
- * function's routing manifest, and the precedence between the two functions for
65
- * that path is a Netlify runtime behavior. If routing resolves to the
66
- * synchronous function, the run still completes via the existing 40s
67
- * soft-timeout path (no durable win, no regression). See
68
- * docs/design/durable-agent-runs.md (Open risks #1).
71
+ * The function declares `background: true` so Netlify invokes it ASYNC (HTTP
72
+ * 202 ack) with the 15-min budget, and a `config.path` of the process-run route
73
+ * so the `_process-run` self-dispatch lands on it. The earlier version set the
74
+ * path but omitted `background: true` and relied on the legacy `-background`
75
+ * filename which the `config` object overrides so Netlify served it
76
+ * SYNCHRONOUSLY (~60s) and the durable worker never got the 15-min budget
77
+ * (confirmed live: a POST to the process-run path returned a synchronous 401
78
+ * from the handler instead of a 202 async ack).
79
+ *
80
+ * ⚠️ One Netlify runtime behavior still resolves only on a real deploy: the
81
+ * routing precedence between this function's `config.path` and Nitro's catch-all
82
+ * for that exact path. If the catch-all wins, the run still completes via the
83
+ * 40s soft-timeout path on the sync function (no durable win, no regression).
84
+ * See docs/design/durable-agent-runs.md (Open risks #1).
69
85
  */
70
86
  export declare function emitSingleTemplateNetlifyBackgroundFunction(projectCwd: string): void;
71
87
  /**
@@ -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;AA4B7B,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;;;;;GAKG;AACH,wBAAgB,gCAAgC,IAAI,OAAO,CAK1D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,2CAA2C,CACzD,UAAU,EAAE,MAAM,GACjB,IAAI,CAyCN;AAkND;;;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"}
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;AA4B7B,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;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,2CAA2C,CACzD,UAAU,EAAE,MAAM,GACjB,IAAI,CA2DN;AAkND;;;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"}
@@ -1230,15 +1230,26 @@ export function findInstalledResvgPackages(nodeModulesRoots) {
1230
1230
  /**
1231
1231
  * Deploy-time gate for emitting the second `-background` Netlify function.
1232
1232
  * Reads the same env flag the runtime gate uses
1233
- * (`AGENT_CHAT_DURABLE_BACKGROUND`). Off by default — when off, the deploy
1234
- * emits exactly one function (today's behavior, byte-for-byte).
1233
+ * (`AGENT_CHAT_DURABLE_BACKGROUND`).
1234
+ *
1235
+ * DEFAULT-ON, matching the runtime gate (`isFlagEnabled` in
1236
+ * durable-background.ts): unset/empty/unknown means enabled; an app opts OUT
1237
+ * only with an explicit falsy value (`false`/`0`/`no`/`off`). This is what
1238
+ * actually emits the 15-min `-background` function so the `_process-run`
1239
+ * dispatch lands on it (async 202 → the worker runs with the real 15-min budget
1240
+ * → its ~13-min soft-timeout fits). The deploy gate and runtime gate MUST agree:
1241
+ * if the deploy emitted no `-background` function but the runtime still routed
1242
+ * the worker into the ~13-min timeout regime, the worker would overshoot the
1243
+ * ~60s synchronous wall and re-dispatch in a loop. (The runtime now also guards
1244
+ * the ~13-min budget on the real function name via `isInBackgroundFunctionRuntime`,
1245
+ * so a missing emit degrades to clean 40s-chunked runs rather than the loop.)
1235
1246
  */
1236
1247
  export function isDurableBackgroundDeployEnabled() {
1237
1248
  const raw = process.env.AGENT_CHAT_DURABLE_BACKGROUND;
1238
1249
  if (raw == null)
1239
- return false;
1250
+ return true;
1240
1251
  const v = raw.trim().toLowerCase();
1241
- return v === "1" || v === "true" || v === "yes" || v === "on";
1252
+ return !(v === "0" || v === "false" || v === "no" || v === "off");
1242
1253
  }
1243
1254
  /**
1244
1255
  * Single-template Netlify build: emit a SECOND function whose name ends in
@@ -1251,15 +1262,20 @@ export function isDurableBackgroundDeployEnabled() {
1251
1262
  * that directory to a sibling `<...>-background` function and write an entry
1252
1263
  * with a `config.path` of the process-run route.
1253
1264
  *
1254
- * ⚠️ REAL-DEPLOY VERIFICATION REQUIRED. Whether Netlify routes
1255
- * `/_agent-native/agent-chat/_process-run` to this `-background` function (and
1256
- * invokes it asynchronously with the 15-min budget) vs the synchronous Nitro
1257
- * function cannot be verified in this environment Nitro owns the primary
1258
- * function's routing manifest, and the precedence between the two functions for
1259
- * that path is a Netlify runtime behavior. If routing resolves to the
1260
- * synchronous function, the run still completes via the existing 40s
1261
- * soft-timeout path (no durable win, no regression). See
1262
- * docs/design/durable-agent-runs.md (Open risks #1).
1265
+ * The function declares `background: true` so Netlify invokes it ASYNC (HTTP
1266
+ * 202 ack) with the 15-min budget, and a `config.path` of the process-run route
1267
+ * so the `_process-run` self-dispatch lands on it. The earlier version set the
1268
+ * path but omitted `background: true` and relied on the legacy `-background`
1269
+ * filename which the `config` object overrides so Netlify served it
1270
+ * SYNCHRONOUSLY (~60s) and the durable worker never got the 15-min budget
1271
+ * (confirmed live: a POST to the process-run path returned a synchronous 401
1272
+ * from the handler instead of a 202 async ack).
1273
+ *
1274
+ * ⚠️ One Netlify runtime behavior still resolves only on a real deploy: the
1275
+ * routing precedence between this function's `config.path` and Nitro's catch-all
1276
+ * for that exact path. If the catch-all wins, the run still completes via the
1277
+ * 40s soft-timeout path on the sync function (no durable win, no regression).
1278
+ * See docs/design/durable-agent-runs.md (Open risks #1).
1263
1279
  */
1264
1280
  export function emitSingleTemplateNetlifyBackgroundFunction(projectCwd) {
1265
1281
  const functionsDir = path.join(projectCwd, ".netlify", "functions-internal");
@@ -1277,7 +1293,16 @@ export function emitSingleTemplateNetlifyBackgroundFunction(projectCwd) {
1277
1293
  copyDir(serverDir, dest);
1278
1294
  // Drop the original Nitro entry so our background entry is the entrypoint.
1279
1295
  fs.rmSync(path.join(dest, "server.mjs"), { force: true });
1280
- const entry = `let cachedHandler;
1296
+ const entry = `// Mark this isolate as the durable background runtime BEFORE the handler
1297
+ // bundle is imported, so isInBackgroundFunctionRuntime() reliably returns true
1298
+ // in this function. The deployed Lambda name is NOT guaranteed to end in
1299
+ // "-background" (Netlify may mangle/prefix it), so we cannot depend on
1300
+ // AWS_LAMBDA_FUNCTION_NAME alone. A globalThis flag (NOT process.env) avoids the
1301
+ // no-env-mutation guard and carries no cross-request state — it is a static,
1302
+ // set-once isolate marker read back by isInBackgroundFunctionRuntime().
1303
+ globalThis.__AGENT_NATIVE_BACKGROUND_RUNTIME__ = true;
1304
+
1305
+ let cachedHandler;
1281
1306
 
1282
1307
  export default async function handler(...args) {
1283
1308
  cachedHandler ??= (await import("./main.mjs")).default;
@@ -1287,6 +1312,15 @@ export default async function handler(...args) {
1287
1312
  export const config = {
1288
1313
  name: "agent background handler",
1289
1314
  generator: "agent-native build",
1315
+ // background: true is what actually makes Netlify invoke this ASYNCHRONOUSLY
1316
+ // (immediate HTTP 202 ack) with the 15-minute budget. Without it, a function
1317
+ // that declares a custom \`path\` is served SYNCHRONOUSLY (~60s) even when its
1318
+ // file name ends in "-background" — the \`config\` object overrides the legacy
1319
+ // filename convention. That omission is why the durable worker was capped at
1320
+ // ~60s in prod (verified live: POST to the process-run path returned a
1321
+ // synchronous 401 from the handler, not a 202 async ack). See Netlify docs:
1322
+ // build/functions/background-functions + build/functions/configuration.
1323
+ background: true,
1290
1324
  path: ${JSON.stringify([AGENT_CHAT_PROCESS_RUN_PATH])},
1291
1325
  nodeBundler: "none",
1292
1326
  includedFiles: ["**"],
@@ -1686,11 +1720,12 @@ export default bundle;
1686
1720
  copyInstalledResvgPackages(nitro.options.output.serverDir);
1687
1721
  copyInstalledFfmpegStaticPackage(nitro.options.output.serverDir);
1688
1722
  }
1689
- // Durable background agent runs (off by default). Additive ONLY: emits a
1690
- // SECOND Netlify function whose name ends in `-background` re-exporting the
1691
- // same handler bundle, so the chat `_process-run` POST lands on Netlify's
1692
- // async (15-min) function. When the flag is off this is a no-op and the
1693
- // single-function deploy is byte-for-byte unchanged.
1723
+ // Durable background agent runs (default-ON; opt out with a falsy
1724
+ // AGENT_CHAT_DURABLE_BACKGROUND). Additive ONLY: emits a SECOND Netlify
1725
+ // function whose name ends in `-background` re-exporting the same handler
1726
+ // bundle, so the chat `_process-run` POST lands on Netlify's async (15-min)
1727
+ // function. When explicitly opted out this is a no-op and the single-function
1728
+ // deploy is byte-for-byte unchanged.
1694
1729
  if (preset === "netlify" && isDurableBackgroundDeployEnabled()) {
1695
1730
  try {
1696
1731
  emitSingleTemplateNetlifyBackgroundFunction(cwd);