@agent-native/core 0.161.1 → 0.161.4

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 (44) hide show
  1. package/corpus/templates/analytics/actions/compose-dashboard.ts +5 -2
  2. package/corpus/templates/analytics/actions/export-dashboard-panel-to-google-sheet.ts +11 -5
  3. package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +89 -2
  4. package/corpus/templates/analytics/actions/update-dashboard.ts +14 -2
  5. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +6 -0
  6. package/corpus/templates/analytics/server/lib/dashboard-panel-query.ts +89 -41
  7. package/corpus/templates/analytics/server/lib/dashboard-panel-source-resolver.ts +8 -3
  8. package/corpus/templates/analytics/server/lib/error-capture.ts +6 -0
  9. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +187 -44
  10. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +44 -16
  11. package/corpus/templates/clips/actions/save-browser-transcript.ts +20 -4
  12. package/corpus/templates/clips/app/components/meetings/transcript-bubbles.tsx +167 -35
  13. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +8 -1
  14. package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +39 -2
  15. package/corpus/templates/slides/actions/list-decks.ts +36 -1
  16. package/corpus/templates/slides/app/context/DeckContext.tsx +17 -6
  17. package/dist/agent/engine/builder-engine.js +37 -19
  18. package/dist/agent/engine/types.d.ts +29 -0
  19. package/dist/agent/engine/types.js +6 -0
  20. package/dist/agent/production-agent.js +2 -0
  21. package/dist/agent/run-manager.d.ts +6 -0
  22. package/dist/agent/run-manager.js +27 -0
  23. package/dist/agent/run-store.d.ts +5 -5
  24. package/dist/agent/run-store.js +52 -15
  25. package/dist/client/AssistantChat.d.ts +1 -0
  26. package/dist/client/AssistantChat.js +10 -1
  27. package/dist/db/client.js +10 -2
  28. package/dist/db/create-get-db.js +42 -0
  29. package/dist/observability/routes.d.ts +3 -3
  30. package/dist/provider-api/actions/custom-provider-registration.d.ts +2 -2
  31. package/dist/resources/handlers.d.ts +1 -1
  32. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  33. package/dist/server/onboarding-html.js +22 -77
  34. package/dist/server/poll.d.ts +5 -5
  35. package/dist/server/poll.js +19 -26
  36. package/dist/server/release-migrations.js +4 -0
  37. package/dist/server/transcribe-voice.d.ts +1 -1
  38. package/dist/shared/auth-copy.d.ts +7 -0
  39. package/dist/shared/auth-copy.js +77 -0
  40. package/dist/shared/mcp-embed-headers.js +8 -4
  41. package/dist/vite/client.js +94 -3
  42. package/dist/workspace-connections/migrations.d.ts +18 -0
  43. package/dist/workspace-connections/migrations.js +153 -0
  44. package/package.json +1 -1
@@ -26,6 +26,8 @@ export declare class EngineError extends Error {
26
26
  readonly statusCode?: number;
27
27
  /** Whether the provider explicitly marked this error as retryable. */
28
28
  readonly providerRetryable?: boolean;
29
+ /** Upstream request id, when the provider/gateway supplied one. */
30
+ readonly requestId?: string;
29
31
  /**
30
32
  * Whether the request exceeded the model's context window. Set by engines that
31
33
  * classified the provider's own reply, because the delivered message may not
@@ -34,12 +36,16 @@ export declare class EngineError extends Error {
34
36
  * one-shot trim-and-retry recovery.
35
37
  */
36
38
  readonly contextOverflow?: boolean;
39
+ /** Sizes and counts of the failed request; see {@link EngineRequestShape}. */
40
+ readonly requestShape?: EngineRequestShape;
37
41
  constructor(message: string, opts?: {
38
42
  errorCode?: string;
39
43
  upgradeUrl?: string;
40
44
  statusCode?: number;
41
45
  providerRetryable?: boolean;
46
+ requestId?: string;
42
47
  contextOverflow?: boolean;
48
+ requestShape?: EngineRequestShape;
43
49
  });
44
50
  }
45
51
  /**
@@ -196,6 +202,13 @@ export type EngineEvent = {
196
202
  * should retry even if status code / message patterns don't match.
197
203
  */
198
204
  providerRetryable?: boolean;
205
+ /**
206
+ * Upstream request id, when the provider/gateway supplies one. This is
207
+ * the only key that ties a user-facing error back to the upstream log,
208
+ * so it must survive to the capture even when the error also carries a
209
+ * message — an opaque message is not a diagnostic.
210
+ */
211
+ requestId?: string;
199
212
  /**
200
213
  * The request exceeded the model's context window. Carried structurally
201
214
  * for the same reason as `providerRetryable`: `error` is visitor copy on a
@@ -203,7 +216,23 @@ export type EngineEvent = {
203
216
  * the time the agent decides whether to trim and retry.
204
217
  */
205
218
  contextOverflow?: boolean;
219
+ /**
220
+ * Sizes and counts of the request that failed. Never prompt or user
221
+ * content — the point is to make "what did we send" answerable from a
222
+ * capture, which an opaque gateway 500 otherwise leaves unanswerable.
223
+ */
224
+ requestShape?: EngineRequestShape;
206
225
  };
226
+ /**
227
+ * Shape-only description of what an engine put on the wire. Every field is a
228
+ * size, a count, or a model id, so it is safe to attach to an error capture.
229
+ */
230
+ export interface EngineRequestShape {
231
+ model: string;
232
+ payloadBytes: number;
233
+ toolCount: number;
234
+ messageCount: number;
235
+ }
207
236
  export interface EngineCapabilities {
208
237
  /** Extended / adaptive thinking support */
209
238
  thinking: boolean;
@@ -25,6 +25,8 @@ export class EngineError extends Error {
25
25
  statusCode;
26
26
  /** Whether the provider explicitly marked this error as retryable. */
27
27
  providerRetryable;
28
+ /** Upstream request id, when the provider/gateway supplied one. */
29
+ requestId;
28
30
  /**
29
31
  * Whether the request exceeded the model's context window. Set by engines that
30
32
  * classified the provider's own reply, because the delivered message may not
@@ -33,6 +35,8 @@ export class EngineError extends Error {
33
35
  * one-shot trim-and-retry recovery.
34
36
  */
35
37
  contextOverflow;
38
+ /** Sizes and counts of the failed request; see {@link EngineRequestShape}. */
39
+ requestShape;
36
40
  constructor(message, opts) {
37
41
  super(message);
38
42
  this.name = "EngineError";
@@ -40,6 +44,8 @@ export class EngineError extends Error {
40
44
  this.upgradeUrl = opts?.upgradeUrl;
41
45
  this.statusCode = opts?.statusCode;
42
46
  this.providerRetryable = opts?.providerRetryable;
47
+ this.requestId = opts?.requestId;
43
48
  this.contextOverflow = opts?.contextOverflow;
49
+ this.requestShape = opts?.requestShape;
44
50
  }
45
51
  }
@@ -3752,6 +3752,8 @@ export async function runAgentLoop(opts) {
3752
3752
  statusCode: event.statusCode,
3753
3753
  providerRetryable: event.providerRetryable,
3754
3754
  contextOverflow: event.contextOverflow,
3755
+ requestId: event.requestId,
3756
+ requestShape: event.requestShape,
3755
3757
  });
3756
3758
  }
3757
3759
  }
@@ -1,3 +1,4 @@
1
+ import type { EngineRequestShape } from "./engine/types.js";
1
2
  import type { AgentChatEvent, RunEvent, RunStatus } from "./types.js";
2
3
  export interface ActiveRun {
3
4
  runId: string;
@@ -233,6 +234,11 @@ export declare function resolveSqlSubscriptionPollMs(now: number, activePollUnti
233
234
  */
234
235
  export declare function nextSqlSubscriptionEmptyPolls(current: number, hadEvents: boolean, now: number, activePollUntil: number): number;
235
236
  export declare function resolveSqlSubscriptionRetryMs(consecutiveFailures: number): number;
237
+ /**
238
+ * Sentry tags are strings, and an absent shape must stay absent: a run that
239
+ * failed before the request was built did not send a zero-byte payload.
240
+ */
241
+ export declare function engineRequestShapeTags(shape: EngineRequestShape | undefined): Record<string, string>;
236
242
  export interface StartRunOptions {
237
243
  /** Keep a request-scoped serverless invocation alive for this run. */
238
244
  waitUntil?: (promise: Promise<unknown>) => void;
@@ -299,6 +299,20 @@ function getRunErrorCode(err) {
299
299
  // only when the run row is persisted.
300
300
  return classifyTerminalErrorCode(describeErrorWithCauses(err));
301
301
  }
302
+ /**
303
+ * Sentry tags are strings, and an absent shape must stay absent: a run that
304
+ * failed before the request was built did not send a zero-byte payload.
305
+ */
306
+ export function engineRequestShapeTags(shape) {
307
+ if (!shape)
308
+ return {};
309
+ return {
310
+ engineModel: shape.model,
311
+ enginePayloadBytes: String(shape.payloadBytes),
312
+ engineToolCount: String(shape.toolCount),
313
+ engineMessageCount: String(shape.messageCount),
314
+ };
315
+ }
302
316
  function getEngineRunErrorDetails(err) {
303
317
  if (err.statusCode === 429)
304
318
  return err.message;
@@ -1060,6 +1074,10 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
1060
1074
  let pendingTerminalEvent = null;
1061
1075
  const captureRunError = (error, phase) => {
1062
1076
  const errorCode = getRunErrorCode(error);
1077
+ // A gateway error often arrives as one opaque user-facing sentence, so the
1078
+ // structured fields EngineError already carries are the whole diagnostic.
1079
+ // Dropping them here left operators with an error id and nothing to join on.
1080
+ const engineError = error instanceof EngineError ? error : null;
1063
1081
  captureError(error, {
1064
1082
  route: "/_agent-native/agent-chat",
1065
1083
  aiTraceId: runId,
@@ -1070,6 +1088,15 @@ export function startRun(runId, threadId, runFn, onComplete, options) {
1070
1088
  softTimedOut: softTimedOut ? "true" : "false",
1071
1089
  abortReason: run.abortReason,
1072
1090
  errorCode,
1091
+ gatewayRequestId: engineError?.requestId,
1092
+ statusCode: engineError?.statusCode != null
1093
+ ? String(engineError.statusCode)
1094
+ : undefined,
1095
+ // What we sent, in sizes and counts only. A gateway rejection describes
1096
+ // nothing about the request behind it, so without these an oversized
1097
+ // payload and an upstream outage produce the same capture — which is
1098
+ // how one gateway 500 cost a night of guessing.
1099
+ ...engineRequestShapeTags(engineError?.requestShape),
1073
1100
  },
1074
1101
  extra: {
1075
1102
  runId,
@@ -715,11 +715,11 @@ export declare function getRunOutcomeCounters(options?: {
715
715
  terminalReason: string;
716
716
  count: number;
717
717
  }>>;
718
- /** Delete old runs and expire stale "running" rows that haven't had activity
719
- * (e.g. worker crashed before updating status). Genuinely completed runs are
720
- * pruned at `olderThanMs`; errored/aborted/truncated runs are kept until
721
- * `erroredOlderThanMs` (a longer window, falling back to `olderThanMs`) so
722
- * their event log survives for cut-off pattern analysis via listErroredRuns. */
718
+ /**
719
+ * Run cleanup is scheduled after every completed run, including completions
720
+ * from several concurrent requests in one isolate. Share one sweep locally;
721
+ * Postgres additionally serializes the durable prune across isolates.
722
+ */
723
723
  export declare function cleanupOldRuns(olderThanMs: number, erroredOlderThanMs?: number): Promise<void>;
724
724
  /**
725
725
  * List recent unsuccessful runs (errored, aborted, and truncated) for cut-off
@@ -2357,6 +2357,8 @@ const RUN_OUTCOME_DAY_MS = 86_400_000;
2357
2357
  * every run id a user pasted into a bug report was gone before anyone looked.
2358
2358
  */
2359
2359
  const UNSUCCESSFUL_STATUS_SQL_LIST = `('errored', 'aborted', 'truncated')`;
2360
+ const RUN_OUTCOME_PRUNE_BATCH_LIMIT = 200;
2361
+ const RUN_OUTCOME_PRUNE_LOCK_KEY = "agent-native:run-outcome-prune";
2360
2362
  /**
2361
2363
  * Fold the terminal outcomes of the rows `cleanupOldRuns` is about to delete
2362
2364
  * into `agent_run_outcome_daily`, so success/failure RATES survive pruning even
@@ -2364,29 +2366,46 @@ const UNSUCCESSFUL_STATUS_SQL_LIST = `('errored', 'aborted', 'truncated')`;
2364
2366
  * covers exactly the unpruned ones, so a rate over any window is
2365
2367
  * `getRunOutcomeCounters()` plus the live rows — no gap, no double count.
2366
2368
  *
2367
- * The DELETE ... RETURNING is the claim: concurrent cleanup calls can both
2368
- * observe a row, but only the caller that deletes it receives it to roll up.
2369
- * Grouping the returned rows in TypeScript avoids dialect-specific date SQL.
2369
+ * Postgres callers take a transaction-scoped advisory lease before the claim.
2370
+ * The bounded DELETE ... RETURNING is still the source of truth for which rows
2371
+ * this invocation owns. Grouping the returned rows in TypeScript avoids
2372
+ * dialect-specific date SQL.
2370
2373
  * Counter upserts run in the same transaction as the delete; a failed upsert
2371
2374
  * rolls back the claim so the source rows remain available for a retry.
2372
2375
  */
2373
2376
  async function pruneAndRollUpPrunedRunOutcomes(client, cutoff, erroredCutoff) {
2374
2377
  const prune = async (tx) => {
2375
- await tx.execute({
2376
- sql: `DELETE FROM agent_run_events WHERE run_id IN (
2377
- SELECT id FROM agent_runs
2378
- WHERE (status = 'completed' AND completed_at < ?)
2379
- OR (status IN ${UNSUCCESSFUL_STATUS_SQL_LIST} AND completed_at < ?)
2380
- )`,
2381
- args: [cutoff, erroredCutoff],
2382
- });
2378
+ if (isPostgres()) {
2379
+ const lockResult = await tx.execute({
2380
+ sql: "SELECT pg_try_advisory_xact_lock(hashtextextended(?, 0::bigint)) AS acquired",
2381
+ args: [RUN_OUTCOME_PRUNE_LOCK_KEY],
2382
+ });
2383
+ const acquired = lockResult.rows[0]?.acquired;
2384
+ if (acquired !== true && acquired !== "t")
2385
+ return;
2386
+ }
2383
2387
  const { rows } = await tx.execute({
2384
2388
  sql: `DELETE FROM agent_runs
2385
- WHERE (status = 'completed' AND completed_at < ?)
2386
- OR (status IN ${UNSUCCESSFUL_STATUS_SQL_LIST} AND completed_at < ?)
2387
- RETURNING status, completed_at, terminal_reason`,
2389
+ WHERE id IN (
2390
+ SELECT id FROM agent_runs
2391
+ WHERE (status = 'completed' AND completed_at < ?)
2392
+ OR (status IN ${UNSUCCESSFUL_STATUS_SQL_LIST} AND completed_at < ?)
2393
+ ORDER BY completed_at ASC, id ASC
2394
+ LIMIT ${RUN_OUTCOME_PRUNE_BATCH_LIMIT}
2395
+ )
2396
+ RETURNING id, status, completed_at, terminal_reason`,
2388
2397
  args: [cutoff, erroredCutoff],
2389
2398
  });
2399
+ const runIds = rows
2400
+ .map((row) => row.id)
2401
+ .filter((id) => typeof id === "string");
2402
+ if (runIds.length > 0) {
2403
+ const placeholders = runIds.map(() => "?").join(", ");
2404
+ await tx.execute({
2405
+ sql: `DELETE FROM agent_run_events WHERE run_id IN (${placeholders})`,
2406
+ args: runIds,
2407
+ });
2408
+ }
2390
2409
  const groups = new Map();
2391
2410
  for (const row of rows) {
2392
2411
  const outcome = row;
@@ -2470,7 +2489,8 @@ export async function getRunOutcomeCounters(options) {
2470
2489
  * pruned at `olderThanMs`; errored/aborted/truncated runs are kept until
2471
2490
  * `erroredOlderThanMs` (a longer window, falling back to `olderThanMs`) so
2472
2491
  * their event log survives for cut-off pattern analysis via listErroredRuns. */
2473
- export async function cleanupOldRuns(olderThanMs, erroredOlderThanMs) {
2492
+ let cleanupOldRunsInFlight;
2493
+ async function cleanupOldRunsInternal(olderThanMs, erroredOlderThanMs) {
2474
2494
  await ensureRunTables();
2475
2495
  const client = getDbExec();
2476
2496
  const cutoff = Date.now() - olderThanMs;
@@ -2567,6 +2587,23 @@ export async function cleanupOldRuns(olderThanMs, erroredOlderThanMs) {
2567
2587
  // counting the same source rows.
2568
2588
  await pruneAndRollUpPrunedRunOutcomes(client, cutoff, erroredCutoff);
2569
2589
  }
2590
+ /**
2591
+ * Run cleanup is scheduled after every completed run, including completions
2592
+ * from several concurrent requests in one isolate. Share one sweep locally;
2593
+ * Postgres additionally serializes the durable prune across isolates.
2594
+ */
2595
+ export function cleanupOldRuns(olderThanMs, erroredOlderThanMs) {
2596
+ if (cleanupOldRunsInFlight)
2597
+ return cleanupOldRunsInFlight;
2598
+ const current = cleanupOldRunsInternal(olderThanMs, erroredOlderThanMs);
2599
+ let settled;
2600
+ settled = current.finally(() => {
2601
+ if (cleanupOldRunsInFlight === settled)
2602
+ cleanupOldRunsInFlight = undefined;
2603
+ });
2604
+ cleanupOldRunsInFlight = settled;
2605
+ return settled;
2606
+ }
2570
2607
  /**
2571
2608
  * List recent unsuccessful runs (errored, aborted, and truncated) for cut-off
2572
2609
  * pattern analysis. Read-only, bounded, and ordered newest-first. Surfaced via
@@ -14,6 +14,7 @@ import { type ContentPart } from "./sse-event-processor.js";
14
14
  import type { ChatThreadScope, ChatThreadSnapshot } from "./use-chat-threads.js";
15
15
  export { AssistantMessageListErrorBoundary, AssistantUiStaleIndexErrorBoundary, assistantUiRecoverableRenderErrorKind, isAssistantUiRecoverableRenderError, isAssistantUiStaleIndexError, } from "./assistant-ui-recovery.js";
16
16
  export { displayableUserMessageText } from "./chat/message-components.js";
17
+ export declare function shouldSuppressUnauthenticatedDesktopThreadRestore(surface: AgentChatSurfaceKind, status: number): boolean;
17
18
  type AssistantUiMessageResourceShape = {
18
19
  id: string;
19
20
  content: readonly unknown[];
@@ -44,6 +44,11 @@ import { useRunStuckDetection } from "./use-run-stuck-detection.js";
44
44
  import { cn } from "./utils.js";
45
45
  export { AssistantMessageListErrorBoundary, AssistantUiStaleIndexErrorBoundary, assistantUiRecoverableRenderErrorKind, isAssistantUiRecoverableRenderError, isAssistantUiStaleIndexError, } from "./assistant-ui-recovery.js";
46
46
  export { displayableUserMessageText } from "./chat/message-components.js";
47
+ // Desktop chat mounts beside the parent identity gate, so an unauthenticated
48
+ // relay is an expected empty state until that gate establishes a session.
49
+ export function shouldSuppressUnauthenticatedDesktopThreadRestore(surface, status) {
50
+ return surface === "desktop" && (status === 401 || status === 403);
51
+ }
47
52
  const useBrowserLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
48
53
  export function assistantUiMessageListStructureKey(messages) {
49
54
  return JSON.stringify(messages.map((message) => [
@@ -2654,7 +2659,11 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2654
2659
  const res = await fetch(`${apiUrl}/threads/${encodeURIComponent(threadId)}`);
2655
2660
  if (!res.ok) {
2656
2661
  if (!cancelled) {
2657
- setThreadRestoreError(res.status === 404 ? "not-found" : "unavailable");
2662
+ setThreadRestoreError(shouldSuppressUnauthenticatedDesktopThreadRestore(agentChatSurface, res.status)
2663
+ ? null
2664
+ : res.status === 404
2665
+ ? "not-found"
2666
+ : "unavailable");
2658
2667
  }
2659
2668
  return;
2660
2669
  }
package/dist/db/client.js CHANGED
@@ -1258,7 +1258,12 @@ async function createDbExecInternal(config = {}, trackSingletonResources = false
1258
1258
  const { rawSql, args } = sqlAndArgs(sql);
1259
1259
  const { timeoutMs } = dbExecQueryBudget(sql);
1260
1260
  const pgSql = sqliteToPostgresParams(rawSql);
1261
- const result = await withDbTimeout("query", () => client.query(pgSql, args), timeoutOverrideMs ?? timeoutMs);
1261
+ // Neon only accepts multiple SQL commands through its simple protocol;
1262
+ // the transaction start has no parameters, so use that overload.
1263
+ const runQuery = () => args.length === 0 && rawSql.includes(";")
1264
+ ? client.query(pgSql)
1265
+ : client.query(pgSql, args);
1266
+ const result = await withDbTimeout("query", () => runQuery(), timeoutOverrideMs ?? timeoutMs);
1262
1267
  return {
1263
1268
  rows: result.rows,
1264
1269
  rowsAffected: result.rowCount ?? 0,
@@ -1404,7 +1409,10 @@ async function createDbExecInternal(config = {}, trackSingletonResources = false
1404
1409
  },
1405
1410
  };
1406
1411
  try {
1407
- await queryNeonClient(client, "BEGIN");
1412
+ // Send the transaction start and idle reaper together. Neon
1413
+ // transaction pooling can ignore startup parameters, and a
1414
+ // worker can die between separate BEGIN and SET LOCAL calls.
1415
+ await queryNeonClient(client, "BEGIN; SET LOCAL idle_in_transaction_session_timeout = 30000");
1408
1416
  const result = await fn(tx);
1409
1417
  await queryNeonClient(client, "COMMIT");
1410
1418
  releaseClient();
@@ -40,6 +40,43 @@ function getNeonServerlessDrizzle() {
40
40
  export function isSqlRead(sql) {
41
41
  return /^\s*(SELECT|WITH\s)/i.test(sql);
42
42
  }
43
+ const NEON_IDLE_IN_TRANSACTION_TIMEOUT_SQL = "SET LOCAL idle_in_transaction_session_timeout = 30000";
44
+ function queryText(sql) {
45
+ if (typeof sql === "string")
46
+ return sql;
47
+ if (sql && typeof sql === "object" && "text" in sql) {
48
+ const text = sql.text;
49
+ return typeof text === "string" ? text : "";
50
+ }
51
+ return "";
52
+ }
53
+ function isBeginQuery(sql) {
54
+ return /^\s*BEGIN(?:\s|$)/i.test(queryText(sql));
55
+ }
56
+ /**
57
+ * Drizzle sends BEGIN through the client returned by pool.connect(), so a
58
+ * pool startup parameter alone is not enough protection when Neon routes the
59
+ * connection through a transaction pooler. Put the idle timeout in the same
60
+ * simple-protocol message as BEGIN; a worker killed before its next query
61
+ * still leaves a backend that will reap itself.
62
+ */
63
+ function guardNeonTransactionClient(client) {
64
+ return new Proxy(client, {
65
+ get(target, prop) {
66
+ if (prop !== "query") {
67
+ const value = target[prop];
68
+ return typeof value === "function" ? value.bind(target) : value;
69
+ }
70
+ return (...args) => {
71
+ const sql = args[0];
72
+ if (!isBeginQuery(sql))
73
+ return target.query(...args);
74
+ const text = queryText(sql).replace(/;\s*$/, "");
75
+ return target.query(`${text}; ${NEON_IDLE_IN_TRANSACTION_TIMEOUT_SQL}`);
76
+ };
77
+ },
78
+ });
79
+ }
43
80
  /**
44
81
  * Wraps a @neondatabase/serverless Pool so every query goes through
45
82
  * the same withDbTimeout + retryOnConnectionError resilience that the
@@ -129,6 +166,11 @@ export function buildResilientNeonPool(pool) {
129
166
  get(target, prop) {
130
167
  if (prop === "query")
131
168
  return resilientQuery;
169
+ if (prop === "connect") {
170
+ return (...args) => target
171
+ .connect(...args)
172
+ .then((client) => guardNeonTransactionClient(client));
173
+ }
132
174
  const val = target[prop];
133
175
  return typeof val === "function" ? val.bind(target) : val;
134
176
  },
@@ -41,16 +41,16 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
41
41
  thumbsUpRate: number;
42
42
  avgEvalScore: number;
43
43
  } | {
44
+ error?: undefined;
44
45
  summary: import("./types.js").TraceSummary;
45
46
  spans: import("./types.js").TraceSpan[];
46
47
  id?: undefined;
47
- error?: undefined;
48
48
  ok?: undefined;
49
49
  } | {
50
+ error?: undefined;
50
51
  summary?: undefined;
51
52
  spans?: undefined;
52
53
  id: string;
53
- error?: undefined;
54
54
  ok?: undefined;
55
55
  } | {
56
56
  summary?: undefined;
@@ -59,9 +59,9 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
59
59
  error: any;
60
60
  ok?: undefined;
61
61
  } | {
62
+ error?: undefined;
62
63
  summary?: undefined;
63
64
  spans?: undefined;
64
65
  id?: undefined;
65
66
  ok: boolean;
66
- error?: undefined;
67
67
  }>>;
@@ -75,8 +75,8 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
75
75
  user: "user";
76
76
  }>>;
77
77
  }, z.core.$strip>>, {
78
- id?: undefined;
79
78
  message?: undefined;
79
+ id?: undefined;
80
80
  deleted?: undefined;
81
81
  providers: {
82
82
  id: string;
@@ -93,9 +93,9 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
93
93
  registered?: undefined;
94
94
  label?: undefined;
95
95
  } | {
96
- id?: undefined;
97
96
  message?: undefined;
98
97
  count?: undefined;
98
+ id?: undefined;
99
99
  deleted?: undefined;
100
100
  providers?: undefined;
101
101
  found: boolean;
@@ -48,8 +48,8 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
48
48
  }>;
49
49
  /** DELETE /_agent-native/resources/:id — delete a resource */
50
50
  export declare function handleDeleteResource(event: any): Promise<{
51
- ok?: undefined;
52
51
  error: string;
52
+ ok?: undefined;
53
53
  } | {
54
54
  error?: undefined;
55
55
  ok: boolean;
@@ -27,10 +27,10 @@ export declare function resolveAgentEngineApiKeyWriteTarget(event: H3Event, scop
27
27
  export declare function createAgentEngineApiKeyHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
28
28
  error: any;
29
29
  } | {
30
+ error?: undefined;
30
31
  ok: boolean;
31
32
  key: string;
32
33
  baseUrlKey?: string;
33
34
  scope: AgentEngineApiKeyScope;
34
- error?: undefined;
35
35
  }>>;
36
36
  export {};