@agent-native/core 0.222.2 → 0.222.3-nightly-20261030005008

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.
@@ -1,5 +1,10 @@
1
1
  import { z } from "zod";
2
2
  export declare const onboardingConfig: z.ZodObject<{
3
+ firstRunCreditsExperiment: z.ZodDefault<z.ZodEnum<{
4
+ v1: "v1";
5
+ v2: "v2";
6
+ }>>;
7
+ firstRunCreditsExperimentOverride: z.ZodOptional<z.ZodLiteral<"v1">>;
3
8
  sharedCompletion: z.ZodPrefault<z.ZodObject<{
4
9
  enabled: z.ZodDefault<z.ZodBoolean>;
5
10
  }, z.core.$strip>>;
@@ -1,5 +1,10 @@
1
1
  import { z } from "zod";
2
2
  export const onboardingConfig = z.object({
3
+ firstRunCreditsExperiment: z.enum(["v1", "v2"]).default("v1"),
4
+ firstRunCreditsExperimentOverride: z.literal("v1").optional().meta({
5
+ env: "FIRST_RUN_CREDITS_EXPERIMENT",
6
+ doc: "Roll back the first-run credits experiment to v1 for this deployment.",
7
+ }),
3
8
  sharedCompletion: z
4
9
  .object({
5
10
  enabled: z.boolean().default(false).meta({
@@ -160,6 +160,11 @@ export declare const appConfigSchema: z.ZodObject<{
160
160
  inferredSentimentModel: z.ZodDefault<z.ZodString>;
161
161
  }, z.core.$strip>>;
162
162
  onboarding: z.ZodPrefault<z.ZodObject<{
163
+ firstRunCreditsExperiment: z.ZodDefault<z.ZodEnum<{
164
+ v1: "v1";
165
+ v2: "v2";
166
+ }>>;
167
+ firstRunCreditsExperimentOverride: z.ZodOptional<z.ZodLiteral<"v1">>;
163
168
  sharedCompletion: z.ZodPrefault<z.ZodObject<{
164
169
  enabled: z.ZodDefault<z.ZodBoolean>;
165
170
  }, z.core.$strip>>;
@@ -3107,7 +3107,7 @@ export function createAgentKitProtocolAdapter(runtime, options = {}) {
3107
3107
  }
3108
3108
  yield event;
3109
3109
  }
3110
- if (run.streamClosed || run.terminal)
3110
+ if ((run.streamClosed || run.terminal) && !run.cancelling)
3111
3111
  return;
3112
3112
  await notifyWhenChanged(run, signal);
3113
3113
  }
@@ -3310,27 +3310,39 @@ export function createAgentKitProtocolAdapter(runtime, options = {}) {
3310
3310
  const cancellation = cancelCoreTurn(run, "user");
3311
3311
  run.streamClosed = true;
3312
3312
  run.terminal = true;
3313
- let result;
3313
+ // Stopping the turn can end its event stream before the cancel settles,
3314
+ // and the pump wakes readers when it does. Without this hold they would
3315
+ // see a closed run and leave before the cancelled events below exist.
3316
+ run.cancelling = true;
3314
3317
  try {
3315
- result = await cancellation;
3316
- }
3317
- catch (error) {
3318
- run.streamClosed = streamWasClosed;
3319
- run.terminal = false;
3320
- ensurePump(run);
3321
- throw error;
3318
+ let result;
3319
+ try {
3320
+ result = await cancellation;
3321
+ }
3322
+ catch (error) {
3323
+ run.streamClosed = streamWasClosed;
3324
+ run.terminal = false;
3325
+ ensurePump(run);
3326
+ throw error;
3327
+ }
3328
+ if (result.status === "unsupported") {
3329
+ run.streamClosed = streamWasClosed;
3330
+ run.terminal = false;
3331
+ ensurePump(run);
3332
+ throw new Error("The Core runtime does not support run cancellation.");
3333
+ }
3334
+ run.waitingForContinuation = false;
3335
+ delete run.pendingApprovalId;
3336
+ run.terminalSource = "local";
3337
+ run.cancelling = false;
3338
+ append(run, { type: "run.status", status: "cancelled" });
3339
+ append(run, { type: "run.cancelled" });
3322
3340
  }
3323
- if (result.status === "unsupported") {
3324
- run.streamClosed = streamWasClosed;
3325
- run.terminal = false;
3326
- ensurePump(run);
3327
- throw new Error("The Core runtime does not support run cancellation.");
3341
+ finally {
3342
+ run.cancelling = false;
3343
+ for (const listener of run.listeners)
3344
+ listener();
3328
3345
  }
3329
- run.waitingForContinuation = false;
3330
- run.pendingApprovalId = undefined;
3331
- run.terminalSource = "local";
3332
- append(run, { type: "run.status", status: "cancelled" });
3333
- append(run, { type: "run.cancelled" });
3334
3346
  },
3335
3347
  async dispose() {
3336
3348
  if (disposed)
@@ -3343,6 +3355,7 @@ export function createAgentKitProtocolAdapter(runtime, options = {}) {
3343
3355
  for (const run of runs.values()) {
3344
3356
  run.streamClosed = true;
3345
3357
  run.terminal = true;
3358
+ run.cancelling = false;
3346
3359
  run.waitingForContinuation = false;
3347
3360
  run.pendingApprovalId = undefined;
3348
3361
  for (const listener of run.listeners)
@@ -84,27 +84,74 @@ export function splitSqlStatements(sql) {
84
84
  const out = [];
85
85
  let buf = "";
86
86
  let i = 0;
87
- let inSingle = false;
88
87
  while (i < sql.length) {
89
88
  const ch = sql[i];
90
89
  const next = sql[i + 1];
91
- if (!inSingle && ch === "-" && next === "-") {
90
+ if (ch === "-" && next === "-") {
92
91
  while (i < sql.length && sql[i] !== "\n")
93
92
  i++;
94
93
  continue;
95
94
  }
96
- if (ch === "'") {
97
- buf += ch;
98
- if (inSingle && next === "'") {
99
- buf += next;
100
- i += 2;
101
- continue;
95
+ if (ch === "/" && next === "*") {
96
+ const start = i;
97
+ let depth = 1;
98
+ i += 2;
99
+ while (i < sql.length && depth > 0) {
100
+ if (sql.startsWith("/*", i)) {
101
+ depth++;
102
+ i += 2;
103
+ }
104
+ else if (sql.startsWith("*/", i)) {
105
+ depth--;
106
+ i += 2;
107
+ }
108
+ else
109
+ i++;
102
110
  }
103
- inSingle = !inSingle;
104
- i++;
111
+ if (depth)
112
+ throw new Error("Unterminated SQL block comment");
113
+ buf += sql.slice(start, i);
105
114
  continue;
106
115
  }
107
- if (ch === ";" && !inSingle) {
116
+ if (ch === "'" || ch === '"') {
117
+ const start = i++;
118
+ const escaped = ch === "'" &&
119
+ /[eE]/.test(sql[start - 1] ?? "") &&
120
+ !/[\w$\u0080-\uFFFF]/.test(sql[start - 2] ?? "");
121
+ let closed = false;
122
+ while (i < sql.length) {
123
+ if (escaped && sql[i] === "\\") {
124
+ i += 2;
125
+ continue;
126
+ }
127
+ if (sql[i] === ch) {
128
+ if (sql[i + 1] === ch) {
129
+ i += 2;
130
+ continue;
131
+ }
132
+ i++;
133
+ closed = true;
134
+ break;
135
+ }
136
+ i++;
137
+ }
138
+ if (!closed)
139
+ throw new Error("Unterminated SQL quoted value");
140
+ buf += sql.slice(start, i);
141
+ continue;
142
+ }
143
+ if (ch === "$" && !/[\w$\u0080-\uFFFF]/.test(sql[i - 1] ?? "")) {
144
+ const tag = /^\$(?:[A-Za-z_\u0080-\uFFFF][A-Za-z_0-9\u0080-\uFFFF]*)?\$/.exec(sql.slice(i))?.[0];
145
+ if (tag) {
146
+ const end = sql.indexOf(tag, i + tag.length);
147
+ if (end < 0)
148
+ throw new Error("Unterminated SQL dollar quote");
149
+ buf += sql.slice(i, end + tag.length);
150
+ i = end + tag.length;
151
+ continue;
152
+ }
153
+ }
154
+ if (ch === ";") {
108
155
  const trimmed = buf.trim();
109
156
  if (trimmed)
110
157
  out.push(trimmed);
@@ -992,10 +992,7 @@ function patchNetlifyFunctionEntry(functionDir, app, workspaceApps, staticDir, w
992
992
  basePath,
993
993
  `${basePath}.data`,
994
994
  `${basePath}/*`,
995
- ...workspaceOAuthDiscoveryRoutes(app).flatMap(({ path, descendants }) => [
996
- path,
997
- ...(descendants ? [`${path}/*`] : []),
998
- ]),
995
+ ...netlifyOAuthDiscoveryPaths(app),
999
996
  ...rootGoogleCallbackPath,
1000
997
  ];
1001
998
  const normalizeBasePathHelper = app === "dispatch"
@@ -1063,7 +1060,7 @@ export const config = {
1063
1060
  path: ${JSON.stringify(pathConfig)},
1064
1061
  nodeBundler: "none",
1065
1062
  includedFiles: ["**"],
1066
- excludedPath: ${JSON.stringify(netlifyFunctionExcludedPaths(app, staticDir), null, 2)
1063
+ excludedPath: ${JSON.stringify(netlifyFunctionExcludedPaths(app, staticDir, workspaceApps), null, 2)
1067
1064
  .split("\n")
1068
1065
  .join("\n ")},
1069
1066
  preferStatic: false,
@@ -1160,13 +1157,29 @@ export default {
1160
1157
  `;
1161
1158
  fs.writeFileSync(entryPath, entry);
1162
1159
  }
1163
- function netlifyFunctionExcludedPaths(app, staticDir) {
1160
+ function netlifyFunctionExcludedPaths(app, staticDir, workspaceApps) {
1164
1161
  return [
1165
1162
  "/.netlify/*",
1166
1163
  `/${app}/assets/*`,
1167
1164
  ...netlifyPublicAssetPaths(app, staticDir),
1165
+ ...(app === "dispatch" ? netlifyAppOAuthDiscoveryPaths(workspaceApps) : []),
1168
1166
  ];
1169
1167
  }
1168
+ // Netlify does not prefer the most specific function path: when Dispatch's
1169
+ // `/.well-known/*` overlaps an app's exact discovery path, the function whose
1170
+ // name sorts first wins, so apps after "dispatch" got Dispatch's metadata.
1171
+ // Excluding each app's discovery paths from Dispatch leaves one match.
1172
+ function netlifyAppOAuthDiscoveryPaths(workspaceApps) {
1173
+ return workspaceApps
1174
+ .filter((entry) => entry.id !== "dispatch")
1175
+ .flatMap((entry) => netlifyOAuthDiscoveryPaths(entry.id));
1176
+ }
1177
+ function netlifyOAuthDiscoveryPaths(app) {
1178
+ return workspaceOAuthDiscoveryRoutes(app).flatMap(({ path, descendants }) => [
1179
+ path,
1180
+ ...(descendants ? [`${path}/*`] : []),
1181
+ ]);
1182
+ }
1170
1183
  function netlifyPublicAssetPaths(app, staticDir) {
1171
1184
  if (!fs.existsSync(staticDir))
1172
1185
  return [];
@@ -6,5 +6,10 @@ export function resolveOnboardingAppId(explicit) {
6
6
  return normalizeOnboardingAppId(explicit ?? config.app.id ?? config.app.packageName);
7
7
  }
8
8
  export function getOnboardingAppProfile(appId) {
9
- return getOnboardingAppProfileForId(resolveOnboardingAppId(appId));
9
+ const onboarding = getAppConfig().onboarding;
10
+ return {
11
+ ...getOnboardingAppProfileForId(resolveOnboardingAppId(appId)),
12
+ firstRunCreditsExperiment: onboarding.firstRunCreditsExperimentOverride ??
13
+ onboarding.firstRunCreditsExperiment,
14
+ };
10
15
  }
@@ -108,6 +108,7 @@ export interface OnboardingCapability {
108
108
  whyKey?: string;
109
109
  }
110
110
  export interface OnboardingAppProfile {
111
+ firstRunCreditsExperiment?: "v1" | "v2";
111
112
  appId: string;
112
113
  appName: string;
113
114
  capabilities: OnboardingCapability[];
@@ -252,6 +252,10 @@ function emitTrackedEvent(name, properties, source, questionIntakeAssignment) {
252
252
  }
253
253
  }
254
254
  function requestFirstRunExperiment(authUserId) {
255
+ const onboarding = getAppConfig().onboarding;
256
+ if ((onboarding.firstRunCreditsExperimentOverride ??
257
+ onboarding.firstRunCreditsExperiment) !== "v2")
258
+ return null;
255
259
  const assignment = getRequestContext()?.firstRunBuilderCreditsV2Assignment;
256
260
  if (assignment?.authUserId !== authUserId)
257
261
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.222.2",
3
+ "version": "0.222.3-nightly-20261030005008",
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": {
@@ -742,7 +742,7 @@
742
742
  "yaml": "^2.9.0",
743
743
  "yjs": "^13.6.33",
744
744
  "zod": "^4.3.6",
745
- "@agent-native/agentkit": "^0.222.2",
745
+ "@agent-native/agentkit": "^0.222.3-nightly-20261030005008",
746
746
  "@agent-native/recap-cli": "^0.5.93"
747
747
  },
748
748
  "devDependencies": {
@@ -814,7 +814,7 @@
814
814
  "xlsx": "^0.18.5"
815
815
  },
816
816
  "peerDependencies": {
817
- "@agent-native/core-corpus": ">=0.196.0",
817
+ "@agent-native/core-corpus": "0.222.3-nightly-20261030005008",
818
818
  "@ai-sdk/anthropic": ">=3",
819
819
  "@ai-sdk/cohere": ">=3",
820
820
  "@ai-sdk/google": ">=3",