@agent-native/core 0.211.0 → 0.211.1-nightly-20261020213022

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 (52) hide show
  1. package/dist/cli/template-baseline.js +18 -5
  2. package/dist/cli/template-sync.js +100 -19
  3. package/dist/collab/__fixtures__/live-copy-tasks.d.ts +1 -0
  4. package/dist/collab/__fixtures__/live-copy-tasks.js +92 -0
  5. package/dist/collab/awareness.d.ts +2 -2
  6. package/dist/collab/bounded-task-bundle.d.ts +17 -0
  7. package/dist/collab/bounded-task-bundle.js +39 -0
  8. package/dist/collab/bounded-task-source.d.ts +14 -0
  9. package/dist/collab/bounded-task-source.js +8 -0
  10. package/dist/collab/bounded-tasks.d.ts +67 -0
  11. package/dist/collab/bounded-tasks.js +439 -0
  12. package/dist/collab/index.d.ts +5 -2
  13. package/dist/collab/index.js +5 -2
  14. package/dist/collab/live-copy-tasks.d.ts +80 -0
  15. package/dist/collab/live-copy-tasks.js +330 -0
  16. package/dist/collab/live-copy.d.ts +188 -0
  17. package/dist/collab/live-copy.js +415 -0
  18. package/dist/collab/routes.d.ts +6 -1
  19. package/dist/collab/routes.js +24 -8
  20. package/dist/collab/storage.d.ts +53 -1
  21. package/dist/collab/storage.js +93 -5
  22. package/dist/collab/ydoc-manager.d.ts +92 -3
  23. package/dist/collab/ydoc-manager.js +447 -38
  24. package/dist/db/client.d.ts +6 -0
  25. package/dist/db/client.js +25 -5
  26. package/dist/deploy/build.js +2 -0
  27. package/dist/extensions/actions.js +1 -0
  28. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  29. package/dist/jobs/actions/manage-recurring-job.d.ts +1 -1
  30. package/dist/mcp/agent-connected.js +5 -1
  31. package/dist/mcp/build-server.js +39 -10
  32. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  33. package/dist/org/handlers.d.ts +1 -1
  34. package/dist/org/index.d.ts +1 -1
  35. package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
  36. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  37. package/dist/resources/handlers.d.ts +1 -1
  38. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  39. package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
  40. package/dist/server/collab-plugin.d.ts +10 -1
  41. package/dist/server/collab-plugin.js +89 -20
  42. package/dist/server/realtime-token.d.ts +1 -1
  43. package/dist/shared/optional-node-builtins.d.ts +1 -0
  44. package/dist/shared/optional-node-builtins.js +3 -0
  45. package/dist/tracking/providers.d.ts +1 -0
  46. package/dist/tracking/providers.js +2 -1
  47. package/dist/triggers/actions/manage-automation.d.ts +2 -2
  48. package/dist/vite/bounded-task-plugin.d.ts +22 -0
  49. package/dist/vite/bounded-task-plugin.js +44 -0
  50. package/dist/vite/client.js +2 -0
  51. package/dist/vitest-config.js +3 -0
  52. package/package.json +4 -3
@@ -1,6 +1,7 @@
1
1
  import { defineEventHandler, getMethod, setResponseStatus, } from "h3";
2
2
  import { postAwareness, getActiveUsers } from "../collab/awareness.js";
3
3
  import { getCollabEmitter } from "../collab/emitter.js";
4
+ import { LiveCopyError } from "../collab/live-copy.js";
4
5
  import { getCollabState, postCollabUpdate, postCollabText, postCollabSearchReplace, } from "../collab/routes.js";
5
6
  import { hasCollabState } from "../collab/storage.js";
6
7
  import { postCollabJson, getCollabJson, postCollabPatch, } from "../collab/struct-routes.js";
@@ -98,7 +99,67 @@ export function createCollabSourceSeeder(options) {
98
99
  }
99
100
  };
100
101
  }
102
+ // Worker and capacity failures are the server's, so a client may retry them;
103
+ // a task that broke its contract is a server bug, not a bad edit.
104
+ const RETRYABLE_TASK_FAILURES = new Set([
105
+ "unavailable",
106
+ "closed",
107
+ "queue_full",
108
+ "queue_timeout",
109
+ "deadline_exceeded",
110
+ "memory_exceeded",
111
+ "worker_crashed",
112
+ "startup_failed",
113
+ ]);
114
+ export function liveCopyErrorStatus(error) {
115
+ switch (error.code) {
116
+ case "write_refused":
117
+ case "read_refused":
118
+ case "not_live_copy":
119
+ case "not_seeded":
120
+ case "version_conflict":
121
+ return 409;
122
+ case "state_too_large":
123
+ return 413;
124
+ case "malformed_state":
125
+ case "unsupported_content":
126
+ case "derive_refused":
127
+ case "build_refused":
128
+ return 422;
129
+ case "derive_failed":
130
+ case "build_failed":
131
+ if (RETRYABLE_TASK_FAILURES.has(error.reason ?? ""))
132
+ return 503;
133
+ if (error.reason === "input_too_large" ||
134
+ error.reason === "output_too_large") {
135
+ return 413;
136
+ }
137
+ return 500;
138
+ }
139
+ }
140
+ function collabErrorResponse(event, error) {
141
+ if (error instanceof LiveCopyError) {
142
+ setResponseStatus(event, liveCopyErrorStatus(error));
143
+ return {
144
+ error: error.message,
145
+ code: `live_copy_${error.code}`,
146
+ ...(error.reason !== undefined ? { reason: error.reason } : {}),
147
+ };
148
+ }
149
+ return null;
150
+ }
101
151
  export function createCollabPlugin(options = {}) {
152
+ if ("onContentSync" in options) {
153
+ throw new Error("createCollabPlugin no longer accepts onContentSync; it was never called. Use liveCopy (defineLiveCopy) to derive a document's text when its live copy changes.");
154
+ }
155
+ if (options.liveCopy) {
156
+ if (options.autoSeed !== false) {
157
+ throw new Error("createCollabPlugin liveCopy requires autoSeed: false; seed live copies with seedLiveCopy.");
158
+ }
159
+ if (options.contentType === "json") {
160
+ throw new Error('createCollabPlugin liveCopy derives text from an XML fragment and cannot be combined with contentType: "json".');
161
+ }
162
+ }
102
163
  const normalizedAccess = normalizeCollabAccess(options);
103
164
  const { table = "documents", contentColumn = "content", idColumn = "id", autoSeed = true, maxPayloadBytes = DEFAULT_MAX_PAYLOAD_BYTES, } = options;
104
165
  const resolveSourceIdFromCollabDocumentId = options.resolveSourceIdFromCollabDocumentId ?? ((docId) => docId);
@@ -355,26 +416,34 @@ export function createCollabPlugin(options = {}) {
355
416
  (action === "search-replace" && method === "POST") ||
356
417
  (action === "json" && (method === "GET" || method === "POST")) ||
357
418
  (action === "patch" && method === "POST");
358
- if (needsSeed)
359
- await ensureDocumentSeeded(docId);
360
- if (action === "state" && method === "GET")
361
- return getCollabState(event);
362
- if (action === "update" && method === "POST")
363
- return postCollabUpdate(event);
364
- if (action === "text" && method === "POST")
365
- return postCollabText(event);
366
- if (action === "search-replace" && method === "POST")
367
- return postCollabSearchReplace(event);
368
- if (action === "json" && method === "POST")
369
- return postCollabJson(event);
370
- if (action === "json" && method === "GET")
371
- return getCollabJson(event);
372
- if (action === "patch" && method === "POST")
373
- return postCollabPatch(event);
374
- if (action === "awareness" && method === "POST")
375
- return postAwareness(event);
376
- if (action === "users" && method === "GET")
377
- return getActiveUsers(event);
419
+ try {
420
+ if (needsSeed)
421
+ await ensureDocumentSeeded(docId);
422
+ if (action === "state" && method === "GET")
423
+ return await getCollabState(event);
424
+ if (action === "update" && method === "POST")
425
+ return await postCollabUpdate(event);
426
+ if (action === "text" && method === "POST")
427
+ return await postCollabText(event);
428
+ if (action === "search-replace" && method === "POST")
429
+ return await postCollabSearchReplace(event);
430
+ if (action === "json" && method === "POST")
431
+ return await postCollabJson(event);
432
+ if (action === "json" && method === "GET")
433
+ return await getCollabJson(event);
434
+ if (action === "patch" && method === "POST")
435
+ return await postCollabPatch(event);
436
+ if (action === "awareness" && method === "POST")
437
+ return await postAwareness(event);
438
+ if (action === "users" && method === "GET")
439
+ return await getActiveUsers(event);
440
+ }
441
+ catch (error) {
442
+ const response = collabErrorResponse(event, error);
443
+ if (response)
444
+ return response;
445
+ throw error;
446
+ }
378
447
  setResponseStatus(event, 404);
379
448
  return { error: "Not found" };
380
449
  });
@@ -54,8 +54,8 @@ export declare function createRealtimeTokenHandler(): import("h3").EventHandlerW
54
54
  expiresAt?: undefined;
55
55
  ttlSeconds?: undefined;
56
56
  } | {
57
+ error?: undefined;
57
58
  token: string;
58
59
  expiresAt: string;
59
60
  ttlSeconds: number;
60
- error?: undefined;
61
61
  }>>;
@@ -2,4 +2,5 @@ import type { AsyncLocalStorage } from "node:async_hooks";
2
2
  import type { EventEmitter } from "node:events";
3
3
  export type AsyncLocalStorageCtor = new <T>() => AsyncLocalStorage<T>;
4
4
  export declare function getAsyncLocalStorageCtor(): AsyncLocalStorageCtor | undefined;
5
+ export declare function getWorkerThreads(): typeof import("node:worker_threads") | undefined;
5
6
  export declare function createEventEmitter(): EventEmitter;
@@ -11,6 +11,9 @@ function nodeBuiltin(name) {
11
11
  export function getAsyncLocalStorageCtor() {
12
12
  return nodeBuiltin("node:async_hooks")?.AsyncLocalStorage;
13
13
  }
14
+ export function getWorkerThreads() {
15
+ return nodeBuiltin("node:worker_threads");
16
+ }
14
17
  export function createEventEmitter() {
15
18
  const Ctor = nodeBuiltin("node:events")?.EventEmitter;
16
19
  if (Ctor)
@@ -1,2 +1,3 @@
1
+ export declare const AGENT_NATIVE_ANALYTICS_PROVIDER = "agent-native-analytics";
1
2
  export declare function sendPostHogEvent(name: string, properties: Record<string, unknown>, distinctId: string): boolean;
2
3
  export declare function registerBuiltinProviders(): void;
@@ -6,6 +6,7 @@ import { reshapeTrackedExceptionProperties } from "./posthog-exception.js";
6
6
  import { registerTrackingProvider } from "./registry.js";
7
7
  const POSTHOG_DEFAULT_HOST = "https://us.i.posthog.com";
8
8
  const AGENT_NATIVE_ANALYTICS_DEFAULT_ENDPOINT = "https://analytics.agent-native.com/track";
9
+ export const AGENT_NATIVE_ANALYTICS_PROVIDER = "agent-native-analytics";
9
10
  const BATCH_INTERVAL_MS = 10_000;
10
11
  const MAX_BATCH_SIZE = 50;
11
12
  const QUEUE_KEY = Symbol.for("@agent-native/core/tracking.queue");
@@ -323,7 +324,7 @@ function createWebhookProvider(url, authHeader) {
323
324
  function createAgentNativeAnalyticsProvider(publicKey, endpoint) {
324
325
  const flushImmediately = agentNativeAnalyticsFlushesImmediately();
325
326
  return {
326
- name: "agent-native-analytics",
327
+ name: AGENT_NATIVE_ANALYTICS_PROVIDER,
327
328
  acceptsTestIdentityExceptions: true,
328
329
  track(event) {
329
330
  enqueue(endpoint, JSON.stringify({
@@ -13,7 +13,6 @@ declare const _default: import("../../action.js").ActionDefinition<{
13
13
  executionEngine?: string;
14
14
  executionCwd?: string;
15
15
  }, {
16
- deleted?: undefined;
17
16
  created: boolean;
18
17
  name: string;
19
18
  scope: "organization" | "personal";
@@ -24,6 +23,7 @@ declare const _default: import("../../action.js").ActionDefinition<{
24
23
  reasoningEffort: "auto" | "high" | "low" | "max" | "medium" | "minimal" | "none" | "xhigh";
25
24
  webhookPath: string;
26
25
  nextRun: string;
26
+ deleted?: undefined;
27
27
  enabled?: undefined;
28
28
  executionHostId?: undefined;
29
29
  executionEngine?: undefined;
@@ -45,11 +45,11 @@ declare const _default: import("../../action.js").ActionDefinition<{
45
45
  nextRun?: undefined;
46
46
  webhookPath?: undefined;
47
47
  } | {
48
- deleted?: undefined;
49
48
  created?: undefined;
50
49
  scope?: undefined;
51
50
  triggerType?: undefined;
52
51
  event?: undefined;
52
+ deleted?: undefined;
53
53
  name: string;
54
54
  enabled: boolean;
55
55
  schedule: string;
@@ -0,0 +1,22 @@
1
+ interface PluginContext {
2
+ resolve(source: string, importer?: string, options?: {
3
+ skipSelf?: boolean;
4
+ }): Promise<{
5
+ id: string;
6
+ external?: boolean | string;
7
+ } | null>;
8
+ addWatchFile(file: string): void;
9
+ }
10
+ /**
11
+ * `import source from "./tasks.ts?bounded-task"` yields the module bundled
12
+ * into a `BoundedTaskSource` at build time, so deployed servers never run
13
+ * esbuild. Registered for Vite (dev and client builds) and the production
14
+ * Nitro build.
15
+ */
16
+ export declare function boundedTaskSourcePlugin(): {
17
+ name: string;
18
+ enforce: "pre";
19
+ resolveId(this: PluginContext, source: string, importer?: string): Promise<string>;
20
+ load(this: PluginContext, id: string): Promise<string>;
21
+ };
22
+ export {};
@@ -0,0 +1,44 @@
1
+ import path from "node:path";
2
+ import { bundleBoundedTaskSource } from "../collab/bounded-task-bundle.js";
3
+ const QUERY = "?bounded-task";
4
+ const RESOLVED_PREFIX = "\0agent-native-bounded-task:";
5
+ /**
6
+ * `import source from "./tasks.ts?bounded-task"` yields the module bundled
7
+ * into a `BoundedTaskSource` at build time, so deployed servers never run
8
+ * esbuild. Registered for Vite (dev and client builds) and the production
9
+ * Nitro build.
10
+ */
11
+ export function boundedTaskSourcePlugin() {
12
+ return {
13
+ name: "agent-native-bounded-task-source",
14
+ enforce: "pre",
15
+ async resolveId(source, importer) {
16
+ if (!source.endsWith(QUERY))
17
+ return null;
18
+ const request = source.slice(0, -QUERY.length);
19
+ const resolved = await this.resolve(request, importer, {
20
+ skipSelf: true,
21
+ });
22
+ if (!resolved || resolved.external) {
23
+ throw new Error(`Cannot resolve bounded task module ${request}${importer ? ` from ${importer}` : ""}`);
24
+ }
25
+ return RESOLVED_PREFIX + resolved.id.split("?")[0];
26
+ },
27
+ async load(id) {
28
+ if (!id.startsWith(RESOLVED_PREFIX))
29
+ return null;
30
+ const entry = id.slice(RESOLVED_PREFIX.length);
31
+ const bundled = await bundleBoundedTaskSource(entry, {
32
+ name: path.basename(entry).replace(/\.[^.]+$/, ""),
33
+ });
34
+ for (const input of bundled.inputs)
35
+ this.addWatchFile(input);
36
+ const source = {
37
+ kind: bundled.kind,
38
+ name: bundled.name,
39
+ code: bundled.code,
40
+ };
41
+ return `export default Object.freeze(${JSON.stringify(source)});\n`;
42
+ },
43
+ };
44
+ }
@@ -29,6 +29,7 @@ import { AGENT_NATIVE_TYPEGEN_ENV, formatRuntimeConfigReport, getRuntimeConfigRe
29
29
  import { actionTypesPlugin } from "./action-types-plugin.js";
30
30
  import { createAgentNativeConfigContext, loadAgentNativeConfigFile, loadWorkspaceAgentNativeConfigFile, readAgentNativeJsonConfig, resolveFirstRunOnboardingBuildReplacement, resolveHarnessBuildReplacement, writeAgentNativeBuildConfigMarker, } from "./agent-native-config-loader.js";
31
31
  import { agentsBundlePlugin } from "./agents-bundle-plugin.js";
32
+ import { boundedTaskSourcePlugin } from "./bounded-task-plugin.js";
32
33
  import { migrationDiagnosticPlugin } from "./migration-diagnostic-plugin.js";
33
34
  import { motionSourceProvenancePlugin } from "./motion-source-provenance-plugin.js";
34
35
  import { resolveAgentNativePackageVersions } from "./package-versions.js";
@@ -3657,6 +3658,7 @@ function createAgentNativePlugins(options, { command, includeReactTransform, use
3657
3658
  appChangelogRawPlugin(),
3658
3659
  actionTypesPlugin(),
3659
3660
  agentsBundlePlugin({ agentNativeConfig: options.agentNativeConfig }),
3661
+ boundedTaskSourcePlugin(),
3660
3662
  authClientAssetPlugin(cwd),
3661
3663
  autoReloadOnOptimizeDep(),
3662
3664
  fullReloadOnOptimizeDep504(),
@@ -1,3 +1,4 @@
1
+ import { boundedTaskSourcePlugin } from "./vite/bounded-task-plugin.js";
1
2
  const DEFAULT_MAX_WORKERS = "25%";
2
3
  const ENV_KEYS = ["VITEST_CONCURRENCY", "AGENT_NATIVE_VITEST_CONCURRENCY"];
3
4
  export function resolveMaxWorkers(env = process.env, fallback = DEFAULT_MAX_WORKERS) {
@@ -25,6 +26,8 @@ export function resolveMaxWorkers(env = process.env, fallback = DEFAULT_MAX_WORK
25
26
  return count;
26
27
  }
27
28
  const vitestBaseConfig = {
29
+ // App tests import server modules that load `?bounded-task` sources.
30
+ plugins: [boundedTaskSourcePlugin()],
28
31
  test: {
29
32
  maxWorkers: resolveMaxWorkers(),
30
33
  // Vitest's 5 s default only holds while a worker has a core to itself.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.211.0",
3
+ "version": "0.211.1-nightly-20261020213022",
4
4
  "description": "The agentic application framework for building autonomous agents with intuitive UIs",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -403,6 +403,7 @@
403
403
  },
404
404
  "./router": "./dist/router/index.js",
405
405
  "./collab": "./dist/collab/index.js",
406
+ "./collab/live-copy-tasks": "./dist/collab/live-copy-tasks.js",
406
407
  "./a2a": "./dist/a2a/index.js",
407
408
  "./mcp": "./dist/mcp/index.js",
408
409
  "./mcp/fetch": "./dist/mcp/fetch-handler.js",
@@ -711,7 +712,7 @@
711
712
  "yaml": "^2.9.0",
712
713
  "yjs": "^13.6.33",
713
714
  "zod": "^4.3.6",
714
- "@agent-native/agentkit": "^0.211.0",
715
+ "@agent-native/agentkit": "^0.211.1-nightly-20261020213022",
715
716
  "@agent-native/recap-cli": "^0.5.78"
716
717
  },
717
718
  "devDependencies": {
@@ -782,7 +783,7 @@
782
783
  "xlsx": "^0.18.5"
783
784
  },
784
785
  "peerDependencies": {
785
- "@agent-native/core-corpus": ">=0.196.0",
786
+ "@agent-native/core-corpus": "0.211.1-nightly-20261020213022",
786
787
  "@ai-sdk/anthropic": ">=3",
787
788
  "@ai-sdk/cohere": ">=3",
788
789
  "@ai-sdk/google": ">=3",