@agent-native/core 0.146.4 → 0.146.6

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 (113) hide show
  1. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +1 -1
  2. package/corpus/templates/analytics/app/components/layout/Layout.tsx +1 -1
  3. package/corpus/templates/analytics/app/pages/Settings.tsx +5 -1
  4. package/corpus/templates/analytics/app/routes/agent.tsx +7 -5
  5. package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +13 -9
  6. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +69 -33
  7. package/corpus/templates/assets/app/components/layout/Layout.tsx +1 -1
  8. package/corpus/templates/assets/app/routes/agent.tsx +7 -5
  9. package/corpus/templates/assets/app/routes/settings.tsx +7 -2
  10. package/corpus/templates/assets/server/plugins/creative-context.ts +1 -1
  11. package/corpus/templates/brain/app/components/layout/Layout.tsx +1 -1
  12. package/corpus/templates/brain/app/lib/brain.ts +4 -2
  13. package/corpus/templates/brain/app/root.tsx +1 -1
  14. package/corpus/templates/brain/app/routes/agent.tsx +10 -2
  15. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +1 -1
  16. package/corpus/templates/calendar/app/root.tsx +1 -2
  17. package/corpus/templates/calendar/app/routes/_app.agent.tsx +8 -16
  18. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +5 -2
  19. package/corpus/templates/chat/app/routes/agent.tsx +7 -31
  20. package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
  21. package/corpus/templates/clips/app/root.tsx +1 -2
  22. package/corpus/templates/clips/app/routes/_app.agent.tsx +9 -7
  23. package/corpus/templates/content/app/components/layout/Layout.tsx +1 -1
  24. package/corpus/templates/content/app/root.tsx +1 -2
  25. package/corpus/templates/content/app/routes/_app.agent.tsx +9 -8
  26. package/corpus/templates/content/app/routes/_app.settings.tsx +7 -2
  27. package/corpus/templates/content/server/plugins/creative-context.ts +1 -1
  28. package/corpus/templates/crm/app/components/crm/RecordActions.tsx +4 -1
  29. package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +1 -1
  30. package/corpus/templates/crm/app/routes/agent.tsx +10 -2
  31. package/corpus/templates/design/app/components/layout/Layout.tsx +1 -1
  32. package/corpus/templates/design/app/root.tsx +1 -1
  33. package/corpus/templates/design/app/routes/agent.tsx +9 -7
  34. package/corpus/templates/design/app/routes/settings.tsx +7 -2
  35. package/corpus/templates/design/server/plugins/creative-context.ts +1 -1
  36. package/corpus/templates/dispatch/app/root.tsx +5 -2
  37. package/corpus/templates/dispatch/app/routes/agent.tsx +7 -7
  38. package/corpus/templates/factory/app/components/layout/Layout.tsx +1 -1
  39. package/corpus/templates/factory/app/hooks/use-navigation-state.ts +5 -2
  40. package/corpus/templates/factory/app/root.tsx +1 -1
  41. package/corpus/templates/factory/app/routes/agent.tsx +9 -14
  42. package/corpus/templates/forms/app/components/layout/Layout.tsx +1 -1
  43. package/corpus/templates/forms/app/root.tsx +1 -1
  44. package/corpus/templates/forms/app/routes/_app.agent.tsx +9 -7
  45. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +5 -3
  46. package/corpus/templates/macros/app/root.tsx +1 -1
  47. package/corpus/templates/macros/app/routes/agent.tsx +9 -6
  48. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +8 -2
  49. package/corpus/templates/mail/app/components/layout/CommandPalette.tsx +1 -1
  50. package/corpus/templates/mail/app/routes/agent.tsx +9 -6
  51. package/corpus/templates/plan/app/components/layout/Layout.tsx +1 -1
  52. package/corpus/templates/plan/app/root.tsx +1 -1
  53. package/corpus/templates/plan/app/routes/agent.tsx +9 -6
  54. package/corpus/templates/slides/app/components/editor/ImageGenPanel.tsx +8 -12
  55. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +39 -2
  56. package/corpus/templates/slides/app/components/layout/Layout.tsx +1 -1
  57. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  58. package/corpus/templates/slides/app/lib/create-deck-generation.ts +22 -5
  59. package/corpus/templates/slides/app/pages/Index.tsx +20 -5
  60. package/corpus/templates/slides/app/root.tsx +1 -1
  61. package/corpus/templates/slides/app/routes/agent.tsx +6 -9
  62. package/corpus/templates/slides/app/routes/settings.tsx +7 -2
  63. package/corpus/templates/slides/server/plugins/creative-context.ts +1 -1
  64. package/corpus/templates/tasks/app/components/layout/Layout.tsx +1 -1
  65. package/corpus/templates/tasks/app/routes/agent.tsx +10 -2
  66. package/dist/client/index.d.ts +1 -1
  67. package/dist/client/navigation/index.d.ts +1 -1
  68. package/dist/client/navigation/index.js +1 -1
  69. package/dist/client/org/OrgSwitcher.js +1 -1
  70. package/dist/client/settings/SettingsPanel.d.ts +8 -0
  71. package/dist/client/settings/SettingsPanel.js +16 -1
  72. package/dist/client/settings/index.d.ts +1 -1
  73. package/dist/collab/awareness.d.ts +2 -2
  74. package/dist/collab/routes.d.ts +1 -1
  75. package/dist/deploy/build.d.ts +21 -0
  76. package/dist/deploy/build.js +185 -10
  77. package/dist/jobs/background-automation-runner.d.ts +1 -1
  78. package/dist/jobs/background-automation-runner.js +1 -1
  79. package/dist/jobs/scheduler-health.d.ts +4 -0
  80. package/dist/jobs/scheduler-health.js +33 -0
  81. package/dist/localization/server.d.ts +0 -1
  82. package/dist/localization/server.js +3 -1
  83. package/dist/mcp-client/index.d.ts +1 -1
  84. package/dist/mcp-client/index.js +1 -1
  85. package/dist/mcp-client/routes.d.ts +11 -0
  86. package/dist/mcp-client/routes.js +26 -1
  87. package/dist/navigation/index.d.ts +1 -0
  88. package/dist/navigation/index.js +34 -0
  89. package/dist/notifications/routes.d.ts +2 -2
  90. package/dist/observability/routes.d.ts +3 -3
  91. package/dist/provider-api/actions/custom-provider-registration.d.ts +6 -6
  92. package/dist/provider-api/actions/provider-api.d.ts +5 -5
  93. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  94. package/dist/secrets/routes.d.ts +6 -6
  95. package/dist/server/agent-chat/mcp-glue.js +12 -3
  96. package/dist/server/agent-chat-plugin.js +73 -48
  97. package/dist/server/http-response-telemetry.js +112 -5
  98. package/dist/server/realtime-token.d.ts +1 -1
  99. package/dist/server/release-migrations.js +2 -0
  100. package/dist/server/ssr-handler.js +8 -0
  101. package/dist/server/transcribe-voice.d.ts +1 -1
  102. package/dist/templates/chat/app/hooks/use-navigation-state.ts +5 -2
  103. package/dist/templates/chat/app/routes/agent.tsx +7 -31
  104. package/dist/templates/default/app/routes/_index.tsx +1 -1
  105. package/dist/templates/default/app/routes/agent.tsx +7 -25
  106. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +54 -3
  107. package/dist/vite/client.js +5 -1
  108. package/package.json +1 -1
  109. package/src/templates/chat/app/hooks/use-navigation-state.ts +5 -2
  110. package/src/templates/chat/app/routes/agent.tsx +7 -31
  111. package/src/templates/default/app/routes/_index.tsx +1 -1
  112. package/src/templates/default/app/routes/agent.tsx +7 -25
  113. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +54 -3
@@ -3,8 +3,10 @@ name: performance
3
3
  description: >-
4
4
  Keep apps and templates loading fast. Read when adding a data model, a
5
5
  list/read action, a page or sidebar that loads data, or when something loads
6
- slowly. Covers column projection, indexing hot-path queries, avoiding N+1 and
7
- round-trip waterfalls, cheap polling, and not recomputing on every read.
6
+ slowly, or when adding a dependency to the deployed server bundle. Covers
7
+ column projection, indexing hot-path queries, avoiding N+1 and round-trip
8
+ waterfalls, cheap polling, not recomputing on every read, and cold-start
9
+ artifact size.
8
10
  scope: dev
9
11
  metadata:
10
12
  internal: true
@@ -146,7 +148,9 @@ just one.
146
148
 
147
149
  If you're debugging a slow first response, check whether something
148
150
  re-personalized the shell before concluding the render itself is slow — the
149
- fix is client-side data loading after the shell paints, never per-user SSR.
151
+ fix is client-side data loading after the shell paints, never per-user SSR. If
152
+ the shell is clean and a cold miss is still seconds long, the cost is upstream
153
+ of the render: see §9.
150
154
  See the `authentication` skill for the full model and `guard:ssr-cache-shell`
151
155
  plus `ssr-handler.spec.ts` (`packages/core/src/server/ssr-handler.ts`) for the
152
156
  enforced contract.
@@ -231,6 +235,50 @@ await backfillOneRow(); // guard:allow-boot-data-work — single row, bounded
231
235
  branch adds. It cannot see everything — a helper that hides the work one call
232
236
  deeper reads as innocent — so the rule matters more than the check.
233
237
 
238
+ ## 9. Cold start is the artifact, not just the work it does
239
+
240
+ §8 covers what the process does at boot. This covers how much there is to boot.
241
+ Measured in production: a cold cache miss on `www.agent-native.com` returned in
242
+ **4.5–6.0s** while the in-handler `server-timing: app;dur` was only **~2100ms** —
243
+ the other ~2900ms is platform init, spent before any of our code evaluates. A
244
+ different app with a healthy database measured **13.4s** TTFB on its first cold
245
+ request with `app;dur=1338`, so ~12s of init. Platform init scales with the size
246
+ of the deployed artifact. Every app pays it, and no query tuning can reach it.
247
+
248
+ - **The `/*` page function is the one every visitor's cache miss wakes.** Nothing
249
+ belongs in it that a page render cannot call. Headless browsers, ffmpeg, image
250
+ rasterizers, and other heavy runtimes belong in the function that actually
251
+ invokes them, or behind a job — not in the default handler. PR #2684, titled
252
+ "Harden auth and cold-start data paths", put 78MB of headless Chromium into
253
+ every page function; nothing in the diff looked like a performance change.
254
+ - **Each extra emitted function is a full second copy of the bundle.** Netlify
255
+ copies the whole server directory per function, so splitting out a
256
+ `-background` or per-route function multiplies existing weight rather than
257
+ dividing it. Trim the artifact before you split it.
258
+ - **Already-compressed binaries do not shrink again in the deploy zip.** A
259
+ Brotli-packed browser or a static ffmpeg build costs close to its full size in
260
+ upload and in cold-start extraction. Budget from bytes on disk, never from an
261
+ assumption that compression will absorb it.
262
+ - **Never resolve a copied dependency by walking ancestor `node_modules`.** In a
263
+ monorepo that walk does not fail — it finds a sibling app's copy and ships
264
+ that. Resolve from the app's own dependency root and throw when it is missing;
265
+ a silently-found wrong package is precisely the indistinguishable-from-success
266
+ failure this repo bans.
267
+
268
+ `packages/core/src/deploy/build.ts` is what decides all of this: the
269
+ platform/arch filter at `:2384-2410` and the per-preset copy list at
270
+ `:4499-4504`. Adding a package there adds it to every page function.
271
+
272
+ **Measure a built bundle by timing the import and forcing exit.** Never measure
273
+ by waiting for the process to exit — module scope starts timers and opens
274
+ handles, so process lifetime measures those, not boot cost. That exact mistake
275
+ produced a wrong number during the investigation behind this section.
276
+
277
+ ```sh
278
+ node -e 'const t=Date.now();import(process.argv[1]).then(()=>{console.log(`${Date.now()-t}ms`);process.exit(0)})' \
279
+ ./.netlify/functions-internal/server/main.mjs
280
+ ```
281
+
234
282
  ## Checklist — run before shipping a list/read or a new table
235
283
 
236
284
  - [ ] List selects only displayed columns; heavy blobs excluded or `substr`-truncated.
@@ -246,3 +294,6 @@ deeper reads as innocent — so the rule matters more than the check.
246
294
  aggregations and re-syncs run on every cold start there (see §8).
247
295
  - [ ] Mutation-fresh reads go through actions + `useActionQuery`, not SSR loader
248
296
  data.
297
+ - [ ] No heavy runtime (browser, ffmpeg, rasterizer) added to what the `/*` page
298
+ function ships, and no new copied dependency resolved by walking ancestor
299
+ `node_modules` (see §9).
@@ -2547,7 +2547,11 @@ const DEFAULT_VITE_WATCH_IGNORES = [
2547
2547
  function forceServeOnly(pluginOrPreset) {
2548
2548
  if (Array.isArray(pluginOrPreset))
2549
2549
  return pluginOrPreset.map(forceServeOnly);
2550
- return { ...pluginOrPreset, apply: "serve" };
2550
+ return {
2551
+ ...pluginOrPreset,
2552
+ apply: (_config, configEnv) => configEnv.command === "serve" &&
2553
+ !(configEnv.isPreview && process.env.IS_RR_BUILD_REQUEST === "yes"),
2554
+ };
2551
2555
  }
2552
2556
  function nitroPresetMarkerPlugin(options) {
2553
2557
  const preset = options.nitro?.preset;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.146.4",
3
+ "version": "0.146.6",
4
4
  "description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -42,7 +42,10 @@ function viewForPath(pathname: string): string {
42
42
  if (pathname.startsWith("/database")) return "database";
43
43
  if (pathname.startsWith("/extensions")) return "extensions";
44
44
  if (pathname.startsWith("/observability")) return "observability";
45
- if (pathname.startsWith("/agent")) return "agent";
45
+ if (pathname.startsWith("/settings/agent") || pathname.startsWith("/agent")) {
46
+ return "agent";
47
+ }
48
+ if (pathname.startsWith("/settings")) return "settings";
46
49
  if (pathname.startsWith("/team")) return "settings";
47
50
  return "chat";
48
51
  }
@@ -60,7 +63,7 @@ function pathForView(view?: string): string {
60
63
  case "observability":
61
64
  return "/observability";
62
65
  case "agent":
63
- return "/agent";
66
+ return "/settings/agent";
64
67
  case "settings":
65
68
  return "/settings";
66
69
  case "team":
@@ -1,5 +1,4 @@
1
- import { useT } from "@agent-native/core/client/i18n";
2
- import { useSetPageTitle } from "@agent-native/toolkit/app-shell";
1
+ import { buildLegacyAgentSettingsRoute } from "@agent-native/core/client/navigation";
3
2
  import { Navigate, useLocation } from "react-router";
4
3
 
5
4
  export function meta() {
@@ -7,34 +6,11 @@ export function meta() {
7
6
  }
8
7
 
9
8
  export default function AgentRoute() {
10
- const t = useT();
11
9
  const location = useLocation();
12
- useSetPageTitle(t("settings.agentTitle"));
13
-
14
- const legacyTab = location.hash.replace(/^#/, "").toLowerCase();
15
- const resourceTabs = new Set([
16
- "files",
17
- "instructions",
18
- "agents",
19
- "memory",
20
- "skills",
21
- "learnings",
22
- ]);
23
- const destination = resourceTabs.has(legacyTab)
24
- ? `/settings/agent/resources/${legacyTab}`
25
- : legacyTab === "remote-agents"
26
- ? "/settings/agent/agents"
27
- : legacyTab === "connections"
28
- ? "/settings/integrations"
29
- : legacyTab === "jobs"
30
- ? "/settings/agent/automations"
31
- : legacyTab === "access"
32
- ? "/settings/agent"
33
- : ["llm", "app-models", "limits", "voice", "background"].includes(
34
- legacyTab,
35
- )
36
- ? `/settings/agent/${legacyTab}`
37
- : "/settings/agent";
38
-
39
- return <Navigate to={destination} replace />;
10
+ return (
11
+ <Navigate
12
+ to={buildLegacyAgentSettingsRoute(location.hash, location.search)}
13
+ replace
14
+ />
15
+ );
40
16
  }
@@ -76,7 +76,7 @@ export default function IndexPage() {
76
76
  </p>
77
77
  </Link>
78
78
  <Link
79
- to="/agent"
79
+ to="/settings/agent"
80
80
  className="group rounded-lg border border-border/50 px-4 py-3 hover:bg-accent/50 transition-colors"
81
81
  >
82
82
  <p className="text-[13px] font-medium text-foreground">
@@ -1,34 +1,16 @@
1
- import { AgentTabsPage } from "@agent-native/core/client/agent-chat";
2
- import { useT } from "@agent-native/core/client/i18n";
3
- import { Link } from "react-router";
1
+ import { buildLegacyAgentSettingsRoute } from "@agent-native/core/client/navigation";
2
+ import { Navigate, useLocation } from "react-router";
4
3
 
5
4
  export function meta() {
6
5
  return [{ title: "Agent - {{APP_TITLE}}" }];
7
6
  }
8
7
 
9
8
  export default function AgentPage() {
10
- const t = useT();
11
-
9
+ const location = useLocation();
12
10
  return (
13
- <main className="min-h-screen bg-background px-6 py-10">
14
- <div className="mx-auto w-full max-w-5xl space-y-6">
15
- <div className="space-y-2">
16
- <Link
17
- to="/settings"
18
- className="text-[13px] text-muted-foreground hover:text-foreground"
19
- >
20
- {t("settings.title")}
21
- </Link>
22
- <h1 className="text-2xl font-semibold tracking-tight text-foreground">
23
- {t("settings.agentTitle")}
24
- </h1>
25
- <p className="text-[14px] leading-relaxed text-muted-foreground">
26
- {t("settings.agentDescription")}
27
- </p>
28
- </div>
29
-
30
- <AgentTabsPage className="min-h-[640px] rounded-lg border border-border/50" />
31
- </div>
32
- </main>
11
+ <Navigate
12
+ to={buildLegacyAgentSettingsRoute(location.hash, location.search)}
13
+ replace
14
+ />
33
15
  );
34
16
  }
@@ -3,8 +3,10 @@ name: performance
3
3
  description: >-
4
4
  Keep apps and templates loading fast. Read when adding a data model, a
5
5
  list/read action, a page or sidebar that loads data, or when something loads
6
- slowly. Covers column projection, indexing hot-path queries, avoiding N+1 and
7
- round-trip waterfalls, cheap polling, and not recomputing on every read.
6
+ slowly, or when adding a dependency to the deployed server bundle. Covers
7
+ column projection, indexing hot-path queries, avoiding N+1 and round-trip
8
+ waterfalls, cheap polling, not recomputing on every read, and cold-start
9
+ artifact size.
8
10
  scope: dev
9
11
  metadata:
10
12
  internal: true
@@ -146,7 +148,9 @@ just one.
146
148
 
147
149
  If you're debugging a slow first response, check whether something
148
150
  re-personalized the shell before concluding the render itself is slow — the
149
- fix is client-side data loading after the shell paints, never per-user SSR.
151
+ fix is client-side data loading after the shell paints, never per-user SSR. If
152
+ the shell is clean and a cold miss is still seconds long, the cost is upstream
153
+ of the render: see §9.
150
154
  See the `authentication` skill for the full model and `guard:ssr-cache-shell`
151
155
  plus `ssr-handler.spec.ts` (`packages/core/src/server/ssr-handler.ts`) for the
152
156
  enforced contract.
@@ -231,6 +235,50 @@ await backfillOneRow(); // guard:allow-boot-data-work — single row, bounded
231
235
  branch adds. It cannot see everything — a helper that hides the work one call
232
236
  deeper reads as innocent — so the rule matters more than the check.
233
237
 
238
+ ## 9. Cold start is the artifact, not just the work it does
239
+
240
+ §8 covers what the process does at boot. This covers how much there is to boot.
241
+ Measured in production: a cold cache miss on `www.agent-native.com` returned in
242
+ **4.5–6.0s** while the in-handler `server-timing: app;dur` was only **~2100ms** —
243
+ the other ~2900ms is platform init, spent before any of our code evaluates. A
244
+ different app with a healthy database measured **13.4s** TTFB on its first cold
245
+ request with `app;dur=1338`, so ~12s of init. Platform init scales with the size
246
+ of the deployed artifact. Every app pays it, and no query tuning can reach it.
247
+
248
+ - **The `/*` page function is the one every visitor's cache miss wakes.** Nothing
249
+ belongs in it that a page render cannot call. Headless browsers, ffmpeg, image
250
+ rasterizers, and other heavy runtimes belong in the function that actually
251
+ invokes them, or behind a job — not in the default handler. PR #2684, titled
252
+ "Harden auth and cold-start data paths", put 78MB of headless Chromium into
253
+ every page function; nothing in the diff looked like a performance change.
254
+ - **Each extra emitted function is a full second copy of the bundle.** Netlify
255
+ copies the whole server directory per function, so splitting out a
256
+ `-background` or per-route function multiplies existing weight rather than
257
+ dividing it. Trim the artifact before you split it.
258
+ - **Already-compressed binaries do not shrink again in the deploy zip.** A
259
+ Brotli-packed browser or a static ffmpeg build costs close to its full size in
260
+ upload and in cold-start extraction. Budget from bytes on disk, never from an
261
+ assumption that compression will absorb it.
262
+ - **Never resolve a copied dependency by walking ancestor `node_modules`.** In a
263
+ monorepo that walk does not fail — it finds a sibling app's copy and ships
264
+ that. Resolve from the app's own dependency root and throw when it is missing;
265
+ a silently-found wrong package is precisely the indistinguishable-from-success
266
+ failure this repo bans.
267
+
268
+ `packages/core/src/deploy/build.ts` is what decides all of this: the
269
+ platform/arch filter at `:2384-2410` and the per-preset copy list at
270
+ `:4499-4504`. Adding a package there adds it to every page function.
271
+
272
+ **Measure a built bundle by timing the import and forcing exit.** Never measure
273
+ by waiting for the process to exit — module scope starts timers and opens
274
+ handles, so process lifetime measures those, not boot cost. That exact mistake
275
+ produced a wrong number during the investigation behind this section.
276
+
277
+ ```sh
278
+ node -e 'const t=Date.now();import(process.argv[1]).then(()=>{console.log(`${Date.now()-t}ms`);process.exit(0)})' \
279
+ ./.netlify/functions-internal/server/main.mjs
280
+ ```
281
+
234
282
  ## Checklist — run before shipping a list/read or a new table
235
283
 
236
284
  - [ ] List selects only displayed columns; heavy blobs excluded or `substr`-truncated.
@@ -246,3 +294,6 @@ deeper reads as innocent — so the rule matters more than the check.
246
294
  aggregations and re-syncs run on every cold start there (see §8).
247
295
  - [ ] Mutation-fresh reads go through actions + `useActionQuery`, not SSR loader
248
296
  data.
297
+ - [ ] No heavy runtime (browser, ffmpeg, rasterizer) added to what the `/*` page
298
+ function ships, and no new copied dependency resolved by walking ancestor
299
+ `node_modules` (see §9).