@agent-native/core 0.228.1 → 0.228.2-nightly-20261113152307

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.
@@ -36,18 +36,18 @@ export declare const listComposeDrafts: import("h3").EventHandlerWithFetch<impor
36
36
  export declare const getComposeDraft: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<Record<string, unknown> | null>>;
37
37
  export declare const putComposeDraft: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<any>>;
38
38
  export declare const saveComposeDraft: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
39
+ errorCode?: undefined;
39
40
  value?: undefined;
40
41
  error: string;
41
42
  revision?: undefined;
42
- errorCode?: undefined;
43
43
  details?: undefined;
44
44
  } | {
45
+ errorCode?: undefined;
45
46
  error?: undefined;
46
47
  value: {
47
48
  id: string;
48
49
  };
49
50
  revision: string;
50
- errorCode?: undefined;
51
51
  details?: undefined;
52
52
  } | {
53
53
  value?: undefined;
@@ -13,9 +13,9 @@ export declare const postCollabPatch: import("h3").EventHandlerWithFetch<import(
13
13
  ok: boolean;
14
14
  }>>;
15
15
  export declare const getCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
16
+ data?: undefined;
16
17
  error: string;
17
18
  docId?: undefined;
18
- data?: undefined;
19
19
  } | {
20
20
  error?: undefined;
21
21
  docId: string;
@@ -33,9 +33,9 @@ declare const _default: import("../../action.js").ActionDefinition<{
33
33
  idempotencyKey: string;
34
34
  deleted: boolean;
35
35
  } | {
36
- id?: undefined;
37
36
  error: string;
38
37
  url?: undefined;
38
+ id?: undefined;
39
39
  provider?: undefined;
40
40
  configured?: undefined;
41
41
  } | {
@@ -45,8 +45,8 @@ declare const _default: import("../../action.js").ActionDefinition<{
45
45
  provider: string;
46
46
  configured?: undefined;
47
47
  } | {
48
- id?: undefined;
49
48
  url?: undefined;
49
+ id?: undefined;
50
50
  provider?: undefined;
51
51
  error: string;
52
52
  configured: boolean;
@@ -0,0 +1,42 @@
1
+ export type BuilderGatewayStep = "signed_url" | "session_start" | "complete";
2
+ export interface BuilderGatewayErrorDetails {
3
+ step: BuilderGatewayStep;
4
+ /** HTTP status of the last attempt; 0 when no response arrived. */
5
+ status: number;
6
+ attempts: number;
7
+ /** The last response was an HTML error page, not the gateway's JSON. */
8
+ isHtml: boolean;
9
+ /** One id per attempt sent to Builder; search the upload function's logs by it. */
10
+ traceIds: string[];
11
+ /** Allow-listed response headers of the last failed attempt. */
12
+ headers: Record<string, string>;
13
+ cause?: unknown;
14
+ }
15
+ export declare class BuilderGatewayError extends Error {
16
+ readonly provider = "builder";
17
+ readonly step: BuilderGatewayStep;
18
+ readonly status: number;
19
+ readonly attempts: number;
20
+ readonly isHtml: boolean;
21
+ readonly traceIds: string[];
22
+ readonly headers: Record<string, string>;
23
+ constructor(message: string, details: BuilderGatewayErrorDetails);
24
+ }
25
+ /** Summarize a failed response without keeping a whole HTML error page. */
26
+ export declare function describeErrorBody(res: Response): Promise<{
27
+ detail: string;
28
+ isHtml: boolean;
29
+ }>;
30
+ export interface GatewayRequestInit {
31
+ method: string;
32
+ headers: Record<string, string>;
33
+ body?: BodyInit;
34
+ }
35
+ /**
36
+ * One bounded, observable call to the Builder upload gateway or the storage
37
+ * session it hands out. Retries only failures that say "try again": no
38
+ * response, a gateway 5xx, and the step's own extra statuses. Resolves with
39
+ * the OK response; rejects with `BuilderGatewayError` once the attempts run
40
+ * out or the failure is not retryable.
41
+ */
42
+ export declare function builderGatewayRequest(step: BuilderGatewayStep, url: string, init: GatewayRequestInit): Promise<Response>;
@@ -0,0 +1,185 @@
1
+ import { randomUUID } from "node:crypto";
2
+ export class BuilderGatewayError extends Error {
3
+ provider = "builder";
4
+ step;
5
+ status;
6
+ attempts;
7
+ isHtml;
8
+ traceIds;
9
+ headers;
10
+ constructor(message, details) {
11
+ super(message, details.cause === undefined ? undefined : { cause: details.cause });
12
+ this.name = "BuilderGatewayError";
13
+ this.step = details.step;
14
+ this.status = details.status;
15
+ this.attempts = details.attempts;
16
+ this.isHtml = details.isHtml;
17
+ this.traceIds = details.traceIds;
18
+ this.headers = details.headers;
19
+ }
20
+ }
21
+ const BACKOFF_FACTOR = 3;
22
+ // The signed-URL and session-start requests are tiny and answer in well under
23
+ // a second, so their 15 s cap lets every attempt fit inside one serverless
24
+ // request; a slow answer is retried instead of waited on.
25
+ const GATEWAY_POLICIES = {
26
+ signed_url: {
27
+ label: "Builder.io signed-URL request failed",
28
+ attempts: 3,
29
+ baseDelayMs: 500,
30
+ timeoutMs: 15_000,
31
+ retryStatuses: new Set([502, 503, 504]),
32
+ retryOnTimeout: true,
33
+ traced: true,
34
+ },
35
+ session_start: {
36
+ label: "GCS resumable session initiation failed",
37
+ attempts: 3,
38
+ baseDelayMs: 500,
39
+ timeoutMs: 15_000,
40
+ retryStatuses: new Set([408, 429, 500, 502, 503, 504]),
41
+ retryOnTimeout: true,
42
+ traced: false,
43
+ },
44
+ // Completing a stable video can include server-side compression, so this
45
+ // keeps the long timeout and never retries after our own timeout: that retry
46
+ // would race the first attempt. A 409 is that race from elsewhere (a
47
+ // duplicate in flight); the next call returns the registered asset.
48
+ complete: {
49
+ label: "Builder.io upload complete failed",
50
+ attempts: 4,
51
+ baseDelayMs: 500,
52
+ timeoutMs: 120_000,
53
+ retryStatuses: new Set([409, 502, 503, 504]),
54
+ retryOnTimeout: false,
55
+ traced: true,
56
+ },
57
+ };
58
+ // Response headers that say which layer answered; never request headers,
59
+ // which carry the Authorization token.
60
+ const DIAGNOSTIC_RESPONSE_HEADERS = [
61
+ "server",
62
+ "via",
63
+ "x-served-by",
64
+ "x-cache",
65
+ "x-cloud-trace-context",
66
+ "x-amz-cf-id",
67
+ "x-amz-cf-pop",
68
+ "cf-ray",
69
+ "retry-after",
70
+ "content-type",
71
+ "date",
72
+ ];
73
+ function snapshotResponseHeaders(headers) {
74
+ const snapshot = {};
75
+ for (const name of DIAGNOSTIC_RESPONSE_HEADERS) {
76
+ const value = headers.get(name);
77
+ if (value)
78
+ snapshot[name] = value;
79
+ }
80
+ return snapshot;
81
+ }
82
+ /** Summarize a failed response without keeping a whole HTML error page. */
83
+ export async function describeErrorBody(res) {
84
+ let raw;
85
+ try {
86
+ raw = await res.text();
87
+ }
88
+ catch {
89
+ return {
90
+ detail: `${res.statusText || "no status text"} (response body unreadable)`,
91
+ isHtml: false,
92
+ };
93
+ }
94
+ const isHtml = /text\/html/i.test(res.headers.get("content-type") ?? "") ||
95
+ /^\s*<(?:!doctype\s+html|html)\b/i.test(raw);
96
+ if (isHtml) {
97
+ return { detail: "HTML error page returned instead of JSON", isHtml: true };
98
+ }
99
+ const text = raw.trim();
100
+ return { detail: text ? text.slice(0, 500) : res.statusText, isHtml: false };
101
+ }
102
+ async function sendOnce(url, init, policy, traceId) {
103
+ const controller = new AbortController();
104
+ let timedOut = false;
105
+ const timer = setTimeout(() => {
106
+ timedOut = true;
107
+ controller.abort();
108
+ }, policy.timeoutMs);
109
+ try {
110
+ const response = await fetch(url, {
111
+ ...init,
112
+ headers: traceId
113
+ ? { ...init.headers, "X-Cloud-Trace-Context": `${traceId}/1;o=1` }
114
+ : init.headers,
115
+ signal: controller.signal,
116
+ });
117
+ return { kind: "response", response };
118
+ }
119
+ catch (error) {
120
+ return { kind: "network", error, timedOut };
121
+ }
122
+ finally {
123
+ clearTimeout(timer);
124
+ }
125
+ }
126
+ /**
127
+ * One bounded, observable call to the Builder upload gateway or the storage
128
+ * session it hands out. Retries only failures that say "try again": no
129
+ * response, a gateway 5xx, and the step's own extra statuses. Resolves with
130
+ * the OK response; rejects with `BuilderGatewayError` once the attempts run
131
+ * out or the failure is not retryable.
132
+ */
133
+ export async function builderGatewayRequest(step, url, init) {
134
+ const policy = GATEWAY_POLICIES[step];
135
+ const traceIds = [];
136
+ for (let attempt = 1;; attempt++) {
137
+ const startedAt = Date.now();
138
+ const traceId = policy.traced ? randomUUID().replaceAll("-", "") : null;
139
+ if (traceId)
140
+ traceIds.push(traceId);
141
+ const result = await sendOnce(url, init, policy, traceId);
142
+ const elapsedMs = Date.now() - startedAt;
143
+ if (result.kind === "response" && result.response.ok) {
144
+ if (attempt > 1) {
145
+ console.log(`[builder-upload] ${step} recovered on attempt ${attempt}/${policy.attempts}`, { elapsedMs, traceId });
146
+ }
147
+ return result.response;
148
+ }
149
+ let status = 0;
150
+ let isHtml = false;
151
+ let detail;
152
+ let headers = {};
153
+ let retryable;
154
+ if (result.kind === "response") {
155
+ status = result.response.status;
156
+ headers = snapshotResponseHeaders(result.response.headers);
157
+ ({ detail, isHtml } = await describeErrorBody(result.response));
158
+ retryable = policy.retryStatuses.has(status);
159
+ }
160
+ else {
161
+ detail = result.timedOut
162
+ ? `timed out after ${policy.timeoutMs} ms`
163
+ : result.error instanceof Error
164
+ ? result.error.message
165
+ : String(result.error);
166
+ retryable = result.timedOut ? policy.retryOnTimeout : true;
167
+ }
168
+ const willRetry = retryable && attempt < policy.attempts;
169
+ console.warn(`[builder-upload] ${step} attempt ${attempt}/${policy.attempts} failed${willRetry ? ", retrying" : ""}`, { status: status || "no response", elapsedMs, traceId, headers });
170
+ if (!willRetry) {
171
+ throw new BuilderGatewayError(`${policy.label} (${status || "no response"}): ${detail}`, {
172
+ step,
173
+ status,
174
+ attempts: attempt,
175
+ isHtml,
176
+ traceIds,
177
+ headers,
178
+ cause: result.kind === "network" ? result.error : undefined,
179
+ });
180
+ }
181
+ // Jitter keeps a burst of retrying recordings from landing together.
182
+ const delayMs = policy.baseDelayMs * BACKOFF_FACTOR ** (attempt - 1);
183
+ await new Promise((resolve) => setTimeout(resolve, Math.round(delayMs * (0.75 + Math.random() * 0.5))));
184
+ }
185
+ }
@@ -1,3 +1,4 @@
1
+ import { builderGatewayRequest, describeErrorBody } from "./builder-gateway.js";
1
2
  const DEFAULT_BUILDER_APP_HOST = "https://builder.io";
2
3
  const LARGE_FILE_THRESHOLD_BYTES = 30 * 1024 * 1024;
3
4
  const UPLOAD_TIMEOUT_MS = 120_000;
@@ -44,8 +45,10 @@ function setRecordAssetQueryParam(url, recordAsset) {
44
45
  }
45
46
  async function assertOk(res, label) {
46
47
  if (!res.ok) {
47
- const body = await res.text().catch(() => "");
48
- throw Object.assign(new Error(`${label} (${res.status}): ${body || res.statusText}`), { status: res.status });
48
+ const { detail } = await describeErrorBody(res);
49
+ throw Object.assign(new Error(`${label} (${res.status}): ${detail}`), {
50
+ status: res.status,
51
+ });
49
52
  }
50
53
  }
51
54
  function confirmedBuilderAuthorizationFailure(error) {
@@ -116,7 +119,7 @@ async function requestBuilderSignedUrl(authorization, apiKey, filename, mimeType
116
119
  const url = new URL("/api/v1/upload/signed-url", host);
117
120
  if (apiKey)
118
121
  url.searchParams.set("apiKey", apiKey);
119
- const res = await fetchWithTimeout(url.toString(), {
122
+ const res = await builderGatewayRequest("signed_url", url.toString(), {
120
123
  method: "POST",
121
124
  headers: {
122
125
  Authorization: authorization,
@@ -129,7 +132,6 @@ async function requestBuilderSignedUrl(authorization, apiKey, filename, mimeType
129
132
  resumable,
130
133
  }),
131
134
  });
132
- await assertOk(res, "Builder.io signed-URL request failed");
133
135
  const json = (await res.json());
134
136
  if (!json.uploadUrl || !json.assetId || !json.requiredHeaders) {
135
137
  throw new Error(`Builder.io signed-URL response missing required fields: ${JSON.stringify(Object.keys(json))}`);
@@ -149,7 +151,7 @@ async function completeBuilderUpload(authorization, apiKey, assetId, filename, o
149
151
  setStableUrlQueryParam(url);
150
152
  }
151
153
  setRecordAssetQueryParam(url, options?.recordAsset);
152
- const res = await fetchWithTimeout(url.toString(), {
154
+ const res = await builderGatewayRequest("complete", url.toString(), {
153
155
  method: "POST",
154
156
  headers: {
155
157
  Authorization: authorization,
@@ -161,7 +163,6 @@ async function completeBuilderUpload(authorization, apiKey, assetId, filename, o
161
163
  ...(options?.recordAsset === false ? { record: false } : {}),
162
164
  }),
163
165
  });
164
- await assertOk(res, "Builder.io upload complete failed");
165
166
  const json = (await res.json());
166
167
  if (!json.url)
167
168
  throw new Error("Builder.io upload/complete returned no URL");
@@ -315,15 +316,11 @@ export const builderFileUploadProvider = {
315
316
  if (contentLengthRange)
316
317
  initHeaders["x-goog-content-length-range"] = contentLengthRange;
317
318
  console.log(`[builder-resumable] session step 2: initiating GCS session`);
318
- const initRes = await fetchWithTimeout(uploadUrl, {
319
+ const initRes = await builderGatewayRequest("session_start", uploadUrl, {
319
320
  method: "POST",
320
321
  headers: initHeaders,
321
322
  body: new Uint8Array(0),
322
323
  });
323
- if (!initRes.ok) {
324
- const body = await initRes.text().catch(() => "");
325
- throw new Error(`GCS resumable session initiation failed (${initRes.status}): ${body}`);
326
- }
327
324
  const sessionUri = initRes.headers.get("location");
328
325
  if (!sessionUri)
329
326
  throw new Error("GCS did not return a Location header for the resumable session");
@@ -1,6 +1,7 @@
1
1
  export type { FileUploadDeleteInput, FileUploadInput, FileUploadProvider, FileUploadResult, ResumableUploadSession, ResumableChunkResult, } from "./types.js";
2
2
  export { registerFileUploadProvider, unregisterFileUploadProvider, listFileUploadProviders, getActiveFileUploadProvider, getActiveFileUploadProviderForRequest, deleteUploadedFile, uploadFile, } from "./registry.js";
3
3
  export { builderFileUploadProvider } from "./builder.js";
4
+ export { BuilderGatewayError, type BuilderGatewayErrorDetails, type BuilderGatewayStep, } from "./builder-gateway.js";
4
5
  export { getBuilderUploadCredentialStatus } from "./status.js";
5
6
  export { ensureS3FileUploadProvider, S3RequestError, s3FileUploadProvider, } from "./s3.js";
6
7
  export { cancelS3ResponseBody, fetchS3WithTimeout, presignS3GetUrl, readS3ErrorText, rfc3986, s3ObjectUri, sha256Hex, signS3Request, signedS3Request, trustedDeploymentS3Origin, type PresignS3GetOptions, type S3ClientConfig, type S3Method, type SignedS3RequestOptions, } from "./s3-client.js";
@@ -1,5 +1,6 @@
1
1
  export { registerFileUploadProvider, unregisterFileUploadProvider, listFileUploadProviders, getActiveFileUploadProvider, getActiveFileUploadProviderForRequest, deleteUploadedFile, uploadFile, } from "./registry.js";
2
2
  export { builderFileUploadProvider } from "./builder.js";
3
+ export { BuilderGatewayError, } from "./builder-gateway.js";
3
4
  export { getBuilderUploadCredentialStatus } from "./status.js";
4
5
  export { ensureS3FileUploadProvider, S3RequestError, s3FileUploadProvider, } from "./s3.js";
5
6
  export { cancelS3ResponseBody, fetchS3WithTimeout, presignS3GetUrl, readS3ErrorText, rfc3986, s3ObjectUri, sha256Hex, signS3Request, signedS3Request, trustedDeploymentS3Origin, } from "./s3-client.js";
@@ -1,10 +1,10 @@
1
1
  {
2
- "@agent-native/agentkit": "0.228.1",
2
+ "@agent-native/agentkit": "0.228.2-nightly-20261113152307",
3
3
  "@agent-native/code-agents-ui": "0.1.75",
4
- "@agent-native/core": "0.228.1",
5
- "@agent-native/core-corpus": "0.228.1",
4
+ "@agent-native/core": "0.228.2-nightly-20261113152307",
5
+ "@agent-native/core-corpus": "0.228.2-nightly-20261113152307",
6
6
  "@agent-native/creative-context": "0.8.71",
7
- "@agent-native/dispatch": "0.42.6",
7
+ "@agent-native/dispatch": "0.42.7-nightly-20261113152307",
8
8
  "@agent-native/embedding": "0.2.0",
9
9
  "@agent-native/migrate": "0.0.7",
10
10
  "@agent-native/otel": "0.1.38",
@@ -12,6 +12,6 @@
12
12
  "@agent-native/recap-cli": "0.5.102",
13
13
  "@agent-native/scheduling": "0.2.58",
14
14
  "@agent-native/shared-app-config": "0.1.2",
15
- "@agent-native/skills": "0.4.6",
16
- "@agent-native/toolkit": "0.228.1"
15
+ "@agent-native/skills": "0.4.7-nightly-20261113152307",
16
+ "@agent-native/toolkit": "0.228.2-nightly-20261113152307"
17
17
  }
@@ -283,20 +283,20 @@ export declare function screenMemoryMcpToolDefinitions(): ({
283
283
  type: string;
284
284
  };
285
285
  startAt: {
286
- description?: undefined;
287
286
  type: string;
287
+ description?: undefined;
288
288
  };
289
289
  endAt: {
290
- description?: undefined;
291
290
  type: string;
291
+ description?: undefined;
292
292
  };
293
293
  count: {
294
294
  type: string;
295
295
  description: string;
296
296
  };
297
297
  reason: {
298
- description?: undefined;
299
298
  type: string;
299
+ description?: undefined;
300
300
  };
301
301
  includeMicrophone?: undefined;
302
302
  includeSystemAudio?: undefined;
@@ -180,9 +180,9 @@ export declare const getMyOrgHandler: import("h3").EventHandlerWithFetch<import(
180
180
  soloDeploymentAdmin: boolean | undefined;
181
181
  }>>;
182
182
  export declare const createOrgHandler: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
183
- success: boolean;
184
183
  id?: undefined;
185
184
  name?: undefined;
185
+ success: boolean;
186
186
  role?: undefined;
187
187
  } | {
188
188
  success?: undefined;
@@ -65,8 +65,8 @@ export declare function createWriteSecretHandler(): import("h3").EventHandlerWit
65
65
  ok?: undefined;
66
66
  status?: undefined;
67
67
  } | {
68
- error?: undefined;
69
68
  errorCode?: undefined;
69
+ error?: undefined;
70
70
  ok: boolean;
71
71
  status: string;
72
72
  } | {
@@ -66,8 +66,8 @@ export declare function createAgentEngineApiKeyHandler(): import("h3").EventHand
66
66
  error: string;
67
67
  code: ProviderKeyCheckCode;
68
68
  } | {
69
- errorCode?: undefined;
70
69
  error?: undefined;
70
+ errorCode?: undefined;
71
71
  code?: undefined;
72
72
  ok: boolean;
73
73
  key: string;
@@ -1,4 +1,4 @@
1
- import { type BetterAuthOptions } from "better-auth";
1
+ import { type BetterAuthOptions, type BetterAuthPlugin } from "better-auth";
2
2
  import type { H3Event } from "h3";
3
3
  import { type SignupOrigin } from "./attribution.js";
4
4
  import { type EmailReadiness } from "./email.js";
@@ -330,5 +330,16 @@ export interface GoogleAuthIdentity {
330
330
  }
331
331
  export declare function ensureGoogleAuthIdentity(identity: GoogleAuthIdentity): Promise<boolean>;
332
332
  export declare function ensureGoogleAuthIdentityWithAdapter(adapter: BetterAuthInternalAdapter, identity: GoogleAuthIdentity): Promise<boolean>;
333
+ type BetterAuthInitContext = Parameters<NonNullable<BetterAuthPlugin["init"]>>[0];
334
+ /**
335
+ * Better Auth runs mail callbacks through `runInBackgroundOrAwait`, which logs
336
+ * and swallows their errors. Track the delivery promises so the runner can hand
337
+ * them back and a failed send fails the request.
338
+ */
339
+ export declare function trackAuthEmailDeliveries(ctx: BetterAuthInitContext): {
340
+ context: {
341
+ runInBackgroundOrAwait(task: Parameters<BetterAuthInitContext["runInBackgroundOrAwait"]>[0]): unknown;
342
+ };
343
+ } | undefined;
333
344
  export declare function resetBetterAuth(): Promise<void>;
334
345
  export declare function buildDatabaseConfig(): Promise<BetterAuthOptions["database"]>;
@@ -1403,6 +1403,58 @@ export async function ensureGoogleAuthIdentityWithAdapter(adapter, identity) {
1403
1403
  await syncGoogleProfile(adapter, existing, email, identity);
1404
1404
  return false;
1405
1405
  }
1406
+ /**
1407
+ * Better Auth runs mail callbacks through `runInBackgroundOrAwait`, which logs
1408
+ * and swallows their errors. Track the delivery promises so the runner can hand
1409
+ * them back and a failed send fails the request.
1410
+ */
1411
+ export function trackAuthEmailDeliveries(ctx) {
1412
+ const deliveries = new WeakSet();
1413
+ const emailVerification = ctx.options.emailVerification;
1414
+ const sendVerificationEmail = emailVerification?.sendVerificationEmail;
1415
+ if (emailVerification && sendVerificationEmail) {
1416
+ emailVerification.sendVerificationEmail = (...args) => {
1417
+ const delivery = sendVerificationEmail(...args);
1418
+ if (delivery instanceof Promise)
1419
+ deliveries.add(delivery);
1420
+ return delivery;
1421
+ };
1422
+ }
1423
+ const changeEmail = ctx.options.user?.changeEmail;
1424
+ const sendChangeEmailConfirmation = changeEmail?.sendChangeEmailConfirmation;
1425
+ if (changeEmail && sendChangeEmailConfirmation) {
1426
+ changeEmail.sendChangeEmailConfirmation = (...args) => {
1427
+ const delivery = sendChangeEmailConfirmation(...args);
1428
+ if (delivery instanceof Promise)
1429
+ deliveries.add(delivery);
1430
+ return delivery;
1431
+ };
1432
+ }
1433
+ if (!sendVerificationEmail && !sendChangeEmailConfirmation)
1434
+ return;
1435
+ const passwordOptions = ctx.options.emailAndPassword;
1436
+ const onExistingUserSignUp = passwordOptions?.onExistingUserSignUp;
1437
+ if (passwordOptions && onExistingUserSignUp) {
1438
+ passwordOptions.onExistingUserSignUp = (...args) => {
1439
+ const delivery = onExistingUserSignUp(...args);
1440
+ deliveries.add(delivery);
1441
+ return delivery;
1442
+ };
1443
+ }
1444
+ const runInBackgroundOrAwait = ctx.runInBackgroundOrAwait.bind(ctx);
1445
+ return {
1446
+ context: {
1447
+ runInBackgroundOrAwait(task) {
1448
+ // Better Auth swallows even awaited task errors; verification and
1449
+ // email-change mail must fail the request before the UI can claim
1450
+ // mail was sent.
1451
+ if (task instanceof Promise && deliveries.has(task))
1452
+ return task;
1453
+ return runInBackgroundOrAwait(task);
1454
+ },
1455
+ },
1456
+ };
1457
+ }
1406
1458
  export async function resetBetterAuth() {
1407
1459
  _authInitGeneration++;
1408
1460
  _auth = undefined;
@@ -2021,40 +2073,7 @@ async function createBetterAuthInstance(config) {
2021
2073
  },
2022
2074
  ],
2023
2075
  },
2024
- init(ctx) {
2025
- const emailVerification = ctx.options.emailVerification;
2026
- if (!emailVerification?.sendVerificationEmail)
2027
- return;
2028
- const sendVerificationEmail = emailVerification.sendVerificationEmail;
2029
- const deliveries = new WeakSet();
2030
- emailVerification.sendVerificationEmail = (...args) => {
2031
- const delivery = sendVerificationEmail(...args);
2032
- if (delivery instanceof Promise)
2033
- deliveries.add(delivery);
2034
- return delivery;
2035
- };
2036
- const passwordOptions = ctx.options.emailAndPassword;
2037
- const onExistingUserSignUp = passwordOptions?.onExistingUserSignUp;
2038
- if (passwordOptions && onExistingUserSignUp) {
2039
- passwordOptions.onExistingUserSignUp = (...args) => {
2040
- const delivery = onExistingUserSignUp(...args);
2041
- deliveries.add(delivery);
2042
- return delivery;
2043
- };
2044
- }
2045
- const runInBackgroundOrAwait = ctx.runInBackgroundOrAwait.bind(ctx);
2046
- return {
2047
- context: {
2048
- runInBackgroundOrAwait(task) {
2049
- // Better Auth swallows even awaited task errors; verification
2050
- // must fail the request before the UI can claim mail was sent.
2051
- if (task instanceof Promise && deliveries.has(task))
2052
- return task;
2053
- return runInBackgroundOrAwait(task);
2054
- },
2055
- },
2056
- };
2057
- },
2076
+ init: trackAuthEmailDeliveries,
2058
2077
  },
2059
2078
  ],
2060
2079
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.228.1",
3
+ "version": "0.228.2-nightly-20261113152307",
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": {
@@ -771,7 +771,7 @@
771
771
  "yaml": "^2.9.0",
772
772
  "yjs": "^13.6.33",
773
773
  "zod": "^4.3.6",
774
- "@agent-native/agentkit": "^0.228.1",
774
+ "@agent-native/agentkit": "^0.228.2-nightly-20261113152307",
775
775
  "@agent-native/recap-cli": "^0.5.102"
776
776
  },
777
777
  "devDependencies": {
@@ -845,7 +845,7 @@
845
845
  "xlsx": "^0.18.5"
846
846
  },
847
847
  "peerDependencies": {
848
- "@agent-native/core-corpus": ">=0.196.0",
848
+ "@agent-native/core-corpus": "0.228.2-nightly-20261113152307",
849
849
  "@ai-sdk/anthropic": ">=3",
850
850
  "@ai-sdk/cohere": ">=3",
851
851
  "@ai-sdk/google": ">=3",