@agent-native/core 0.164.4 → 0.164.12

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 (268) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +84 -0
  3. package/corpus/templates/calendar/AGENTS.md +5 -0
  4. package/corpus/templates/calendar/actions/delete-event.ts +1 -1
  5. package/corpus/templates/calendar/actions/delete-events.ts +508 -0
  6. package/corpus/templates/calendar/actions/event-action-helpers.ts +1 -1
  7. package/corpus/templates/calendar/actions/list-events.ts +53 -0
  8. package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +36 -47
  9. package/corpus/templates/calendar/app/components/calendar/DayView.tsx +3 -0
  10. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +18 -1
  11. package/corpus/templates/calendar/app/components/calendar/InlineEventPickers.tsx +256 -38
  12. package/corpus/templates/calendar/app/hooks/use-google-auth.ts +43 -3
  13. package/corpus/templates/calendar/app/i18n-data.ts +120 -0
  14. package/corpus/templates/calendar/app/lib/event-form-utils.ts +113 -0
  15. package/corpus/templates/calendar/changelog/2026-08-18-the-agent-can-now-remove-many-meetings-at-once-such-as-every.md +6 -0
  16. package/corpus/templates/calendar/server/handlers/google-auth.ts +119 -3
  17. package/corpus/templates/calendar/server/lib/event-weekday.ts +112 -0
  18. package/corpus/templates/calendar/server/routes/[base]/_agent-native/google/add-account/auth-url.post.ts +1 -0
  19. package/corpus/templates/calendar/server/routes/[base]/_agent-native/google/auth-url.post.ts +1 -0
  20. package/corpus/templates/calendar/server/routes/_agent-native/google/add-account/auth-url.post.ts +1 -0
  21. package/corpus/templates/calendar/server/routes/_agent-native/google/auth-url.post.ts +1 -0
  22. package/corpus/templates/clips/app/components/player/video-player.tsx +12 -0
  23. package/corpus/templates/clips/app/routes/_app.dictate.tsx +18 -4
  24. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +114 -20
  25. package/corpus/templates/clips/app/routes/share.$shareId.tsx +83 -78
  26. package/corpus/templates/clips/changelog/2026-08-19-clips-nightly-builds-are-available-for-trying-the-latest-upd.md +6 -0
  27. package/corpus/templates/clips/changelog/2026-08-19-social-preview-video-frames.md +1 -0
  28. package/corpus/templates/clips/desktop/README.md +19 -4
  29. package/corpus/templates/clips/desktop/src/app.tsx +78 -16
  30. package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +3 -2
  31. package/corpus/templates/clips/desktop/src-tauri/tauri.conf.json +1 -0
  32. package/corpus/templates/clips/server/routes/[base]/_agent-native/google/auth-url.post.ts +1 -0
  33. package/corpus/templates/clips/server/routes/_agent-native/google/auth-url.get.ts +41 -3
  34. package/corpus/templates/clips/server/routes/_agent-native/google/auth-url.post.ts +1 -0
  35. package/corpus/templates/clips/server/routes/_agent-native/google/callback.get.ts +22 -1
  36. package/corpus/templates/clips/server/routes/api/clips-updater.json.get.ts +41 -22
  37. package/corpus/templates/factory/AGENTS.md +3 -2
  38. package/corpus/templates/factory/actions/get-factory-graph-version.ts +69 -0
  39. package/corpus/templates/factory/actions/list-factory-automations.ts +4 -0
  40. package/corpus/templates/factory/actions/list-factory-graph-versions.ts +82 -0
  41. package/corpus/templates/factory/actions/restore-factory-graph-version.ts +163 -0
  42. package/corpus/templates/factory/actions/save-factory-graph.ts +93 -60
  43. package/corpus/templates/factory/actions/start-builder-for-item.ts +19 -17
  44. package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +100 -36
  45. package/corpus/templates/factory/app/components/factory/FactoryHistoryView.tsx +709 -0
  46. package/corpus/templates/factory/app/components/factory/FactoryInspector.tsx +62 -2
  47. package/corpus/templates/factory/app/components/ui/alert-dialog.tsx +1 -0
  48. package/corpus/templates/factory/app/i18n/en-US.ts +47 -0
  49. package/corpus/templates/factory/app/routes/factory.tsx +324 -61
  50. package/corpus/templates/factory/server/connectors/slack.ts +44 -2
  51. package/corpus/templates/factory/server/plugins/agent-chat.ts +12 -8
  52. package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +13 -0
  53. package/corpus/templates/factory/server/triage/slack-client.ts +5 -0
  54. package/corpus/templates/factory/server/triage/slack-poller.ts +72 -4
  55. package/corpus/templates/mail/actions/view-screen.ts +1 -1
  56. package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +100 -18
  57. package/corpus/templates/mail/server/handlers/google-auth.ts +125 -24
  58. package/corpus/templates/mail/server/lib/gmail-query.ts +5 -2
  59. package/corpus/templates/mail/server/routes/[base]/_agent-native/google/add-account/auth-url.post.ts +1 -0
  60. package/corpus/templates/mail/server/routes/[base]/_agent-native/google/auth-url.post.ts +1 -0
  61. package/corpus/templates/mail/server/routes/_agent-native/google/add-account/auth-url.post.ts +1 -0
  62. package/corpus/templates/mail/server/routes/_agent-native/google/auth-url.post.ts +1 -0
  63. package/corpus/templates/plan/app/pages/PlansPage.tsx +0 -12
  64. package/corpus/templates/plan/changelog/2026-08-19-plan-prompts-now-guide-you-to-connect-ai-before-sending-and-.md +6 -0
  65. package/corpus/templates/slides/actions/approve-deck-access-request.ts +234 -0
  66. package/corpus/templates/slides/actions/get-deck-access-status.ts +35 -2
  67. package/corpus/templates/slides/actions/request-deck-access.ts +263 -64
  68. package/corpus/templates/slides/app/components/editor/MissingDeckAccessPane.tsx +196 -0
  69. package/corpus/templates/slides/app/components/editor/RequestDeckAccessDialog.tsx +101 -0
  70. package/corpus/templates/slides/app/hooks/use-deck-access.ts +7 -4
  71. package/corpus/templates/slides/app/i18n/en-US.ts +29 -6
  72. package/corpus/templates/slides/app/pages/DeckEditor.tsx +147 -169
  73. package/corpus/templates/slides/app/routes/access-request.approve.tsx +250 -0
  74. package/corpus/templates/slides/server/db/schema.ts +8 -0
  75. package/corpus/templates/slides/server/lib/access-request-email.ts +36 -0
  76. package/corpus/templates/slides/server/lib/emails.ts +26 -0
  77. package/corpus/templates/slides/server/plugins/agent-chat.ts +7 -0
  78. package/corpus/templates/slides/server/plugins/db.ts +50 -0
  79. package/corpus/templates/slides/shared/deck-access.ts +31 -0
  80. package/dist/a2a/task-store.d.ts +1 -0
  81. package/dist/a2a/task-store.js +1 -1
  82. package/dist/agent/observational-memory/store.d.ts +1 -0
  83. package/dist/agent/observational-memory/store.js +1 -1
  84. package/dist/agent/run-store.d.ts +1 -0
  85. package/dist/agent/run-store.js +1 -1
  86. package/dist/agent/tool-approval-store.d.ts +1 -0
  87. package/dist/agent/tool-approval-store.js +1 -1
  88. package/dist/application-state/store.d.ts +1 -0
  89. package/dist/application-state/store.js +1 -1
  90. package/dist/browser-sessions/store.d.ts +1 -0
  91. package/dist/browser-sessions/store.js +1 -1
  92. package/dist/checkpoints/store.d.ts +1 -0
  93. package/dist/checkpoints/store.js +1 -1
  94. package/dist/cli/code-agent-schedules.d.ts +11 -0
  95. package/dist/cli/code-agent-schedules.js +44 -5
  96. package/dist/client/AgentPanel.d.ts +5 -1
  97. package/dist/client/AgentPanel.js +2 -2
  98. package/dist/client/AssistantChat.d.ts +5 -1
  99. package/dist/client/AssistantChat.js +40 -6
  100. package/dist/client/EnvironmentBadge.d.ts +7 -13
  101. package/dist/client/EnvironmentBadge.js +43 -92
  102. package/dist/client/agent-chat/index.d.ts +1 -0
  103. package/dist/client/agent-chat/index.js +1 -0
  104. package/dist/client/agent-chat-adapter.js +76 -50
  105. package/dist/client/app-providers.js +4 -4
  106. package/dist/client/chat/message-components.d.ts +4 -0
  107. package/dist/client/chat/message-components.js +28 -1
  108. package/dist/client/chat/run-recovery.js +26 -0
  109. package/dist/client/chat-first/apps-rail.d.ts +1 -0
  110. package/dist/client/chat-first/apps-rail.js +28 -2
  111. package/dist/client/sse-event-processor.js +13 -8
  112. package/dist/client/use-active-agent-chat-run.d.ts +2 -0
  113. package/dist/client/use-active-agent-chat-run.js +22 -0
  114. package/dist/coding-tools/sandbox/executions-store.d.ts +1 -0
  115. package/dist/coding-tools/sandbox/executions-store.js +1 -1
  116. package/dist/collab/awareness-store.d.ts +1 -0
  117. package/dist/collab/awareness-store.js +1 -1
  118. package/dist/collab/routes.d.ts +1 -1
  119. package/dist/collab/storage.d.ts +1 -0
  120. package/dist/collab/storage.js +1 -1
  121. package/dist/collab/struct-routes.d.ts +1 -1
  122. package/dist/db/client.js +3 -3
  123. package/dist/db/ddl-guard.js +8 -0
  124. package/dist/db/migration-runtime.d.ts +23 -0
  125. package/dist/db/migration-runtime.js +41 -0
  126. package/dist/db/migrations.d.ts +1 -2
  127. package/dist/db/migrations.js +2 -24
  128. package/dist/email-catalog/log.d.ts +1 -0
  129. package/dist/email-catalog/log.js +1 -1
  130. package/dist/guards/index.d.ts +1 -0
  131. package/dist/guards/index.js +1 -0
  132. package/dist/guards/release-schema-complete.d.ts +22 -0
  133. package/dist/guards/release-schema-complete.js +144 -0
  134. package/dist/integrations/a2a-continuations-store.d.ts +1 -0
  135. package/dist/integrations/a2a-continuations-store.js +1 -1
  136. package/dist/integrations/awaiting-input-store.d.ts +1 -0
  137. package/dist/integrations/awaiting-input-store.js +1 -1
  138. package/dist/integrations/config-store.d.ts +1 -0
  139. package/dist/integrations/config-store.js +1 -1
  140. package/dist/integrations/controls-store.d.ts +1 -0
  141. package/dist/integrations/controls-store.js +1 -1
  142. package/dist/integrations/identity-links-store.d.ts +1 -0
  143. package/dist/integrations/identity-links-store.js +1 -1
  144. package/dist/integrations/installations-store.d.ts +1 -0
  145. package/dist/integrations/installations-store.js +1 -1
  146. package/dist/integrations/remote-commands-store.d.ts +1 -0
  147. package/dist/integrations/remote-commands-store.js +1 -1
  148. package/dist/integrations/remote-devices-store.d.ts +1 -0
  149. package/dist/integrations/remote-devices-store.js +1 -1
  150. package/dist/integrations/remote-push-store.d.ts +1 -0
  151. package/dist/integrations/remote-push-store.js +1 -1
  152. package/dist/integrations/remote-run-events-store.d.ts +1 -0
  153. package/dist/integrations/remote-run-events-store.js +1 -1
  154. package/dist/integrations/scope-store.d.ts +1 -0
  155. package/dist/integrations/scope-store.js +1 -1
  156. package/dist/integrations/thread-mapping-store.d.ts +1 -0
  157. package/dist/integrations/thread-mapping-store.js +1 -1
  158. package/dist/integrations/usage-budget-store.d.ts +1 -0
  159. package/dist/integrations/usage-budget-store.js +1 -1
  160. package/dist/jobs/background-automation-runner.js +111 -9
  161. package/dist/jobs/run-history.d.ts +1 -0
  162. package/dist/jobs/run-history.js +1 -1
  163. package/dist/jobs/scheduler-health.d.ts +1 -0
  164. package/dist/jobs/scheduler-health.js +1 -1
  165. package/dist/mcp/approval-store.d.ts +1 -0
  166. package/dist/mcp/approval-store.js +1 -1
  167. package/dist/mcp/connect-store.d.ts +1 -0
  168. package/dist/mcp/connect-store.js +1 -1
  169. package/dist/mcp/oauth-store.d.ts +1 -0
  170. package/dist/mcp/oauth-store.js +1 -1
  171. package/dist/notifications/store.d.ts +1 -0
  172. package/dist/notifications/store.js +1 -1
  173. package/dist/oauth-tokens/store.d.ts +1 -0
  174. package/dist/oauth-tokens/store.js +1 -1
  175. package/dist/observability/routes.d.ts +5 -5
  176. package/dist/progress/routes.d.ts +1 -1
  177. package/dist/progress/store.d.ts +1 -0
  178. package/dist/progress/store.js +1 -1
  179. package/dist/provider-api/actions/custom-provider-registration.d.ts +5 -5
  180. package/dist/provider-api/actions/provider-api.d.ts +4 -4
  181. package/dist/provider-api/corpus-jobs-store.d.ts +1 -0
  182. package/dist/provider-api/corpus-jobs-store.js +1 -1
  183. package/dist/provider-api/custom-registry.d.ts +1 -0
  184. package/dist/provider-api/custom-registry.js +1 -1
  185. package/dist/provider-api/quota-governor.d.ts +1 -0
  186. package/dist/provider-api/quota-governor.js +1 -1
  187. package/dist/provider-api/staged-datasets-store.d.ts +1 -0
  188. package/dist/provider-api/staged-datasets-store.js +1 -1
  189. package/dist/resources/handlers.d.ts +3 -3
  190. package/dist/resources/store.d.ts +1 -0
  191. package/dist/resources/store.js +1 -1
  192. package/dist/scripts/dev/index.js +15 -1
  193. package/dist/search/index.js +3 -0
  194. package/dist/secrets/routes.d.ts +9 -9
  195. package/dist/secrets/storage.d.ts +1 -0
  196. package/dist/secrets/storage.js +1 -1
  197. package/dist/server/agent-chat-plugin.js +38 -9
  198. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  199. package/dist/server/agent-teams-run-queue.d.ts +1 -0
  200. package/dist/server/agent-teams-run-queue.js +1 -1
  201. package/dist/server/auth-marketing.js +3 -1
  202. package/dist/server/auth.d.ts +18 -1
  203. package/dist/server/auth.js +370 -154
  204. package/dist/server/embed-session.d.ts +1 -0
  205. package/dist/server/embed-session.js +1 -1
  206. package/dist/server/google-auth-plugin.js +3 -1
  207. package/dist/server/google-oauth.d.ts +10 -0
  208. package/dist/server/google-oauth.js +25 -1
  209. package/dist/server/identity-sso-store.d.ts +1 -0
  210. package/dist/server/identity-sso-store.js +1 -1
  211. package/dist/server/index.d.ts +1 -1
  212. package/dist/server/index.js +1 -1
  213. package/dist/server/onboarding-html.js +200 -31
  214. package/dist/server/poll.d.ts +2 -0
  215. package/dist/server/poll.js +19 -1
  216. package/dist/server/realtime-token.d.ts +1 -1
  217. package/dist/server/release-migrations.js +5 -0
  218. package/dist/server/release-schema.d.ts +46 -0
  219. package/dist/server/release-schema.js +307 -0
  220. package/dist/settings/store.d.ts +1 -0
  221. package/dist/settings/store.js +1 -1
  222. package/dist/shared/environment-lanes.d.ts +28 -0
  223. package/dist/shared/environment-lanes.js +61 -0
  224. package/dist/sharing/actions/share-resource.js +22 -2
  225. package/dist/styles/agent-native.css +17 -15
  226. package/dist/triggers/routes.d.ts +11 -0
  227. package/dist/triggers/routes.js +10 -0
  228. package/dist/usage/alerts-store.d.ts +1 -0
  229. package/dist/usage/alerts-store.js +1 -1
  230. package/dist/usage/store.d.ts +1 -0
  231. package/dist/usage/store.js +1 -1
  232. package/docs/content/actions-access-control.mdx +136 -2
  233. package/docs/content/actions-agent-tools.mdx +101 -0
  234. package/docs/content/actions-defining.mdx +2 -2
  235. package/docs/content/audit-log.mdx +1 -1
  236. package/docs/content/authentication.mdx +1 -1
  237. package/docs/content/cloudflare.mdx +43 -0
  238. package/docs/content/creating-templates.mdx +1 -1
  239. package/docs/content/deploy-an-app.mdx +109 -0
  240. package/docs/content/deployment-environment-variables.mdx +101 -0
  241. package/docs/content/deployment.mdx +125 -792
  242. package/docs/content/docs-components.mdx +2 -2
  243. package/docs/content/environment-variables.mdx +41 -41
  244. package/docs/content/file-uploads.mdx +74 -40
  245. package/docs/content/harness-agents.mdx +2 -2
  246. package/docs/content/internationalization.mdx +61 -65
  247. package/docs/content/key-concepts.mdx +3 -3
  248. package/docs/content/multi-app-workspace.mdx +2 -2
  249. package/docs/content/netlify.mdx +47 -0
  250. package/docs/content/node-docker.mdx +138 -0
  251. package/docs/content/organizations-teams-permissions.mdx +5 -5
  252. package/docs/content/other-platforms.mdx +27 -0
  253. package/docs/content/ssr-caching.mdx +45 -0
  254. package/docs/content/template-assets-developers.mdx +2 -2
  255. package/docs/content/template-chat-developers.mdx +2 -2
  256. package/docs/content/template-content-developers.mdx +2 -2
  257. package/docs/content/{local-file-mode.mdx → template-content-local-files.mdx} +2 -1
  258. package/docs/content/template-content-sync.mdx +2 -2
  259. package/docs/content/toolkit-agent-ux.mdx +1 -1
  260. package/docs/content/toolkit-resources.mdx +2 -2
  261. package/docs/content/updating-ui-in-production.mdx +35 -0
  262. package/docs/content/vercel.mdx +38 -0
  263. package/docs/content/what-is-agent-native.mdx +1 -1
  264. package/docs/content/workspace-deployment.mdx +350 -0
  265. package/package.json +2 -2
  266. package/docs/content/agents.mdx +0 -9
  267. package/docs/content/database.mdx +0 -317
  268. package/docs/content/human-approval.mdx +0 -156
@@ -20,7 +20,7 @@ const TRUST_VALUES = new Set([
20
20
  "external_shared",
21
21
  "unknown",
22
22
  ]);
23
- async function ensureTable() {
23
+ export async function ensureTable() {
24
24
  if (!initPromise) {
25
25
  initPromise = (async () => {
26
26
  const db = getDbExec();
@@ -1,3 +1,4 @@
1
+ export declare function ensureTable(): Promise<void>;
1
2
  export interface ThreadMapping {
2
3
  platform: string;
3
4
  externalThreadId: string;
@@ -1,7 +1,7 @@
1
1
  import { getDbExec, isPostgres, intType } from "../db/client.js";
2
2
  import { ensureTableExists } from "../db/ddl-guard.js";
3
3
  let _initPromise;
4
- async function ensureTable() {
4
+ export async function ensureTable() {
5
5
  if (!_initPromise) {
6
6
  _initPromise = (async () => {
7
7
  const client = getDbExec();
@@ -53,6 +53,7 @@ export interface IntegrationBudgetThresholdEvent {
53
53
  observedMicros: number;
54
54
  createdAt: number;
55
55
  }
56
+ export declare function ensureTables(): Promise<void>;
56
57
  export declare function saveIntegrationUsageBudget(input: {
57
58
  subject: IntegrationBudgetSubject;
58
59
  period: IntegrationBudgetPeriod;
@@ -5,7 +5,7 @@ let initPromise;
5
5
  let transactionTail = Promise.resolve();
6
6
  /** All budget values are integer millionths of one billing currency unit. */
7
7
  export const INTEGRATION_BUDGET_COST_UNIT = "currency_micros";
8
- async function ensureTables() {
8
+ export async function ensureTables() {
9
9
  if (!initPromise) {
10
10
  initPromise = (async () => {
11
11
  const db = getDbExec();
@@ -2,11 +2,12 @@ import { collectFinalResponseTextFromAgentEvents } from "../a2a/response-text.js
2
2
  import { getStoredModelForEngine, normalizeModelForEngine, resolveEngine, } from "../agent/engine/index.js";
3
3
  import { actionsToEngineTools, filterInitialEngineTools, getOwnerActiveApiKey, } from "../agent/production-agent.js";
4
4
  import { runAgentLoopDirectWithSoftTimeout } from "../agent/run-loop-with-resume.js";
5
- import { resolveRunSoftTimeoutMs, startRun } from "../agent/run-manager.js";
5
+ import { resolveRunSoftTimeoutMs, startRun, } from "../agent/run-manager.js";
6
6
  import { claimBackgroundRun, insertRun } from "../agent/run-store.js";
7
+ import { buildAssistantMessage, buildUserMessage, extractThreadMeta, foldAssistantTurn, upsertUserMessage, } from "../agent/thread-data-builder.js";
7
8
  import { attachToolSearch } from "../agent/tool-search.js";
8
9
  import { resolveAutomationExecutionIdentity, } from "../automations/service.js";
9
- import { createThread } from "../chat-threads/store.js";
10
+ import { createThread, getThread, updateThreadData, withThreadDataLock, } from "../chat-threads/store.js";
10
11
  import { queryOrgMembers } from "../org/context.js";
11
12
  import { organizationIdFromResourceOwner, organizationResourceOwner, } from "../resources/store.js";
12
13
  import { runWithRequestContext, } from "../server/request-context.js";
@@ -204,6 +205,80 @@ async function recordRunThread(historyId, threadId, runId) {
204
205
  console.error(`[automations] Could not attach thread ${threadId} to run ${historyId}:`, err);
205
206
  }
206
207
  }
208
+ function backgroundAutomationPersistFailure(input) {
209
+ if (input.hardTimedOut) {
210
+ return {
211
+ message: `Background automation timed out after ${BACKGROUND_RUN_HARD_TIMEOUT_MS / 60_000} minutes`,
212
+ errorCode: "background_automation_hard_timeout",
213
+ };
214
+ }
215
+ const cutOffReason = backgroundRunCutOffReason(input.run);
216
+ if (!cutOffReason)
217
+ return undefined;
218
+ return {
219
+ message: `Background automation was cut off before finishing (${cutOffReason})`,
220
+ errorCode: "background_automation_cut_off",
221
+ };
222
+ }
223
+ /**
224
+ * Chat opens `/chat/:threadId` from `thread_data`, not `agent_run_events`.
225
+ * Persist before the cut-off/status reject so a failed run still has a
226
+ * visible trace. Keep the scheduler title — `extractThreadMeta` would
227
+ * otherwise replace `Job: …` with the prompt excerpt.
228
+ *
229
+ * Cut-off and hard-abort turns have no terminal error event of their own.
230
+ * `suppressInternalContinuation` also drops `auto_continue`, so persist
231
+ * would otherwise store a completed assistant message. Append a
232
+ * non-recoverable error and skip that suppress so Open thread shows the
233
+ * incomplete state.
234
+ */
235
+ async function persistBackgroundAutomationTurn(input) {
236
+ await withThreadDataLock(input.threadId, async () => {
237
+ const row = await getThread(input.threadId);
238
+ if (!row) {
239
+ throw new Error(`Background automation thread ${input.threadId} was not found while saving run ${input.run.runId}.`);
240
+ }
241
+ let repo;
242
+ try {
243
+ repo = JSON.parse(row.threadData || "{}");
244
+ }
245
+ catch {
246
+ throw new Error(`Background automation thread ${input.threadId} has unreadable thread data.`);
247
+ }
248
+ if (!repo || typeof repo !== "object" || Array.isArray(repo)) {
249
+ throw new Error(`Background automation thread ${input.threadId} has unreadable thread data.`);
250
+ }
251
+ repo = upsertUserMessage(repo, buildUserMessage({ text: input.prompt, runId: input.run.runId }));
252
+ const events = [...(input.run.events ?? [])];
253
+ if (input.persistFailure) {
254
+ events.push({
255
+ seq: events.length,
256
+ event: {
257
+ type: "error",
258
+ error: input.persistFailure.message,
259
+ errorCode: input.persistFailure.errorCode,
260
+ recoverable: false,
261
+ },
262
+ });
263
+ }
264
+ const assistantMsg = buildAssistantMessage(events, input.run.runId, {
265
+ suppressInternalContinuation: !input.persistFailure,
266
+ turnId: input.run.turnId,
267
+ runDurationMs: Number.isFinite(input.run.startedAt)
268
+ ? Math.max(0, Date.now() - input.run.startedAt)
269
+ : undefined,
270
+ });
271
+ if (assistantMsg) {
272
+ repo = foldAssistantTurn(repo, assistantMsg, {
273
+ runId: input.run.runId,
274
+ turnId: input.run.turnId,
275
+ });
276
+ }
277
+ const meta = extractThreadMeta(repo);
278
+ const messages = repo.messages;
279
+ await updateThreadData(input.threadId, JSON.stringify(repo), input.threadTitle || row.title, meta.preview || row.preview, Array.isArray(messages) ? messages.length : 0);
280
+ });
281
+ }
207
282
  async function recordRunOutcome(historyId, status, error) {
208
283
  if (!historyId)
209
284
  return;
@@ -282,6 +357,7 @@ async function executeBackgroundAutomation(options, deps, historyId) {
282
357
  const usageRef = { current: null };
283
358
  let responseText = "";
284
359
  let hardAbortTimer = null;
360
+ let hardTimedOut = false;
285
361
  // This runner executes in-process, synchronously — there is no HTTP
286
362
  // self-dispatch to a separate worker. Self-claim the row into
287
363
  // 'background-processing' right away, exactly like a genuine HTTP
@@ -331,9 +407,29 @@ async function executeBackgroundAutomation(options, deps, historyId) {
331
407
  clearTimeout(hardAbortTimer);
332
408
  hardAbortTimer = null;
333
409
  }
334
- const cutOffReason = backgroundRunCutOffReason(run);
335
- if (cutOffReason) {
336
- reject(new Error(`Background automation was cut off before finishing (${cutOffReason})`));
410
+ const persistFailure = backgroundAutomationPersistFailure({
411
+ run,
412
+ hardTimedOut,
413
+ });
414
+ try {
415
+ await persistBackgroundAutomationTurn({
416
+ threadId: thread.id,
417
+ threadTitle,
418
+ prompt,
419
+ run,
420
+ persistFailure,
421
+ });
422
+ }
423
+ catch (err) {
424
+ reject(err instanceof Error ? err : new Error(String(err)));
425
+ throw err;
426
+ }
427
+ // Hard timeout owns the runner reject so a serverless return
428
+ // waits for this persist via `activeRun.finalized`.
429
+ if (hardTimedOut)
430
+ return;
431
+ if (persistFailure) {
432
+ reject(new Error(persistFailure.message));
337
433
  return;
338
434
  }
339
435
  if (run.status !== "completed") {
@@ -350,10 +446,16 @@ async function executeBackgroundAutomation(options, deps, historyId) {
350
446
  });
351
447
  hardAbortTimer = setTimeout(() => {
352
448
  hardAbortTimer = null;
353
- if (activeRun.status === "running") {
354
- activeRun.abort.abort("background_automation_hard_timeout");
355
- reject(new Error(`Background automation timed out after ${BACKGROUND_RUN_HARD_TIMEOUT_MS / 60_000} minutes`));
356
- }
449
+ if (activeRun.status !== "running")
450
+ return;
451
+ hardTimedOut = true;
452
+ activeRun.abort.abort("background_automation_hard_timeout");
453
+ const timeoutError = new Error(`Background automation timed out after ${BACKGROUND_RUN_HARD_TIMEOUT_MS / 60_000} minutes`);
454
+ void activeRun.finalized
455
+ .catch(() => { })
456
+ .then(() => {
457
+ reject(timeoutError);
458
+ });
357
459
  }, BACKGROUND_RUN_HARD_TIMEOUT_MS);
358
460
  }).finally(() => {
359
461
  if (hardAbortTimer) {
@@ -36,6 +36,7 @@ export interface StartAutomationRunInput {
36
36
  /** Authoritative release-time schema for durable automation history. */
37
37
  export declare const AUTOMATION_RUN_MIGRATIONS: MigrationEntry[];
38
38
  export declare function runAutomationRunMigrations(nitroApp: unknown): Promise<void>;
39
+ export declare function ensureTable(): Promise<void>;
39
40
  /**
40
41
  * Record an automation execution. Manual runs create the row before dispatch,
41
42
  * so `dispatchPending` distinguishes that durable handoff from a run that has
@@ -83,7 +83,7 @@ export async function runAutomationRunMigrations(nitroApp) {
83
83
  })(nitroApp);
84
84
  }
85
85
  let _initPromise;
86
- async function ensureTable() {
86
+ export async function ensureTable() {
87
87
  if (!_initPromise) {
88
88
  _initPromise = (async () => {
89
89
  const client = getDbExec();
@@ -13,6 +13,7 @@ export interface AutomationSchedulerHealth {
13
13
  runtime: string | null;
14
14
  updatedAt: number | null;
15
15
  }
16
+ export declare function ensureHealthTable(): Promise<void>;
16
17
  /** Claim one recurring scheduler across all deployments of an app. */
17
18
  export declare function acquireAutomationSchedulerLease(input?: {
18
19
  appId?: string;
@@ -55,7 +55,7 @@ function rowIdForScope(appId, orgId) {
55
55
  return `${appId}:${orgId ?? "global"}`;
56
56
  }
57
57
  let initPromise;
58
- async function ensureHealthTable() {
58
+ export async function ensureHealthTable() {
59
59
  if (!initPromise) {
60
60
  initPromise = (async () => {
61
61
  const createSql = `
@@ -1,3 +1,4 @@
1
+ export declare function ensureApprovalTable(): Promise<void>;
1
2
  export interface McpApprovalGrant {
2
3
  nonce: string;
3
4
  callerKey: string;
@@ -1,7 +1,7 @@
1
1
  import { getDbExec, intType, isPostgres } from "../db/client.js";
2
2
  import { ensureTableExists } from "../db/ddl-guard.js";
3
3
  let initPromise;
4
- async function ensureApprovalTable() {
4
+ export async function ensureApprovalTable() {
5
5
  if (!initPromise) {
6
6
  initPromise = (async () => {
7
7
  const createSql = `
@@ -41,6 +41,7 @@ export declare const MAX_TOKEN_TTL_DAYS = 365;
41
41
  */
42
42
  export declare const DEVICE_START_MAX = 20;
43
43
  export declare const DEVICE_START_WINDOW_MS = 60000;
44
+ export declare function ensureTable(): Promise<void>;
44
45
  export interface MintedTokenRow {
45
46
  id: string;
46
47
  jti: string;
@@ -45,7 +45,7 @@ export const MAX_TOKEN_TTL_DAYS = 365;
45
45
  */
46
46
  export const DEVICE_START_MAX = 20;
47
47
  export const DEVICE_START_WINDOW_MS = 60_000;
48
- async function ensureTable() {
48
+ export async function ensureTable() {
49
49
  if (!_initPromise) {
50
50
  _initPromise = (async () => {
51
51
  const client = getDbExec();
@@ -19,6 +19,7 @@ export declare const MCP_OAUTH_ACCESS_TOKEN_TTL_SECONDS: number;
19
19
  export declare const MCP_OAUTH_REFRESH_TOKEN_TTL_MS: number;
20
20
  export declare const MCP_OAUTH_REGISTER_MAX = 60;
21
21
  export declare const MCP_OAUTH_REGISTER_WINDOW_MS = 60000;
22
+ export declare function ensureTable(): Promise<void>;
22
23
  export interface OAuthClientRow {
23
24
  clientId: string;
24
25
  clientName: string | null;
@@ -65,7 +65,7 @@ export const MCP_OAUTH_ACCESS_TOKEN_TTL_SECONDS = _accessTokenTtl.seconds;
65
65
  export const MCP_OAUTH_REFRESH_TOKEN_TTL_MS = 365 * 24 * 60 * 60_000;
66
66
  export const MCP_OAUTH_REGISTER_MAX = 60;
67
67
  export const MCP_OAUTH_REGISTER_WINDOW_MS = 60_000;
68
- async function ensureTable() {
68
+ export async function ensureTable() {
69
69
  if (!_initPromise) {
70
70
  _initPromise = (async () => {
71
71
  const client = getDbExec();
@@ -1,4 +1,5 @@
1
1
  import type { Notification, NotificationSeverity } from "./types.js";
2
+ export declare function ensureTable(): Promise<void>;
2
3
  export interface InsertNotificationInput {
3
4
  owner: string;
4
5
  severity: NotificationSeverity;
@@ -11,7 +11,7 @@ function normalizeLimit(value, fallback = 50) {
11
11
  return fallback;
12
12
  return Math.min(Math.floor(value), 200);
13
13
  }
14
- async function ensureTable() {
14
+ export async function ensureTable() {
15
15
  if (!_initPromise) {
16
16
  _initPromise = (async () => {
17
17
  const client = getDbExec();
@@ -1,3 +1,4 @@
1
+ export declare function ensureTable(): Promise<void>;
1
2
  export declare function getOAuthTokens(provider: string, accountId: string, owner?: string): Promise<Record<string, unknown> | null>;
2
3
  export interface OAuthTokenSnapshot {
3
4
  tokens: Record<string, unknown>;
@@ -51,7 +51,7 @@ function isDuplicateColumnError(err) {
51
51
  message.includes("duplicate column") ||
52
52
  message.includes("already exists"));
53
53
  }
54
- async function ensureTable() {
54
+ export async function ensureTable() {
55
55
  if (!_initPromise) {
56
56
  _initPromise = (async () => {
57
57
  const client = getDbExec();
@@ -41,27 +41,27 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
41
41
  thumbsUpRate: number;
42
42
  avgEvalScore: number;
43
43
  } | {
44
+ error?: undefined;
45
+ ok?: undefined;
44
46
  summary: import("./types.js").TraceSummary;
45
47
  spans: import("./types.js").TraceSpan[];
46
48
  id?: undefined;
49
+ } | {
47
50
  error?: undefined;
48
51
  ok?: undefined;
49
- } | {
50
52
  summary?: undefined;
51
53
  spans?: undefined;
52
54
  id: string;
53
- error?: undefined;
54
- ok?: undefined;
55
55
  } | {
56
+ ok?: undefined;
56
57
  summary?: undefined;
57
58
  spans?: undefined;
58
59
  id?: undefined;
59
60
  error: any;
60
- ok?: undefined;
61
61
  } | {
62
+ error?: undefined;
62
63
  summary?: undefined;
63
64
  spans?: undefined;
64
65
  id?: undefined;
65
- error?: undefined;
66
66
  ok: boolean;
67
67
  }>>;
@@ -15,6 +15,6 @@ export declare function createProgressHandler(): import("h3").EventHandlerWithFe
15
15
  error: string;
16
16
  ok?: undefined;
17
17
  } | {
18
- ok: boolean;
19
18
  error?: undefined;
19
+ ok: boolean;
20
20
  }>>;
@@ -1,5 +1,6 @@
1
1
  import type { AgentRun, ListRunsOptions, StartRunInput, UpdateProgressInput } from "./types.js";
2
2
  export declare const DEFAULT_PROGRESS_RUN_STALE_MS: number;
3
+ export declare function ensureTable(): Promise<void>;
3
4
  export declare function insertRun(input: StartRunInput): Promise<AgentRun>;
4
5
  export declare function getRun(id: string, owner: string): Promise<AgentRun | null>;
5
6
  export declare function updateRun(id: string, owner: string, input: UpdateProgressInput): Promise<AgentRun | null>;
@@ -21,7 +21,7 @@ function resolveProgressRunStaleMs() {
21
21
  }
22
22
  return DEFAULT_PROGRESS_RUN_STALE_MS;
23
23
  }
24
- async function ensureTable() {
24
+ export async function ensureTable() {
25
25
  if (!_initPromise) {
26
26
  _initPromise = (async () => {
27
27
  const client = getDbExec();
@@ -75,7 +75,6 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
75
75
  user: "user";
76
76
  }>>;
77
77
  }, z.core.$strip>>, {
78
- message?: undefined;
79
78
  id?: undefined;
80
79
  provider?: undefined;
81
80
  deleted?: undefined;
@@ -92,18 +91,18 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
92
91
  found?: undefined;
93
92
  registered?: undefined;
94
93
  label?: undefined;
95
- } | {
96
94
  message?: undefined;
97
- count?: undefined;
95
+ } | {
98
96
  id?: undefined;
97
+ count?: undefined;
99
98
  deleted?: undefined;
100
99
  providers?: undefined;
101
100
  found: boolean;
102
101
  provider: import("../custom-registry.js").CustomProviderConfig;
103
102
  registered?: undefined;
104
103
  label?: undefined;
105
- } | {
106
104
  message?: undefined;
105
+ } | {
107
106
  count?: undefined;
108
107
  provider?: undefined;
109
108
  deleted?: undefined;
@@ -112,8 +111,8 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
112
111
  id: string;
113
112
  registered?: undefined;
114
113
  label?: undefined;
115
- } | {
116
114
  message?: undefined;
115
+ } | {
117
116
  count?: undefined;
118
117
  provider?: undefined;
119
118
  providers?: undefined;
@@ -122,6 +121,7 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
122
121
  id: string;
123
122
  registered?: undefined;
124
123
  label?: undefined;
124
+ message?: undefined;
125
125
  } | {
126
126
  count?: undefined;
127
127
  provider?: undefined;
@@ -311,6 +311,7 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
311
311
  notes?: string | undefined;
312
312
  scope?: "org" | "user" | undefined;
313
313
  }, {
314
+ message?: undefined;
314
315
  deleted?: undefined;
315
316
  id?: undefined;
316
317
  providers: {
@@ -327,8 +328,8 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
327
328
  found?: undefined;
328
329
  registered?: undefined;
329
330
  label?: undefined;
330
- message?: undefined;
331
331
  } | {
332
+ message?: undefined;
332
333
  deleted?: undefined;
333
334
  id?: undefined;
334
335
  providers?: undefined;
@@ -337,8 +338,8 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
337
338
  provider: import("../custom-registry.js").CustomProviderConfig;
338
339
  registered?: undefined;
339
340
  label?: undefined;
340
- message?: undefined;
341
341
  } | {
342
+ message?: undefined;
342
343
  deleted?: undefined;
343
344
  providers?: undefined;
344
345
  count?: undefined;
@@ -347,8 +348,8 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
347
348
  id: string;
348
349
  registered?: undefined;
349
350
  label?: undefined;
350
- message?: undefined;
351
351
  } | {
352
+ message?: undefined;
352
353
  providers?: undefined;
353
354
  count?: undefined;
354
355
  provider?: undefined;
@@ -357,7 +358,6 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
357
358
  id: string;
358
359
  registered?: undefined;
359
360
  label?: undefined;
360
- message?: undefined;
361
361
  } | {
362
362
  deleted?: undefined;
363
363
  providers?: undefined;
@@ -62,6 +62,7 @@ export interface UpdateProviderCorpusJobOptions {
62
62
  error?: string | null;
63
63
  nextResumeAt?: number | null;
64
64
  }
65
+ export declare function ensureTables(): Promise<void>;
65
66
  export declare function createProviderCorpusJob(options: CreateProviderCorpusJobOptions): Promise<ProviderCorpusJobRecord>;
66
67
  export declare function getProviderCorpusJob(options: {
67
68
  id: string;
@@ -9,7 +9,7 @@
9
9
  import { getDbExec, intType, isPostgres } from "../db/client.js";
10
10
  import { ensureTableExists, ensureIndexExists } from "../db/ddl-guard.js";
11
11
  let initPromise;
12
- async function ensureTables() {
12
+ export async function ensureTables() {
13
13
  if (!initPromise) {
14
14
  initPromise = (async () => {
15
15
  const db = getDbExec();
@@ -67,6 +67,7 @@ export interface UpsertCustomProviderArgs {
67
67
  */
68
68
  orgRole: string | null;
69
69
  }
70
+ export declare function ensureTable(): Promise<void>;
70
71
  /**
71
72
  * Validate and normalise a custom provider base URL. Throws when the URL is
72
73
  * invalid, uses a non-http(s) scheme, or resolves to a private/internal host.
@@ -42,7 +42,7 @@ const CREATE_SQL = `CREATE TABLE IF NOT EXISTS custom_api_providers (
42
42
  PRIMARY KEY (scope, scope_id, id)
43
43
  )`;
44
44
  let _initPromise;
45
- async function ensureTable() {
45
+ export async function ensureTable() {
46
46
  if (!_initPromise) {
47
47
  _initPromise = (async () => {
48
48
  const client = getDbExec();
@@ -50,3 +50,4 @@ export declare function createProviderRequestDedupeKey(input: {
50
50
  }): string | undefined;
51
51
  export declare function executeWithProviderQuota<T>(options: ExecuteWithProviderQuotaOptions<T>): Promise<T>;
52
52
  export declare function resetProviderQuotaStateForTests(): void;
53
+ export declare function ensureCooldownTable(): Promise<void>;
@@ -244,7 +244,7 @@ function persistenceTemporarilyUnavailable() {
244
244
  return Boolean(state.persistenceUnavailableUntil &&
245
245
  state.persistenceUnavailableUntil > Date.now());
246
246
  }
247
- async function ensureCooldownTable() {
247
+ export async function ensureCooldownTable() {
248
248
  if (!shouldPersistCooldowns())
249
249
  return;
250
250
  if (persistenceTemporarilyUnavailable())
@@ -14,6 +14,7 @@
14
14
  */
15
15
  export declare const MAX_ROWS_PER_APP = 200000;
16
16
  export declare const MAX_BYTES_PER_APP: number;
17
+ export declare function ensureTables(): Promise<void>;
17
18
  export interface StagedDatasetMeta {
18
19
  id: string;
19
20
  appId: string;
@@ -23,7 +23,7 @@ export const MAX_BYTES_PER_APP = 50 * 1024 * 1024; // 50 MB
23
23
  // Table initialisation
24
24
  // ---------------------------------------------------------------------------
25
25
  let _initPromise;
26
- async function ensureTables() {
26
+ export async function ensureTables() {
27
27
  if (!_initPromise) {
28
28
  _initPromise = (async () => {
29
29
  const db = getDbExec();
@@ -48,11 +48,11 @@ 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
- error?: undefined;
55
54
  ok: boolean;
55
+ error?: undefined;
56
56
  }>;
57
57
  /** POST /_agent-native/resources/upload — upload a file as a resource */
58
58
  export declare function handleUploadResource(event: any): Promise<import("./store.js").Resource | {
@@ -73,10 +73,10 @@ export declare function handleUploadResource(event: any): Promise<import("./stor
73
73
  runId: string | null;
74
74
  expiresAt: number | null;
75
75
  metadata: string | null;
76
- error?: undefined;
77
76
  url: string;
78
77
  provider: string;
79
78
  storageSetupRequired?: undefined;
79
+ error?: undefined;
80
80
  } | {
81
81
  error: string;
82
82
  storageSetupRequired: boolean;
@@ -94,6 +94,7 @@ export interface EffectiveResourceContext {
94
94
  export declare const LOCAL_WORKSPACE_RESOURCE_METADATA_SOURCE = "local-workspace-resource";
95
95
  export declare function canWriteLocalWorkspaceResourcePath(resourcePath: string): Promise<boolean>;
96
96
  export { isLocalWorkspaceResourceId };
97
+ export declare function ensureTable(): Promise<void>;
97
98
  /**
98
99
  * Seed personal AGENTS.md and LEARNINGS.md for a user if they don't exist.
99
100
  * Called when listing resources or from the agent chat plugin.
@@ -601,7 +601,7 @@ function scheduleExpiredAgentScratchCleanup(client) {
601
601
  console.warn("[resources] expired agent-scratch cleanup failed; will retry on a later read:", err?.message ?? err);
602
602
  });
603
603
  }
604
- async function ensureTable() {
604
+ export async function ensureTable() {
605
605
  if (!_initPromise) {
606
606
  _initPromise = _doEnsureTable().catch((err) => {
607
607
  // Don't cache the rejection — let the next caller retry a fresh init.
@@ -6,6 +6,7 @@
6
6
  * registered in production.
7
7
  */
8
8
  import { createCodingToolRegistry } from "../../coding-tools/index.js";
9
+ import { getRequestRunContext } from "../../server/request-context.js";
9
10
  import { normalizeDatabaseToolsMode, } from "../db/tool-mode.js";
10
11
  import { dbExecToolParameters } from "../db/tool-schemas.js";
11
12
  import { tool as listFilesTool, run as listFilesRun } from "./list-files.js";
@@ -67,6 +68,19 @@ function blockedDatabaseActionFromBash(command, databaseToolsMode) {
67
68
  }
68
69
  return null;
69
70
  }
71
+ function unauthorizedActionFromBash(command, allowedActionNames) {
72
+ if (!allowedActionNames)
73
+ return null;
74
+ const allowed = new Set(allowedActionNames);
75
+ const actionCommands = command.matchAll(/\b(?:pnpm|npm|yarn|bun)(?:\s+\S+){0,4}\s+action\s+([a-z][a-z0-9-]*)\b/g);
76
+ for (const match of actionCommands) {
77
+ const actionName = match[1];
78
+ if (actionName && !allowed.has(actionName)) {
79
+ return `Error: action "${actionName}" is not available in this request's action surface.`;
80
+ }
81
+ }
82
+ return null;
83
+ }
70
84
  /**
71
85
  * Creates the dev-mode script registry with shared bash/read/edit/write
72
86
  * coding tools and database tools. Call this and merge with your app's registry
@@ -200,7 +214,7 @@ export async function createDevScriptRegistry(options = {}) {
200
214
  const codingEntries = createCodingToolRegistry({
201
215
  cwd: process.cwd(),
202
216
  bashThrowsOnNonZero: true,
203
- beforeBash: ({ command }) => blockedDatabaseActionFromBash(command, databaseToolsMode),
217
+ beforeBash: ({ command }) => unauthorizedActionFromBash(command, getRequestRunContext()?.allowedActionNames) ?? blockedDatabaseActionFromBash(command, databaseToolsMode),
204
218
  });
205
219
  const legacyEntries = options.legacyAliases
206
220
  ? {
@@ -48,6 +48,9 @@ export function assertPgVectorAvailable(postgres = isPostgres()) {
48
48
  if (!postgres)
49
49
  throw new Error(PGVECTOR_REQUIRED_MESSAGE);
50
50
  }
51
+ // guard:allow-unreleased-schema - the table name is derived at call time from
52
+ // the search namespace and embedding dimensions (`${namespace}_vectors${suffix}`),
53
+ // so the set of tables is not known at release time and cannot be pre-created.
51
54
  export async function ensurePgVectorIndex(db, dimensions, options) {
52
55
  const resolved = pgVectorOptions(options);
53
56
  const names = searchNamespaceIdentifiers(resolved.namespace, dimensions);