@agent-native/core 0.214.0 → 0.217.0

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 (196) hide show
  1. package/dist/action.js +54 -1
  2. package/dist/agent/actions/disconnect-chatgpt-subscription.js +5 -0
  3. package/dist/agent/actions/get-agentkit-capabilities.js +3 -3
  4. package/dist/agent/actions/manage-builder-connection.js +5 -0
  5. package/dist/agent/actions/manage-provider-key-policy.js +5 -0
  6. package/dist/agent/actions/manage-provider-models.js +5 -0
  7. package/dist/agent/actions/manage-service-providers.js +5 -0
  8. package/dist/agent/actions/select-chatgpt-subscription-account.js +5 -0
  9. package/dist/agent/context-xray/actions/context-evict.js +5 -0
  10. package/dist/agent/context-xray/actions/context-pin.js +5 -0
  11. package/dist/agent/context-xray/actions/context-report.js +5 -0
  12. package/dist/agent/context-xray/actions/context-restore.js +5 -0
  13. package/dist/agent/execution-fence.d.ts +1 -0
  14. package/dist/agent/execution-fence.js +5 -0
  15. package/dist/agent/production-agent.d.ts +35 -2
  16. package/dist/agent/production-agent.js +629 -32
  17. package/dist/agent/run-manager.d.ts +2 -0
  18. package/dist/agent/run-manager.js +397 -115
  19. package/dist/agent/run-slot-lock.d.ts +2 -0
  20. package/dist/agent/run-slot-lock.js +6 -0
  21. package/dist/agent/run-store.d.ts +5 -0
  22. package/dist/agent/run-store.js +423 -156
  23. package/dist/agent/thread-data-builder.js +27 -5
  24. package/dist/agent/types.d.ts +6 -12
  25. package/dist/agentkit/capabilities.d.ts +1 -1
  26. package/dist/app-config/analytics.js +1 -1
  27. package/dist/application-state/store.d.ts +5 -0
  28. package/dist/application-state/store.js +26 -0
  29. package/dist/automation/index.d.ts +1 -1
  30. package/dist/chat-threads/schema-migrations.js +17 -0
  31. package/dist/chat-threads/store.d.ts +21 -1
  32. package/dist/chat-threads/store.js +223 -41
  33. package/dist/cli/skills-content/turn-into-app-skill.d.ts +1 -1
  34. package/dist/cli/skills-content/turn-into-app-skill.js +20 -18
  35. package/dist/cli/templates-meta.js +14 -0
  36. package/dist/client/analytics-session.d.ts +7 -0
  37. package/dist/client/analytics-session.js +27 -1
  38. package/dist/client/analytics.js +276 -31
  39. package/dist/client/chat/agentkit-agent-native.js +79 -3
  40. package/dist/client/chat/agentkit-protocol.js +80 -42
  41. package/dist/client/chat/runtime.d.ts +5 -1
  42. package/dist/client/chat/runtime.js +46 -3
  43. package/dist/client/consent.d.ts +48 -0
  44. package/dist/client/consent.js +413 -0
  45. package/dist/client/onboarding/index.d.ts +1 -0
  46. package/dist/client/onboarding/index.js +1 -0
  47. package/dist/client/onboarding/use-onboarding-checklist.d.ts +23 -0
  48. package/dist/client/onboarding/use-onboarding-checklist.js +115 -0
  49. package/dist/client/review/use-review.d.ts +2 -0
  50. package/dist/client/review/use-review.js +28 -1
  51. package/dist/client/session-replay.d.ts +1 -1
  52. package/dist/client/session-replay.js +142 -3
  53. package/dist/client/sharing/useResourceAccessGate.d.ts +3 -2
  54. package/dist/client/sharing/useResourceAccessGate.js +9 -1
  55. package/dist/client/use-chat-thread-list.d.ts +2 -0
  56. package/dist/client/use-chat-thread-list.js +12 -2
  57. package/dist/client/use-chat-threads.d.ts +1 -0
  58. package/dist/client/use-chat-threads.js +2 -0
  59. package/dist/collab/awareness.d.ts +2 -2
  60. package/dist/connections/catalog.d.ts +5 -5
  61. package/dist/connections/catalog.js +22 -3
  62. package/dist/data-widgets/index.d.ts +36 -2
  63. package/dist/data-widgets/index.js +94 -6
  64. package/dist/db/migrations.js +4 -1
  65. package/dist/db/schema-snapshot.generated.js +8 -1
  66. package/dist/feature-flags/actions/set-feature-flag.js +5 -0
  67. package/dist/feature-flags/index.d.ts +1 -1
  68. package/dist/feature-flags/index.js +1 -1
  69. package/dist/feature-flags/store.d.ts +12 -0
  70. package/dist/feature-flags/store.js +79 -7
  71. package/dist/file-upload/actions/manage-file-storage.js +5 -0
  72. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  73. package/dist/file-upload/actions/upload-image.js +5 -0
  74. package/dist/history/actions/create-resource-version.js +5 -0
  75. package/dist/history/actions/restore-resource-version.js +5 -0
  76. package/dist/ingestion/index.d.ts +1 -1
  77. package/dist/ingestion/index.js +1 -1
  78. package/dist/ingestion/pptx.d.ts +11 -0
  79. package/dist/ingestion/pptx.js +81 -1
  80. package/dist/integrations/actions/manage-messaging-channel.js +5 -0
  81. package/dist/jobs/actions/manage-recurring-job.d.ts +1 -1
  82. package/dist/jobs/scheduler.js +17 -1
  83. package/dist/labs/actions/set-lab.js +5 -0
  84. package/dist/localization/actions/set-localization-preference.js +5 -0
  85. package/dist/localization/consent-banner-messages.d.ts +16 -0
  86. package/dist/localization/consent-banner-messages.js +149 -0
  87. package/dist/localization/core-messages.js +4 -0
  88. package/dist/localization/default-messages.d.ts +1 -0
  89. package/dist/localization/default-messages.js +2 -0
  90. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  91. package/dist/notifications/routes.d.ts +2 -2
  92. package/dist/observability/actions/save-observability-instruction-update.js +5 -0
  93. package/dist/observability/actions/save-observability-review-summary.js +5 -0
  94. package/dist/observability/routes.d.ts +6 -6
  95. package/dist/onboarding/index.d.ts +2 -1
  96. package/dist/onboarding/index.js +1 -0
  97. package/dist/onboarding/plugin.js +55 -46
  98. package/dist/onboarding/status.d.ts +15 -0
  99. package/dist/onboarding/status.js +59 -0
  100. package/dist/onboarding/types.d.ts +12 -0
  101. package/dist/onboarding/types.js +2 -1
  102. package/dist/org/workspace-app-access.js +19 -9
  103. package/dist/progress/routes.d.ts +1 -1
  104. package/dist/provider-api/actions/custom-provider-registration.d.ts +16 -16
  105. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  106. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  107. package/dist/provider-api/index.js +9 -2
  108. package/dist/resources/handlers.d.ts +1 -1
  109. package/dist/review/actions/consume-review-feedback.js +5 -0
  110. package/dist/review/actions/create-review-comment.js +5 -0
  111. package/dist/review/actions/delete-review-comment.js +5 -0
  112. package/dist/review/actions/react-to-review-comment.js +5 -0
  113. package/dist/review/actions/reply-review-comment.js +5 -0
  114. package/dist/review/actions/resolve-review-thread.js +5 -0
  115. package/dist/review/actions/send-review-thread-to-agent.js +5 -0
  116. package/dist/review/actions/set-review-status.js +5 -0
  117. package/dist/review/actions/set-review-thread-muted.js +5 -0
  118. package/dist/review/actions/set-review-thread-unread.js +5 -0
  119. package/dist/review/actions/set-review-threads-unread.js +5 -0
  120. package/dist/review/actions/update-review-comment-anchor.js +5 -0
  121. package/dist/review/actions/update-review-comment.js +5 -0
  122. package/dist/review/suggestions/actions.js +60 -21
  123. package/dist/review/suggestions/store.d.ts +2 -0
  124. package/dist/review/suggestions/store.js +28 -0
  125. package/dist/secrets/actions/delete-api-key.js +5 -0
  126. package/dist/secrets/routes.d.ts +6 -6
  127. package/dist/server/agent-capabilities.js +13 -6
  128. package/dist/server/agent-chat/context-tools.js +63 -2
  129. package/dist/server/agent-chat-plugin.d.ts +2 -0
  130. package/dist/server/agent-chat-plugin.js +242 -54
  131. package/dist/server/agent-engine-default-model-route.d.ts +1 -1
  132. package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
  133. package/dist/server/analytics.d.ts +0 -1
  134. package/dist/server/analytics.js +81 -20
  135. package/dist/server/application-state-maintenance.d.ts +2 -0
  136. package/dist/server/application-state-maintenance.js +2 -0
  137. package/dist/server/attribution.d.ts +14 -0
  138. package/dist/server/attribution.js +62 -2
  139. package/dist/server/auth.js +7 -0
  140. package/dist/server/builder-api-auth.d.ts +7 -0
  141. package/dist/server/builder-api-auth.js +24 -0
  142. package/dist/server/builder-oauth.d.ts +5 -1
  143. package/dist/server/builder-oauth.js +5 -0
  144. package/dist/server/consent-route.d.ts +41 -0
  145. package/dist/server/consent-route.js +102 -0
  146. package/dist/server/core-routes-plugin.d.ts +1 -1
  147. package/dist/server/first-touch-route.d.ts +39 -0
  148. package/dist/server/first-touch-route.js +115 -0
  149. package/dist/server/index.d.ts +2 -1
  150. package/dist/server/index.js +2 -1
  151. package/dist/server/queued-submission-inbox-drain.d.ts +9 -0
  152. package/dist/server/queued-submission-inbox-drain.js +12 -0
  153. package/dist/server/request-origin.d.ts +6 -0
  154. package/dist/server/request-origin.js +12 -0
  155. package/dist/settings/org-settings.d.ts +2 -1
  156. package/dist/settings/org-settings.js +4 -1
  157. package/dist/settings/store.d.ts +8 -0
  158. package/dist/settings/store.js +14 -5
  159. package/dist/shared/consent.d.ts +33 -0
  160. package/dist/shared/consent.js +149 -0
  161. package/dist/shared/first-touch-persistence.d.ts +31 -0
  162. package/dist/shared/first-touch-persistence.js +53 -0
  163. package/dist/sharing/actions/set-resource-visibility.js +5 -0
  164. package/dist/sharing/actions/share-resource.js +5 -0
  165. package/dist/sharing/actions/unshare-resource.js +5 -0
  166. package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +1 -1
  167. package/dist/templates/default/.agents/skills/actions/references/action-fields.md +1 -1
  168. package/dist/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +36 -80
  169. package/dist/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +54 -16
  170. package/dist/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +50 -73
  171. package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +1 -1
  172. package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -1
  173. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +20 -18
  174. package/dist/triggers/actions/manage-automation.d.ts +4 -4
  175. package/dist/usage/actions/get-usage-metrics.js +27 -4
  176. package/dist/usage/actions/manage-usage-alert.js +5 -0
  177. package/dist/vite/client.js +8 -6
  178. package/dist/workspace-connections/actions/bulk-update-workspace-user-groups.js +5 -0
  179. package/dist/workspace-connections/actions/delete-workspace-user-group.js +5 -0
  180. package/dist/workspace-connections/actions/upsert-workspace-user-group.js +5 -0
  181. package/docs/content/actions-access-control.mdx +8 -8
  182. package/docs/content/actions-defining.mdx +9 -8
  183. package/docs/content/deployment-environment-variables.mdx +1 -1
  184. package/docs/content/environment-variables.mdx +1 -1
  185. package/docs/content/template-design-developers.mdx +9 -9
  186. package/docs/content/template-design-features.mdx +1 -3
  187. package/docs/content/turn-into-app.mdx +4 -0
  188. package/package.json +6 -3
  189. package/src/templates/chat/.agents/skills/actions/references/action-fields.md +1 -1
  190. package/src/templates/default/.agents/skills/actions/references/action-fields.md +1 -1
  191. package/src/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +36 -80
  192. package/src/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +54 -16
  193. package/src/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +50 -73
  194. package/src/templates/headless/.agents/skills/actions/references/action-fields.md +1 -1
  195. package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -1
  196. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +20 -18
@@ -33,7 +33,7 @@ import { attachToolSearch } from "../agent/tool-search.js";
33
33
  import { getAppConfig } from "../app-config/index.js";
34
34
  import { readAppStateForCurrentTab } from "../application-state/script-helpers.js";
35
35
  import { runChatThreadDataMigrations } from "../chat-threads/migrations.js";
36
- import { InlineAttachmentDataNotPersistableError, QueuedSubmissionAdmissionError, adoptThreadScopeIfUnscoped, blockQueuedSubmissionReceipt, clearQueuedSubmissionInterruptRun, createThread, forkThread, getThread, getQueuedSubmissionReceipt, listQueuedSubmissionReceipts, markQueuedSubmissionSubmitted, queuedSubmissionBehaviorMatches, recordQueuedSubmissionInterruptRun, renewQueuedSubmissionInterruptClaim, registerChatThreadsShareable, retryQueuedSubmissionReceipt, resolveRunThreadScope, resolveThreadAccess, listThreads, searchThreads, renameThread, createThreadShareLink, getThreadByShareToken, getThreadShareState, revokeThreadShareLink, setThreadArchived, setThreadPinned, setThreadScope, updateThreadData, withThreadDataLock, deleteThread, mutateThreadQueuedMessages, setThreadSourceIfMissing, isAppOwnedChatScope, isChatThreadOwnership, threadScopeMismatch, } from "../chat-threads/store.js";
36
+ import { InlineAttachmentDataNotPersistableError, QueuedSubmissionAdmissionError, adoptThreadScopeIfUnscoped, blockQueuedSubmissionReceipt, clearQueuedSubmissionInterruptRun, createThread, forkThread, getThread, getQueuedSubmissionReceipt, getQueuedSubmissionReceiptStatus, listQueuedSubmissionReceipts, markQueuedSubmissionSubmitted, queuedSubmissionBehaviorMatches, recordQueuedSubmissionInterruptRun, renewQueuedSubmissionInterruptClaim, registerChatThreadsShareable, retryQueuedSubmissionReceipt, resolveRunThreadScope, resolveThreadAccess, resolveThreadAccessScope, listThreads, searchThreads, renameThread, createThreadShareLink, getThreadByShareToken, getThreadShareState, revokeThreadShareLink, setThreadArchived, setThreadPinned, setThreadScope, updateThreadData, withThreadDataLock, deleteThread, mutateThreadQueuedMessages, setThreadSourceIfMissing, isAppOwnedChatScope, isChatThreadOwnership, threadScopeMismatch, } from "../chat-threads/store.js";
37
37
  import { isCheckpointRestorePath } from "../checkpoints/route-match.js";
38
38
  import { createDbAdminAgentTools } from "../db-admin/agent-tools.js";
39
39
  import { isTransientDatabaseError } from "../db/client.js";
@@ -78,10 +78,12 @@ import { loadHostedHarnessConfig } from "./hosted-harness-policy.js";
78
78
  import { startIntervalJob } from "./interval-job.js";
79
79
  import { isDirectLoopbackRequest } from "./loopback.js";
80
80
  import { getModelFamilyOverlay } from "./prompts/index.js";
81
+ import { scheduleQueuedSubmissionInboxDrain } from "./queued-submission-inbox-drain.js";
81
82
  import { mountRealtimeVoiceRoutes } from "./realtime-voice.js";
82
83
  import { runWithRequestContext, getRequestContext, getRequestOrgId, getRequestUserEmail, getRequestRunContext, ensureRequestRunContext, } from "./request-context.js";
83
84
  import { getForwardedRequestOrigin } from "./request-origin.js";
84
85
  export { handleSharedThreadRequest };
86
+ const MAX_QUEUED_SUBMISSION_RETRIES = 5;
85
87
  export function trackAgentChatRunLifecycle(event, threadId, attemptId, userId, properties = {}, appId, trackingSource) {
86
88
  if (!threadId?.trim() ||
87
89
  !attemptId?.trim() ||
@@ -298,6 +300,33 @@ export async function runPreAgentTurnAutosave(callback, scope, run) {
298
300
  }
299
301
  }
300
302
  export { foldAgentChatRunCompletion };
303
+ export function assertAgentChatRunProjectionUpdated(updated, threadId, runId) {
304
+ if (!updated) {
305
+ throw new Error(`Agent chat thread ${threadId} could not save the projection for run ${runId}.`);
306
+ }
307
+ }
308
+ export async function runAgentChatRunCompletionHooksAfterProjection(persistProjection, runCompletionHooks) {
309
+ let projectionFailed = false;
310
+ let projectionError;
311
+ try {
312
+ await persistProjection();
313
+ }
314
+ catch (error) {
315
+ projectionFailed = true;
316
+ projectionError = error;
317
+ }
318
+ try {
319
+ await runCompletionHooks();
320
+ }
321
+ catch (error) {
322
+ if (projectionFailed) {
323
+ throw new AggregateError([projectionError, error], "Agent chat projection and completion hooks failed.");
324
+ }
325
+ throw error;
326
+ }
327
+ if (projectionFailed)
328
+ throw projectionError;
329
+ }
301
330
  /**
302
331
  * The model this mount runs with, when the caller does not pass one per request.
303
332
  *
@@ -429,6 +458,7 @@ export async function runA2AAgentLoopWithRunManager(runOptions, pluginOptions, t
429
458
  : undefined;
430
459
  if (reasonCode === "stale_execution_fence" ||
431
460
  reasonCode === A2A_TASK_CLAIM_LOST_ERROR_CODE) {
461
+ run.abortReason = "execution_lease_lost";
432
462
  run.abort.abort("execution_lease_lost");
433
463
  return;
434
464
  }
@@ -2925,7 +2955,7 @@ export function createAgentChatPlugin(options) {
2925
2955
  // the frontend-triggered saves below). Without the lock, a concurrent
2926
2956
  // queued-message save can clobber the assistant message we just
2927
2957
  // appended here, or vice versa.
2928
- await withThreadDataLock(threadId, async () => {
2958
+ await runAgentChatRunCompletionHooksAfterProjection(() => withThreadDataLock(threadId, async () => {
2929
2959
  const thread = await getThread(threadId);
2930
2960
  if (!thread) {
2931
2961
  throw new Error(`Agent chat thread ${threadId} was not found while saving run ${run.runId}.`);
@@ -2949,14 +2979,25 @@ export function createAgentChatPlugin(options) {
2949
2979
  };
2950
2980
  repo = appendThreadDebugHistory(repo, debug);
2951
2981
  const meta = extractThreadMeta(repo);
2952
- await updateThreadData(threadId, JSON.stringify(repo), thread.title, meta.preview || thread.preview, repo.messages.length, { trustedRunSequenceResetIds: new Set([run.runId]) });
2982
+ const projectionUpdated = await updateThreadData(threadId, JSON.stringify(repo), thread.title, meta.preview || thread.preview, repo.messages.length, { trustedRunSequenceResetIds: new Set([run.runId]) });
2983
+ assertAgentChatRunProjectionUpdated(projectionUpdated, threadId, run.runId);
2984
+ }), async () => {
2985
+ // Checkpoint creation is part of durable turn completion. The helper
2986
+ // catches and reports its own failures, so a broken app checkpoint does
2987
+ // not strand the run while a successful checkpoint cannot be lost when
2988
+ // a serverless invocation exits.
2989
+ await runPostAgentTurnAutosave(options?.onAgentTurnComplete, chatScope, run);
2990
+ await runPostAgentRunComplete(options?.onAgentRunComplete, chatScope, run, { turnContinues: endsAtContinuationBoundary(run) });
2991
+ });
2992
+ scheduleQueuedSubmissionInboxDrain({
2993
+ threadId: runThreadId,
2994
+ turnContinues: endsAtContinuationBoundary(run),
2995
+ waitUntil: getRequestRunContext()?.waitUntil,
2996
+ drain: drainQueuedSubmissionInbox,
2997
+ onError: (error) => {
2998
+ console.error(`[agent-chat] queued-submission follow-up drain failed for ${runThreadId}:`, error);
2999
+ },
2953
3000
  });
2954
- // Checkpoint creation is part of durable turn completion. The helper
2955
- // catches and reports its own failures, so a broken app checkpoint does
2956
- // not strand the run while a successful checkpoint cannot be lost when
2957
- // a serverless invocation exits.
2958
- await runPostAgentTurnAutosave(options?.onAgentTurnComplete, chatScope, run);
2959
- await runPostAgentRunComplete(options?.onAgentRunComplete, chatScope, run, { turnContinues: endsAtContinuationBoundary(run) });
2960
3001
  // Event triggers and local git checkpoints remain best effort and do
2961
3002
  // not extend the durable chat persistence gate.
2962
3003
  void (async () => {
@@ -5866,6 +5907,17 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
5866
5907
  };
5867
5908
  // ── Specific thread: GET/PUT/DELETE /threads/:id ──
5868
5909
  if (threadId) {
5910
+ if (method === "GET" &&
5911
+ threadTail[0] === "queue" &&
5912
+ threadTail[1] &&
5913
+ threadTail[2] === "receipt" &&
5914
+ threadTail.length === 3) {
5915
+ const thread = await resolveThreadAccessScope(owner, threadId, "viewer", { orgId });
5916
+ if (!thread || !threadMatchesRequestedScope(thread)) {
5917
+ return threadNotFound();
5918
+ }
5919
+ return await getQueuedSubmissionReceiptStatus(threadId, threadTail[1]);
5920
+ }
5869
5921
  if (method === "GET") {
5870
5922
  const thread = await resolveThreadAccess(owner, threadId, "viewer", { orgId });
5871
5923
  if (!thread || !threadMatchesRequestedScope(thread)) {
@@ -6129,7 +6181,9 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6129
6181
  mutation = { type: "append", message: queued };
6130
6182
  }
6131
6183
  }
6132
- else if ((record?.type === "remove" || record?.type === "moveToTop") &&
6184
+ else if ((record?.type === "remove" ||
6185
+ record?.type === "cancel" ||
6186
+ record?.type === "moveToTop") &&
6133
6187
  typeof record.messageId === "string" &&
6134
6188
  record.messageId) {
6135
6189
  mutation = {
@@ -6229,12 +6283,30 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6229
6283
  retryable: true,
6230
6284
  };
6231
6285
  }
6286
+ if (mutation.type === "append" &&
6287
+ result.message &&
6288
+ !result.alreadySubmitted &&
6289
+ !result.submissionExpired) {
6290
+ scheduleQueuedSubmissionInboxDrain({
6291
+ threadId,
6292
+ turnContinues: false,
6293
+ waitUntil: getRequestRunContext()?.waitUntil,
6294
+ drain: drainQueuedSubmissionInbox,
6295
+ onError: (error) => {
6296
+ console.error(`[agent-chat] queued-submission append drain failed for ${threadId}:`, error);
6297
+ },
6298
+ });
6299
+ }
6300
+ if (mutation.type === "cancel" && result.submittedRunId) {
6301
+ await abortRunAndTurnDurably(result.submittedRunId, clientAbortReason("user"));
6302
+ }
6232
6303
  const withoutClaim = (message) => {
6233
6304
  const { promotionClaim: _claim, ...safeMessage } = message;
6234
6305
  return safeMessage;
6235
6306
  };
6307
+ const { submittedRunId: _submittedRunId, ...safeResult } = result;
6236
6308
  return {
6237
- ...result,
6309
+ ...(mutation.type === "cancel" ? safeResult : result),
6238
6310
  queuedMessages: result.queuedMessages.map(withoutClaim),
6239
6311
  ...(result.message
6240
6312
  ? { message: withoutClaim(result.message) }
@@ -6407,6 +6479,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6407
6479
  const scope = parseScopeFromQuery(query);
6408
6480
  const unscopedOnly = String(query.unscoped ?? "") === "1";
6409
6481
  const includeExternal = String(query.includeExternal ?? "") === "1";
6482
+ const includeArchived = String(query.includeArchived ?? "") === "1";
6410
6483
  const ownership = query.ownership === undefined ? "all" : query.ownership;
6411
6484
  if (!isChatThreadOwnership(ownership)) {
6412
6485
  setResponseStatus(event, 400);
@@ -6420,6 +6493,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6420
6493
  scope: scope ?? undefined,
6421
6494
  orgId,
6422
6495
  includeExternal,
6496
+ includeArchived,
6423
6497
  sourceAppId: options?.appId ?? null,
6424
6498
  ownership,
6425
6499
  offset,
@@ -6431,6 +6505,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6431
6505
  unscopedOnly,
6432
6506
  orgId,
6433
6507
  includeExternal,
6508
+ includeArchived,
6434
6509
  sourceAppId: options?.appId ?? null,
6435
6510
  ownership,
6436
6511
  });
@@ -6563,7 +6638,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6563
6638
  return handler(event);
6564
6639
  });
6565
6640
  };
6566
- const drainQueuedSubmissionInbox = async () => {
6641
+ const drainQueuedSubmissionInbox = async (drainOptions = {}) => {
6567
6642
  const result = {
6568
6643
  scanned: 0,
6569
6644
  claimed: 0,
@@ -6573,8 +6648,16 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6573
6648
  expired: 0,
6574
6649
  failed: 0,
6575
6650
  };
6576
- const pending = await listQueuedSubmissionReceipts({ limit: 25 });
6651
+ const pending = await listQueuedSubmissionReceipts({
6652
+ limit: 25,
6653
+ ...(drainOptions.threadId ? { threadId: drainOptions.threadId } : {}),
6654
+ });
6577
6655
  result.scanned = pending.length;
6656
+ const deferredThreads = new Set();
6657
+ const deferReceipt = (threadId) => {
6658
+ result.deferred += 1;
6659
+ deferredThreads.add(threadId);
6660
+ };
6578
6661
  const deadlineAt = Date.now() + 30_000;
6579
6662
  const maxAdmissions = 5;
6580
6663
  const waitForStableIdle = async (threadId) => {
@@ -6596,10 +6679,75 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6596
6679
  return false;
6597
6680
  };
6598
6681
  for (const receipt of pending) {
6682
+ if (deferredThreads.has(receipt.threadId)) {
6683
+ result.deferred += 1;
6684
+ continue;
6685
+ }
6599
6686
  if (Date.now() >= deadlineAt || result.submitted >= maxAdmissions) {
6600
6687
  break;
6601
6688
  }
6689
+ if (drainOptions.threadId &&
6690
+ !(await waitForStableIdle(drainOptions.threadId))) {
6691
+ deferReceipt(receipt.threadId);
6692
+ break;
6693
+ }
6602
6694
  let claimId;
6695
+ let retryCount = receipt.retryCount;
6696
+ let recoveryMutationAttempted = false;
6697
+ const retryClaimedReceipt = async (countRetry = false) => {
6698
+ if (!claimId) {
6699
+ throw new Error(`Queued submission ${receipt.messageId} has no active claim to retry`);
6700
+ }
6701
+ recoveryMutationAttempted = true;
6702
+ let updated = await retryQueuedSubmissionReceipt(receipt.threadId, receipt.messageId, Date.now() + 10_000, { claimId, ...(countRetry ? { countRetry: true } : {}) });
6703
+ if (!updated) {
6704
+ updated = await retryQueuedSubmissionReceipt(receipt.threadId, receipt.messageId, Date.now() + 10_000, countRetry ? { countRetry: true } : {});
6705
+ }
6706
+ if (updated && countRetry)
6707
+ retryCount += 1;
6708
+ return updated;
6709
+ };
6710
+ const blockClaimedReceipt = async () => {
6711
+ if (!claimId) {
6712
+ throw new Error(`Queued submission ${receipt.messageId} has no active claim to block`);
6713
+ }
6714
+ recoveryMutationAttempted = true;
6715
+ const updated = await blockQueuedSubmissionReceipt(receipt.threadId, receipt.messageId, {
6716
+ claimId,
6717
+ });
6718
+ return (updated ||
6719
+ (await blockQueuedSubmissionReceipt(receipt.threadId, receipt.messageId)));
6720
+ };
6721
+ const recoverClaimedReceipt = async () => {
6722
+ if (!claimId) {
6723
+ deferReceipt(receipt.threadId);
6724
+ return;
6725
+ }
6726
+ if (!recoveryMutationAttempted &&
6727
+ retryCount >= MAX_QUEUED_SUBMISSION_RETRIES) {
6728
+ const blocked = await blockClaimedReceipt();
6729
+ await mutateThreadQueuedMessages(receipt.threadId, {
6730
+ type: "release",
6731
+ messageId: receipt.messageId,
6732
+ claimId,
6733
+ });
6734
+ claimId = undefined;
6735
+ if (blocked)
6736
+ result.blocked += 1;
6737
+ else
6738
+ deferReceipt(receipt.threadId);
6739
+ return;
6740
+ }
6741
+ if (!recoveryMutationAttempted)
6742
+ await retryClaimedReceipt(true);
6743
+ await mutateThreadQueuedMessages(receipt.threadId, {
6744
+ type: "release",
6745
+ messageId: receipt.messageId,
6746
+ claimId,
6747
+ });
6748
+ claimId = undefined;
6749
+ deferReceipt(receipt.threadId);
6750
+ };
6603
6751
  try {
6604
6752
  const message = receipt.message;
6605
6753
  if (!message ||
@@ -6610,7 +6758,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6610
6758
  if (blocked)
6611
6759
  result.blocked += 1;
6612
6760
  else
6613
- result.deferred += 1;
6761
+ deferReceipt(receipt.threadId);
6614
6762
  continue;
6615
6763
  }
6616
6764
  const thread = await resolveThreadAccess(receipt.actor.email, receipt.threadId, "editor", { orgId: receipt.actor.orgId ?? undefined });
@@ -6619,7 +6767,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6619
6767
  if (blocked)
6620
6768
  result.blocked += 1;
6621
6769
  else
6622
- result.deferred += 1;
6770
+ deferReceipt(receipt.threadId);
6623
6771
  continue;
6624
6772
  }
6625
6773
  claimId = crypto.randomUUID();
@@ -6635,14 +6783,18 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6635
6783
  if (error instanceof QueuedSubmissionAdmissionError &&
6636
6784
  error.code !== "queued_message_id_conflict") {
6637
6785
  claimId = undefined;
6638
- result.deferred += 1;
6786
+ deferReceipt(receipt.threadId);
6639
6787
  continue;
6640
6788
  }
6641
6789
  throw error;
6642
6790
  }
6643
6791
  if (claim?.receiptUnavailable) {
6644
6792
  claimId = undefined;
6645
- result.deferred += 1;
6793
+ deferReceipt(receipt.threadId);
6794
+ continue;
6795
+ }
6796
+ if (claim?.retryDeferred) {
6797
+ deferReceipt(receipt.threadId);
6646
6798
  continue;
6647
6799
  }
6648
6800
  if (claim?.receiptConflict) {
@@ -6651,7 +6803,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6651
6803
  continue;
6652
6804
  }
6653
6805
  if (claim?.claimBusy) {
6654
- result.deferred += 1;
6806
+ deferReceipt(receipt.threadId);
6655
6807
  continue;
6656
6808
  }
6657
6809
  if (claim?.submissionExpired) {
@@ -6663,7 +6815,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6663
6815
  if (blocked)
6664
6816
  result.blocked += 1;
6665
6817
  else
6666
- result.deferred += 1;
6818
+ deferReceipt(receipt.threadId);
6667
6819
  continue;
6668
6820
  }
6669
6821
  const claimedMessage = claim.claimedMessage;
@@ -6674,7 +6826,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6674
6826
  result.submitted += 1;
6675
6827
  }
6676
6828
  else {
6677
- result.deferred += 1;
6829
+ deferReceipt(receipt.threadId);
6678
6830
  }
6679
6831
  await mutateThreadQueuedMessages(receipt.threadId, {
6680
6832
  type: "release",
@@ -6684,6 +6836,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6684
6836
  claimId = undefined;
6685
6837
  continue;
6686
6838
  }
6839
+ retryCount = claimedReceipt.retryCount;
6687
6840
  const finishInterrupt = async (runId) => {
6688
6841
  if (!(await renewQueuedSubmissionInterruptClaim({
6689
6842
  threadId: receipt.threadId,
@@ -6718,28 +6871,28 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6718
6871
  if (claimedReceipt.interruptRunId) {
6719
6872
  const stableIdle = await finishInterrupt(claimedReceipt.interruptRunId);
6720
6873
  if (!stableIdle) {
6721
- await retryQueuedSubmissionReceipt(receipt.threadId, receipt.messageId, Date.now() + 10_000, { claimId });
6874
+ await retryClaimedReceipt();
6722
6875
  await mutateThreadQueuedMessages(receipt.threadId, {
6723
6876
  type: "release",
6724
6877
  messageId: receipt.messageId,
6725
6878
  claimId,
6726
6879
  });
6727
6880
  claimId = undefined;
6728
- result.deferred += 1;
6881
+ deferReceipt(receipt.threadId);
6729
6882
  continue;
6730
6883
  }
6731
6884
  }
6732
6885
  const active = await getActiveRunForThreadAsync(receipt.threadId);
6733
6886
  if (active?.inFlight) {
6734
6887
  if (claimedMessage.interruptActiveRun !== true) {
6735
- await retryQueuedSubmissionReceipt(receipt.threadId, receipt.messageId, Date.now() + 10_000, { claimId });
6888
+ await retryClaimedReceipt();
6736
6889
  await mutateThreadQueuedMessages(receipt.threadId, {
6737
6890
  type: "release",
6738
6891
  messageId: receipt.messageId,
6739
6892
  claimId,
6740
6893
  });
6741
6894
  claimId = undefined;
6742
- result.deferred += 1;
6895
+ deferReceipt(receipt.threadId);
6743
6896
  continue;
6744
6897
  }
6745
6898
  const recorded = await recordQueuedSubmissionInterruptRun({
@@ -6749,25 +6902,25 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6749
6902
  claimId,
6750
6903
  });
6751
6904
  if (!recorded) {
6752
- await retryQueuedSubmissionReceipt(receipt.threadId, receipt.messageId, Date.now() + 10_000, { claimId });
6905
+ await retryClaimedReceipt();
6753
6906
  await mutateThreadQueuedMessages(receipt.threadId, {
6754
6907
  type: "release",
6755
6908
  messageId: receipt.messageId,
6756
6909
  claimId,
6757
6910
  });
6758
6911
  claimId = undefined;
6759
- result.deferred += 1;
6912
+ deferReceipt(receipt.threadId);
6760
6913
  continue;
6761
6914
  }
6762
6915
  if (!(await finishInterrupt(active.runId))) {
6763
- await retryQueuedSubmissionReceipt(receipt.threadId, receipt.messageId, Date.now() + 10_000, { claimId });
6916
+ await retryClaimedReceipt();
6764
6917
  await mutateThreadQueuedMessages(receipt.threadId, {
6765
6918
  type: "release",
6766
6919
  messageId: receipt.messageId,
6767
6920
  claimId,
6768
6921
  });
6769
6922
  claimId = undefined;
6770
- result.deferred += 1;
6923
+ deferReceipt(receipt.threadId);
6771
6924
  continue;
6772
6925
  }
6773
6926
  }
@@ -6788,6 +6941,9 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6788
6941
  ...(claimedMessage.requestAttachments !== undefined
6789
6942
  ? { requestAttachments: claimedMessage.requestAttachments }
6790
6943
  : {}),
6944
+ ...(claimedMessage.references !== undefined
6945
+ ? { references: claimedMessage.references }
6946
+ : {}),
6791
6947
  ...(claimedMessage.metadata !== undefined
6792
6948
  ? { metadata: claimedMessage.metadata }
6793
6949
  : {}),
@@ -6813,6 +6969,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6813
6969
  orgId: receipt.actor.orgId ?? null,
6814
6970
  orgScope: receipt.actor.orgScope ?? null,
6815
6971
  };
6972
+ seedAgentRunOwnerContext(admissionEvent, ownerContext);
6816
6973
  let admissionResponse;
6817
6974
  try {
6818
6975
  admissionResponse = await runWithAgentRunContext({
@@ -6827,9 +6984,9 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6827
6984
  afterError = await getQueuedSubmissionReceipt(receipt.threadId, receipt.messageId);
6828
6985
  }
6829
6986
  catch (receiptError) {
6830
- result.failed += 1;
6831
6987
  console.error(`[agent-chat] could not verify queued submission ${receipt.messageId} after admission failed:`, { error, receiptError });
6832
- claimId = undefined;
6988
+ await recoverClaimedReceipt();
6989
+ result.failed += 1;
6833
6990
  continue;
6834
6991
  }
6835
6992
  if (afterError?.state === "submitted") {
@@ -6837,14 +6994,34 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6837
6994
  claimId = undefined;
6838
6995
  continue;
6839
6996
  }
6840
- await retryQueuedSubmissionReceipt(receipt.threadId, receipt.messageId, Date.now() + 10_000, { claimId });
6997
+ const nonRetryableError = error !== null &&
6998
+ typeof error === "object" &&
6999
+ "retryable" in error &&
7000
+ error.retryable === false;
7001
+ const retryLimitReached = (afterError?.retryCount ?? 0) >= MAX_QUEUED_SUBMISSION_RETRIES;
7002
+ if (nonRetryableError || retryLimitReached) {
7003
+ const blocked = await blockClaimedReceipt();
7004
+ await mutateThreadQueuedMessages(receipt.threadId, {
7005
+ type: "release",
7006
+ messageId: receipt.messageId,
7007
+ claimId,
7008
+ });
7009
+ claimId = undefined;
7010
+ if (blocked)
7011
+ result.blocked += 1;
7012
+ else
7013
+ deferReceipt(receipt.threadId);
7014
+ console.error(`[agent-chat] queued submission admission could not be retried for ${receipt.messageId}:`, error);
7015
+ continue;
7016
+ }
7017
+ await retryClaimedReceipt(true);
6841
7018
  await mutateThreadQueuedMessages(receipt.threadId, {
6842
7019
  type: "release",
6843
7020
  messageId: receipt.messageId,
6844
7021
  claimId,
6845
7022
  });
6846
7023
  claimId = undefined;
6847
- result.deferred += 1;
7024
+ deferReceipt(receipt.threadId);
6848
7025
  console.error(`[agent-chat] queued submission admission failed for ${receipt.messageId}:`, error);
6849
7026
  continue;
6850
7027
  }
@@ -6869,18 +7046,18 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6869
7046
  admittedReceipt = await getQueuedSubmissionReceipt(receipt.threadId, receipt.messageId);
6870
7047
  }
6871
7048
  catch (error) {
6872
- result.failed += 1;
6873
7049
  console.error(`[agent-chat] could not verify queued submission ${receipt.messageId} after admission returned:`, error);
6874
- claimId = undefined;
6875
7050
  await stream
6876
7051
  ?.cancel()
6877
7052
  .catch((cancelError) => console.error(`[agent-chat] could not cancel stream for unverified queued submission ${receipt.messageId}:`, cancelError));
7053
+ await recoverClaimedReceipt();
7054
+ result.failed += 1;
6878
7055
  continue;
6879
7056
  }
6880
7057
  if (responseRunId &&
6881
7058
  (responseStatus < 400 || admittedReceipt?.state === "submitted")) {
6882
7059
  if (admittedReceipt?.state !== "submitted") {
6883
- await blockQueuedSubmissionReceipt(receipt.threadId, receipt.messageId, { claimId });
7060
+ await blockClaimedReceipt();
6884
7061
  result.failed += 1;
6885
7062
  console.error(`[agent-chat] run ${responseRunId} started without a submitted receipt for ${receipt.messageId}`);
6886
7063
  }
@@ -6897,21 +7074,38 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6897
7074
  await stream?.cancel().catch(() => { });
6898
7075
  continue;
6899
7076
  }
6900
- if (responseStatus >= 500 ||
6901
- responseCode === "run_slot_busy" ||
6902
- responseBody?.retryable === true) {
6903
- await retryQueuedSubmissionReceipt(receipt.threadId, receipt.messageId, Date.now() + 10_000, { claimId });
7077
+ if (responseCode === "run_slot_busy") {
7078
+ // The thread's run slot is still held by a run that is ending. That
7079
+ // is a wait, not a failed admission: release the claim without
7080
+ // spending a retry or setting a backoff, so the completion drain
7081
+ // for that run can claim this receipt. A backoff here would make
7082
+ // that drain skip it until the recurring sweep.
7083
+ await mutateThreadQueuedMessages(receipt.threadId, {
7084
+ type: "release",
7085
+ messageId: receipt.messageId,
7086
+ claimId,
7087
+ });
7088
+ claimId = undefined;
7089
+ deferReceipt(receipt.threadId);
7090
+ await stream?.cancel().catch(() => { });
7091
+ continue;
7092
+ }
7093
+ const retryableAdmission = responseBody?.retryable === true ||
7094
+ (responseBody?.retryable !== false && responseStatus >= 500);
7095
+ if (retryableAdmission &&
7096
+ retryCount < MAX_QUEUED_SUBMISSION_RETRIES) {
7097
+ await retryClaimedReceipt(true);
6904
7098
  await mutateThreadQueuedMessages(receipt.threadId, {
6905
7099
  type: "release",
6906
7100
  messageId: receipt.messageId,
6907
7101
  claimId,
6908
7102
  });
6909
7103
  claimId = undefined;
6910
- result.deferred += 1;
7104
+ deferReceipt(receipt.threadId);
6911
7105
  await stream?.cancel().catch(() => { });
6912
7106
  continue;
6913
7107
  }
6914
- const blocked = await blockQueuedSubmissionReceipt(receipt.threadId, receipt.messageId, { claimId });
7108
+ const blocked = await blockClaimedReceipt();
6915
7109
  await mutateThreadQueuedMessages(receipt.threadId, {
6916
7110
  type: "release",
6917
7111
  messageId: receipt.messageId,
@@ -6921,24 +7115,18 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6921
7115
  if (blocked)
6922
7116
  result.blocked += 1;
6923
7117
  else
6924
- result.deferred += 1;
7118
+ deferReceipt(receipt.threadId);
6925
7119
  await stream?.cancel().catch(() => { });
6926
7120
  }
6927
7121
  catch (error) {
6928
7122
  result.failed += 1;
6929
7123
  console.error(`[agent-chat] queued submission drain failed for ${receipt.messageId}:`, error);
6930
- if (claimId) {
6931
- try {
6932
- await retryQueuedSubmissionReceipt(receipt.threadId, receipt.messageId, Date.now() + 10_000, { claimId });
6933
- await mutateThreadQueuedMessages(receipt.threadId, {
6934
- type: "release",
6935
- messageId: receipt.messageId,
6936
- claimId,
6937
- });
6938
- }
6939
- catch (releaseError) {
6940
- console.error(`[agent-chat] could not release queued submission ${receipt.messageId}:`, releaseError);
6941
- }
7124
+ try {
7125
+ await recoverClaimedReceipt();
7126
+ }
7127
+ catch (releaseError) {
7128
+ console.error(`[agent-chat] could not release queued submission ${receipt.messageId}:`, releaseError);
7129
+ deferReceipt(receipt.threadId);
6942
7130
  }
6943
7131
  }
6944
7132
  }
@@ -9,8 +9,8 @@ export declare const AGENT_ENGINE_API_KEY_ACTION_NAME = "agent-engine-api-key";
9
9
  */
10
10
  export declare function createAgentEngineDisconnectHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
11
11
  error: string;
12
- scope?: undefined;
13
12
  ok?: undefined;
13
+ scope?: undefined;
14
14
  } | {
15
15
  ok: boolean;
16
16
  error: any;
@@ -3,7 +3,7 @@ export declare function createAgentEngineOllamaModelsHandler(): import("h3").Eve
3
3
  models?: undefined;
4
4
  ok?: undefined;
5
5
  } | {
6
- error?: undefined;
7
6
  ok: boolean;
8
7
  models: string[];
8
+ error?: undefined;
9
9
  }>>;
@@ -1,5 +1,4 @@
1
1
  export declare function getAgentNativeAnalyticsConfigScript(): string | null;
2
- export declare function getHeadScriptTag(): string | null;
3
2
  export declare function getGaInlineConfigScriptBody(options?: {
4
3
  dataLayerName?: string;
5
4
  sendPageView?: boolean;