@sentry/junior 0.266.0 → 0.268.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 (87) hide show
  1. package/dist/{actor-tlxzqaRe.js → actor-CP9K2Idu.js} +9 -1
  2. package/dist/{adapter-eRFA_naf.js → adapter-04AcD2SO.js} +5 -7
  3. package/dist/{admin-tILpP51p.js → admin-DIU1QyG3.js} +1 -1
  4. package/dist/{agent-invocations-CxKldAeB.js → agent-invocations-C1RNOCs8.js} +2 -0
  5. package/dist/{agent-runner-BtYK7bht.js → agent-runner-CAYfFmU7.js} +2636 -601
  6. package/dist/api/schema.d.ts +2 -5454
  7. package/dist/api/schema.js +6 -5
  8. package/dist/api.d.ts +6 -1
  9. package/dist/api.js +255 -1208
  10. package/dist/{app-Csbi9dW7.d.ts → app-z6Uuyq3j.d.ts} +23 -4
  11. package/dist/app.d.ts +2 -2
  12. package/dist/app.js +1869 -378
  13. package/dist/{automation-BKpY9LPa.js → automation-CmeFBSEh.js} +42 -14
  14. package/dist/{briefs-DgfWMU7e.js → briefs-DQbV2jNr.js} +4 -4
  15. package/dist/{catalog-runtime-DAJjAbSx.js → catalog-runtime-BD9GSpc6.js} +1 -1
  16. package/dist/cli/chat.js +15 -15
  17. package/dist/cli/check.js +3 -3
  18. package/dist/cli/init.js +0 -1
  19. package/dist/cli/main.js +3 -3
  20. package/dist/cli/plugins.js +4 -4
  21. package/dist/cli/snapshot-create.js +4 -4
  22. package/dist/cli/upgrade.d.ts +1 -1
  23. package/dist/cli/upgrade.js +3 -3
  24. package/dist/{client-B0YZfxNy.js → client-C1yDYjoS.js} +2 -2
  25. package/dist/{config-C0UwYqDK.js → config-DrTeF80T.js} +32 -10
  26. package/dist/{connections-Bwu3VORi.js → connections-D46f8vvi.js} +12 -12
  27. package/dist/{conversation-DF4rUcjb.js → conversation-DSo310Ps.js} +8 -1
  28. package/dist/{conversation-privacy-CY7JVjxn.js → conversation-privacy-CxlOCiUo.js} +1 -1
  29. package/dist/{credential-sync-VGAMUTGp.js → credential-sync-sm9fegLY.js} +29 -34
  30. package/dist/{credentialed-enF5Bf3y.js → credentialed-lukuD-cc.js} +2933 -1026
  31. package/dist/db-BU4LQD8s.d.ts +6 -0
  32. package/dist/{executor-TnWbvL09.js → executor-4vhvsMZJ.js} +83 -6
  33. package/dist/instrumentation.js +6 -2
  34. package/dist/{assistant-reply-UyzAfZQo.js → interruption-marker-CkncDT8d.js} +8 -2
  35. package/dist/{job-queue-DBpHmKnd.js → job-queue-In9QKz-I.js} +128 -3
  36. package/dist/{web-input-B-bMjD1V.js → list-BkgnXEEB.js} +1611 -817
  37. package/dist/{logging-Ce0mXZ8J.js → logging-DLSpkSSr.js} +11 -3
  38. package/dist/{message-VZ3DFpGb.js → message-BObyg59s.js} +4 -4
  39. package/dist/nitro.d.ts +1 -1
  40. package/dist/nitro.js +3 -3
  41. package/dist/{oauth-callback-server-CpqWLjVY.js → oauth-callback-server-B-WbSdoH.js} +2 -2
  42. package/dist/{prompt-BcCGlmg2.js → prompt-BW9jFsqZ.js} +1 -1
  43. package/dist/{registry-1BEIPdbT.js → registry-BgecKva0.js} +2 -2
  44. package/dist/{web-message-id-CJSUiksE.js → reporting-window-DVCD_10C.js} +1 -10
  45. package/dist/{resolve-BSHHkEGE.js → resolve-Cpa4Bu1O.js} +3 -3
  46. package/dist/{result-CwOpzqdh.js → result-D3TSmZZ8.js} +9 -9
  47. package/dist/{runner-CEaX04kz.js → runner-DS5OKhEp.js} +11 -11
  48. package/dist/{sandbox-egress-signals-BwtGHwqa.js → sandbox-egress-signals-CnDjY5rx.js} +1 -1
  49. package/dist/{schema-RsaBHxRH.js → schema-0050HFnB.js} +82 -5
  50. package/dist/schema-ZngqcOWM.d.ts +5813 -0
  51. package/dist/{service-account-6wC76eBZ.js → service-account-CKV2WTY7.js} +3 -3
  52. package/dist/{service-account-Dg4lIbHm.js → service-account-DGjnDw9y.js} +3 -3
  53. package/dist/{session-stop-tZOw9AJD.js → session-stop-Dam1EI7B.js} +527 -134
  54. package/dist/{skills-DzyGN7wd.js → skills-CfAnfImD.js} +2 -2
  55. package/dist/{spawn-6rokq7l_.js → spawn-cmq9p4Ly.js} +2 -2
  56. package/dist/{store-DcKkzrdt.js → store-C5PN02QO.js} +4 -4
  57. package/dist/{store-CG0VJyye.d.ts → store-xMuuXRE0.d.ts} +23 -9
  58. package/dist/store-zPEoJPBB.js +295 -0
  59. package/dist/{task-queue-Bg4RS2Gy.js → task-queue-_mf28dSu.js} +10 -5
  60. package/dist/{task-runner-8N5LIkSg.js → task-runner-DMI2prDO.js} +25 -14
  61. package/dist/{tasks-DDT-J3Rf.js → tasks-SB9z-VTU.js} +1551 -54
  62. package/dist/{thread-state-cprEaxgl.js → thread-state-BbbPh0Sn.js} +8 -18
  63. package/dist/{turn-failure-response-C8sMdsdX.js → turn-failure-response-BKKmnMB5.js} +11 -16
  64. package/dist/{turn-lifecycle-DaBVoz7h.js → turn-lifecycle-oP0kVeGz.js} +1 -1
  65. package/dist/{validation-C2lllinq.js → validation--JsAGLwc.js} +1 -1
  66. package/dist/{version-oaLfxxnf.js → version-jHwJp4hC.js} +1 -1
  67. package/dist/version.js +1 -1
  68. package/dist/{viewer-BpE6Z3qf.js → viewer-CpXTGlep.js} +329 -230
  69. package/dist/web-message-id-DlHNANtd.js +132 -0
  70. package/dist/{work-VX1SHWha.js → work-3N-GHY9m.js} +10 -10
  71. package/dist/{worker-hook-y_Y.js → worker-CCdbcItd.js} +30 -19
  72. package/migrations/0064_any_resource_event_triggers.sql +2 -0
  73. package/migrations/0065_user_customization.sql +1 -0
  74. package/migrations/0066_review_items.sql +53 -0
  75. package/migrations/0067_review_item_dedupe_tenant.sql +2 -0
  76. package/migrations/0068_review_item_slack_cards.sql +10 -0
  77. package/migrations/meta/0064_snapshot.json +3505 -0
  78. package/migrations/meta/0065_snapshot.json +3511 -0
  79. package/migrations/meta/0066_snapshot.json +4099 -0
  80. package/migrations/meta/0067_snapshot.json +3921 -0
  81. package/migrations/meta/0068_snapshot.json +4176 -0
  82. package/migrations/meta/_journal.json +36 -1
  83. package/package.json +19 -4
  84. package/dist/db-BnRqQ7G5.d.ts +0 -5
  85. package/dist/images-BKQqSi5W.js +0 -64
  86. package/dist/store-FALy-JQb.js +0 -1424
  87. package/dist/turn-session-routing-a9CHX-w6.js +0 -76
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
2
- import { m as logWarn } from "./logging-Ce0mXZ8J.js";
2
+ import { h as logWarn } from "./logging-DLSpkSSr.js";
3
3
  import { s as skillRoots } from "./package-discovery-DJBompdd.js";
4
- import { n as pluginCatalogRuntime } from "./catalog-runtime-DAJjAbSx.js";
4
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-BD9GSpc6.js";
5
5
  import path from "node:path";
6
6
  import { z } from "zod";
7
7
  import fs from "node:fs/promises";
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
2
- import { $ as actorFromRun, et as toolInvocationDestination } from "./agent-runner-BtYK7bht.js";
3
- import { n as createAndEnqueueAgentInvocation } from "./work-VX1SHWha.js";
2
+ import { Bt as actorFromRun, Vt as toolInvocationDestination } from "./agent-runner-CAYfFmU7.js";
3
+ import { n as createAndEnqueueAgentInvocation } from "./work-3N-GHY9m.js";
4
4
  // src/chat/agent-invocations/spawn.ts
5
5
  var spawn_exports = /* @__PURE__ */ __exportAll({ bindSpawnAgent: () => bindSpawnAgent });
6
6
  /** Bind a Run's Actor and credentials to new Agent invocations. */
@@ -1,8 +1,8 @@
1
1
  import { l as TURN_REASONING_LEVELS, s as modelProfileSchema } from "./model-profile-Bg8EoCKD.js";
2
- import { d as getConversationStore, p as getSqlExecutor } from "./viewer-BpE6Z3qf.js";
3
- import { a as juniorAgentInvocations, i as juniorAgentBindings, n as AGENT_INVOCATION_PARENT_MAILBOX_STATUSES, t as AGENT_INVOCATION_MAILBOX_STATUSES } from "./agent-invocations-CxKldAeB.js";
4
- import "./executor-TnWbvL09.js";
5
- import { p as credentialContextSchema } from "./registry-1BEIPdbT.js";
2
+ import { h as getSqlExecutor, p as getConversationStore } from "./viewer-CpXTGlep.js";
3
+ import { a as juniorAgentInvocations, i as juniorAgentBindings, n as AGENT_INVOCATION_PARENT_MAILBOX_STATUSES, t as AGENT_INVOCATION_MAILBOX_STATUSES } from "./agent-invocations-C1RNOCs8.js";
4
+ import "./executor-4vhvsMZJ.js";
5
+ import { p as credentialContextSchema } from "./registry-BgecKva0.js";
6
6
  import { z } from "zod";
7
7
  import { createHash } from "node:crypto";
8
8
  import { and, asc, count, countDistinct, desc, eq, inArray, lt, ne, or, sql } from "drizzle-orm";
@@ -48,6 +48,11 @@ type Usage = z.output<typeof usageSchema>;
48
48
  type AgentTurnUsage = Usage;
49
49
  type ConversationSource = "api" | "internal" | "local" | "plugin" | "event" | "scheduler" | "slack" | "web";
50
50
  type ConversationStatus = "paused" | "failed" | "idle" | "pending" | "running";
51
+ /** Cumulative duration and usage that one Run reported. */
52
+ interface ConversationRunMetrics {
53
+ durationMs: number;
54
+ usage?: AgentTurnUsage;
55
+ }
51
56
  interface ConversationExecution {
52
57
  lastCheckpointAtMs?: number;
53
58
  lastEnqueuedAtMs?: number;
@@ -73,10 +78,9 @@ interface Conversation {
73
78
  createdAtMs: number;
74
79
  destination?: Destination;
75
80
  execution: ConversationExecution;
76
- executionMetrics?: {
77
- durationMs: number;
81
+ /** Metrics of the latest Run that wrote metrics. */
82
+ executionMetrics?: ConversationRunMetrics & {
78
83
  runId?: string;
79
- usage?: AgentTurnUsage;
80
84
  };
81
85
  lastActivityAtMs: number;
82
86
  /** Immutable parent Conversation. */
@@ -115,6 +119,11 @@ interface ConversationStore {
115
119
  get(args: {
116
120
  conversationId: string;
117
121
  }): Promise<Conversation | undefined>;
122
+ /** Read one Run's stored metrics, including a Run that is not the latest. */
123
+ getRunMetrics(args: {
124
+ conversationId: string;
125
+ runId: string;
126
+ }): Promise<ConversationRunMetrics | undefined>;
118
127
  /** Resolve the durable conversation bound to one provider conversation. */
119
128
  getConversationIdByProviderConversation(args: {
120
129
  provider: string;
@@ -161,7 +170,11 @@ interface ConversationStore {
161
170
  /** Source normalized to a stable session locator; set-once when absent. */
162
171
  sessionSource?: Source;
163
172
  title?: string;
164
- /** Confirmed destination visibility; omit when unavailable. */
173
+ /**
174
+ * Current visibility from its owner, such as a Slack event channel type. It
175
+ * replaces the visibility of the shared Destination row. Omit it for saved
176
+ * values, such as visibility captured when an Automation was created.
177
+ */
165
178
  visibility?: ConversationPrivacy;
166
179
  }): Promise<void>;
167
180
  /**
@@ -176,15 +189,16 @@ interface ConversationStore {
176
189
  destination?: Destination;
177
190
  execution: ConversationExecution;
178
191
  lastActivityAtMs: number;
179
- metrics: {
180
- durationMs: number;
181
- usage?: AgentTurnUsage;
182
- } | null;
192
+ metrics: ConversationRunMetrics | null;
183
193
  actor?: StoredSlackActor;
184
194
  source?: ConversationSource;
185
195
  title?: string;
186
196
  updatedAtMs: number;
187
- /** Confirmed destination visibility; omit when unavailable. */
197
+ /**
198
+ * Current visibility from its owner, such as a Slack event channel type. It
199
+ * replaces the visibility of the shared Destination row. Omit it for saved
200
+ * values, such as visibility captured when an Automation was created.
201
+ */
188
202
  visibility?: ConversationPrivacy;
189
203
  }): Promise<void>;
190
204
  listByActivity(args?: {
@@ -0,0 +1,295 @@
1
+ import { Cn as removeActiveConversation$1, Dn as steerWebPendingMessages$1, En as startConversationWork$1, On as stopConversationWork$1, Sn as releaseConversationWork$1, Tn as requestConversationWork$1, an as checkInConversationWork$1, bn as recordAttemptFailure$1, cn as completeConversationStop$1, dn as drainConversationMailbox$1, en as ackMessages$1, fn as getConversation$1, in as cancelHumanFacingPendingMessages$1, ln as completeConversationWork$1, nn as appendInboundMessage, on as clearConsumedConversationWake$1, pn as getConversationWorkState$1, rn as beginConversationResume$1, sn as clearExpiredConversationLease$1, tn as appendExclusiveInboundMessage, un as deadLetterAttempt$1, vn as listActiveConversationIds$1, wn as requestAnotherSlice$1, xn as recordConversationRetry$1, yn as markConversationWorkEnqueued$1 } from "./tasks-SB9z-VTU.js";
2
+ import { p as getConversationStore } from "./viewer-CpXTGlep.js";
3
+ import "./job-queue-In9QKz-I.js";
4
+ // src/chat/task-execution/store.ts
5
+ function metadataStore(options) {
6
+ return options.conversationStore ?? getConversationStore();
7
+ }
8
+ function duplicateInboundNudgeIdempotencyKey(message, nowMs) {
9
+ return `duplicate:${message.conversationId}:${message.inboundMessageId}:${nowMs}`;
10
+ }
11
+ function hasRecentEnqueueMarker(conversation, nowMs) {
12
+ const lastEnqueuedAtMs = conversation.execution.lastEnqueuedAtMs;
13
+ return typeof lastEnqueuedAtMs === "number" && lastEnqueuedAtMs + 6e4 > nowMs;
14
+ }
15
+ function now() {
16
+ return Date.now();
17
+ }
18
+ async function recordExecutionMetadata(args) {
19
+ const conversation = await getConversation$1({
20
+ conversationId: args.conversationId,
21
+ state: args.state
22
+ });
23
+ if (!conversation) return;
24
+ await metadataStore(args).recordExecution({
25
+ channelName: conversation.channelName,
26
+ conversationId: conversation.conversationId,
27
+ createdAtMs: conversation.createdAtMs,
28
+ destination: conversation.destination,
29
+ execution: {
30
+ lastCheckpointAtMs: conversation.execution.lastCheckpointAtMs,
31
+ lastEnqueuedAtMs: conversation.execution.lastEnqueuedAtMs,
32
+ runId: conversation.execution.runId,
33
+ status: conversation.execution.status,
34
+ updatedAtMs: conversation.execution.updatedAtMs
35
+ },
36
+ lastActivityAtMs: conversation.lastActivityAtMs,
37
+ metrics: null,
38
+ actor: conversation.actor,
39
+ source: conversation.source,
40
+ title: conversation.title,
41
+ updatedAtMs: conversation.updatedAtMs
42
+ });
43
+ }
44
+ /** Return a persisted conversation record, if one exists. */
45
+ async function getConversation(args) {
46
+ return await getConversation$1(args);
47
+ }
48
+ /** Return a persisted conversation work record, if one exists. */
49
+ async function getConversationWorkState(args) {
50
+ return await getConversationWorkState$1(args);
51
+ }
52
+ /** Count one failed conversation execution and persist its terminal retry state. */
53
+ async function recordConversationRetry(args) {
54
+ const result = await recordConversationRetry$1(args);
55
+ await recordExecutionMetadata(args);
56
+ return result;
57
+ }
58
+ /** Count mailbox messages that have not yet reached the conversation event log. */
59
+ function countPendingConversationMessages(conversation) {
60
+ return conversation.execution.pendingMessages.length;
61
+ }
62
+ /** Return whether a conversation has pending or resumable execution work. */
63
+ function hasRunnableConversationWork(conversation) {
64
+ return conversation.execution.status !== "idle" || countPendingConversationMessages(conversation) > 0;
65
+ }
66
+ /**
67
+ * Ensure runnable conversation work has one accepted queue wake-up nudge.
68
+ *
69
+ * Ordinary wakes coalesce on a recent accepted marker. A caller can ignore the
70
+ * marker without replacing an active lease. Replacement is only for consumed
71
+ * or known-stale deliveries where another queue nudge must exist.
72
+ */
73
+ async function ensureConversationWake(args) {
74
+ const nowMs = args.nowMs ?? now();
75
+ const conversation = await getConversation$1({
76
+ conversationId: args.conversationId,
77
+ state: args.state
78
+ });
79
+ if (!conversation || !hasRunnableConversationWork(conversation)) return { status: "no_work" };
80
+ if (args.replaceExistingWake !== true && conversation.execution.lease && conversation.execution.lease.expiresAtMs > nowMs) return { status: "lease_active" };
81
+ if (args.ignoreEnqueueMarker !== true && args.replaceExistingWake !== true && hasRecentEnqueueMarker(conversation, nowMs)) return { status: "already_enqueued" };
82
+ const queueResult = await args.queue.send({
83
+ schemaVersion: 2,
84
+ conversationId: args.conversationId
85
+ }, {
86
+ delayMs: args.delayMs,
87
+ idempotencyKey: args.idempotencyKey
88
+ });
89
+ await markConversationWorkEnqueued({
90
+ conversationId: args.conversationId,
91
+ conversationStore: args.conversationStore,
92
+ nowMs,
93
+ state: args.state
94
+ });
95
+ return {
96
+ status: "enqueued",
97
+ queueMessageId: queueResult?.messageId
98
+ };
99
+ }
100
+ async function enqueueAfterAppend(args) {
101
+ const nowMs = args.nowMs ?? now();
102
+ const appendResult = args.appendResult;
103
+ if (appendResult.status === "active") return appendResult;
104
+ let idempotencyKey = args.message.inboundMessageId;
105
+ if (appendResult.status === "duplicate") {
106
+ const conversation = await getConversation$1({
107
+ conversationId: args.message.conversationId,
108
+ state: args.state
109
+ });
110
+ if (!conversation) return appendResult;
111
+ if (hasRecentEnqueueMarker(conversation, nowMs)) {
112
+ await recordExecutionMetadata({
113
+ conversationId: args.message.conversationId,
114
+ conversationStore: args.conversationStore,
115
+ state: args.state
116
+ });
117
+ return appendResult;
118
+ }
119
+ if (!conversation.execution.pendingMessages.some((message) => message.inboundMessageId === args.message.inboundMessageId)) {
120
+ await recordExecutionMetadata({
121
+ conversationId: args.message.conversationId,
122
+ conversationStore: args.conversationStore,
123
+ state: args.state
124
+ });
125
+ return appendResult;
126
+ }
127
+ idempotencyKey = duplicateInboundNudgeIdempotencyKey(args.message, nowMs);
128
+ }
129
+ const wake = await ensureConversationWake({
130
+ conversationId: args.message.conversationId,
131
+ conversationStore: args.conversationStore,
132
+ delayMs: args.queueDelayMs,
133
+ idempotencyKey,
134
+ ignoreEnqueueMarker: args.message.source === "event" ? void 0 : true,
135
+ nowMs,
136
+ queue: args.queue,
137
+ replaceExistingWake: args.replaceExistingWake,
138
+ state: args.state
139
+ });
140
+ if (wake.status !== "enqueued") await recordExecutionMetadata({
141
+ conversationId: args.message.conversationId,
142
+ conversationStore: args.conversationStore,
143
+ state: args.state
144
+ });
145
+ return {
146
+ ...appendResult,
147
+ ...wake.status === "enqueued" ? { queueMessageId: wake.queueMessageId } : void 0
148
+ };
149
+ }
150
+ /** Persist inbound work and ensure a worker wake-up. */
151
+ async function appendAndEnqueueInboundMessage(args) {
152
+ const nowMs = args.nowMs ?? now();
153
+ const result = await enqueueAfterAppend({
154
+ ...args,
155
+ appendResult: await appendInboundMessage({
156
+ message: args.message,
157
+ nowMs,
158
+ state: args.state
159
+ }),
160
+ nowMs
161
+ });
162
+ if (result.status === "active") throw new Error("Non-exclusive mailbox enqueue returned active");
163
+ return result;
164
+ }
165
+ /** Persist exclusive inbound work and wake its worker when admitted. */
166
+ async function appendAndEnqueueExclusiveInboundMessage(args) {
167
+ const nowMs = args.nowMs ?? now();
168
+ return await enqueueAfterAppend({
169
+ ...args,
170
+ appendResult: await appendExclusiveInboundMessage({
171
+ message: args.message,
172
+ nowMs,
173
+ state: args.state
174
+ }),
175
+ nowMs
176
+ });
177
+ }
178
+ /** Persist a stop request for the current Conversation run. */
179
+ async function stopConversationWork(args) {
180
+ const result = await stopConversationWork$1(args);
181
+ if (result.status === "requested") await recordExecutionMetadata(args);
182
+ return result;
183
+ }
184
+ /** Finish an observed stop request under the current worker lease. */
185
+ async function completeConversationStop(args) {
186
+ const result = await completeConversationStop$1(args);
187
+ if (result.status === "cleared") await recordExecutionMetadata(args);
188
+ return result;
189
+ }
190
+ /** Clear an accepted wake marker after its delivery finds no runnable work. */
191
+ async function clearConsumedConversationWake(args) {
192
+ const result = await clearConsumedConversationWake$1(args);
193
+ if (result) await recordExecutionMetadata(args);
194
+ return result;
195
+ }
196
+ /** Mark a conversation runnable when there is no new mailbox message. */
197
+ async function requestConversationWork(args) {
198
+ const result = await requestConversationWork$1(args);
199
+ await recordExecutionMetadata({
200
+ conversationId: args.conversationId,
201
+ conversationStore: args.conversationStore,
202
+ state: args.state
203
+ });
204
+ return result;
205
+ }
206
+ /** Record that a wake-up nudge was accepted for the conversation. */
207
+ async function markConversationWorkEnqueued(args) {
208
+ await markConversationWorkEnqueued$1(args);
209
+ await recordExecutionMetadata(args);
210
+ }
211
+ /** Try to acquire the durable execution lease for one conversation. */
212
+ async function startConversationWork(args) {
213
+ const result = await startConversationWork$1(args);
214
+ await recordExecutionMetadata(args);
215
+ return result;
216
+ }
217
+ /** Extend the durable execution lease when the worker checks in. */
218
+ async function checkInConversationWork(args) {
219
+ const result = await checkInConversationWork$1(args);
220
+ if (result) await recordExecutionMetadata(args);
221
+ return result;
222
+ }
223
+ /** Drain pending mailbox entries after the caller accepts responsibility. */
224
+ async function drainConversationMailbox(args) {
225
+ const result = await drainConversationMailbox$1(args);
226
+ if (result.changed) await recordExecutionMetadata(args);
227
+ return result.messages;
228
+ }
229
+ /** Acknowledge leased mailbox entries after the handler accepts responsibility. */
230
+ async function ackMessages(args) {
231
+ const result = await ackMessages$1(args);
232
+ await recordExecutionMetadata(args);
233
+ return result;
234
+ }
235
+ /** Cancel human-facing pending mailbox rows without requiring a worker lease. */
236
+ async function cancelHumanFacingPendingMessages(args) {
237
+ const result = await cancelHumanFacingPendingMessages$1(args);
238
+ if (result.cancelledInboundMessageIds.length > 0) await recordExecutionMetadata(args);
239
+ return result;
240
+ }
241
+ /** Mark one author's queued web messages as interrupts. */
242
+ async function steerWebPendingMessages(args) {
243
+ return await steerWebPendingMessages$1(args);
244
+ }
245
+ /** Mark the leased conversation as needing another queue-delivered slice. */
246
+ async function requestAnotherSlice(args) {
247
+ const result = await requestAnotherSlice$1(args);
248
+ await recordExecutionMetadata(args);
249
+ return result;
250
+ }
251
+ /** Begin a requested turn resume without releasing the current lease. */
252
+ async function beginConversationResume(args) {
253
+ const result = await beginConversationResume$1(args);
254
+ if (result) await recordExecutionMetadata(args);
255
+ return result;
256
+ }
257
+ /** Release the durable execution lease without changing completion state. */
258
+ async function releaseConversationWork(args) {
259
+ const result = await releaseConversationWork$1(args);
260
+ await recordExecutionMetadata(args);
261
+ return result;
262
+ }
263
+ /** Finish a leased conversation and report whether runnable work remains. */
264
+ async function completeConversationWork(args) {
265
+ const result = await completeConversationWork$1(args);
266
+ await recordExecutionMetadata(args);
267
+ return result;
268
+ }
269
+ /** Record one failed delivery attempt and dead-letter messages at their limit. */
270
+ async function recordAttemptFailure(args) {
271
+ const result = await recordAttemptFailure$1(args);
272
+ if (result.status === "recorded") await recordExecutionMetadata(args);
273
+ return result;
274
+ }
275
+ /** Record a terminal failure completion for a leased conversation. */
276
+ async function deadLetterAttempt(args) {
277
+ const result = await deadLetterAttempt$1(args);
278
+ await recordExecutionMetadata(args);
279
+ return result;
280
+ }
281
+ /** Recover an expired lease and persist the resulting retry state. */
282
+ async function clearExpiredConversationLease(args) {
283
+ const result = await clearExpiredConversationLease$1(args);
284
+ await recordExecutionMetadata(args);
285
+ return result;
286
+ }
287
+ /** Remove one conversation from the active index after it is missing or idle. */
288
+ async function removeActiveConversation(args) {
289
+ return await removeActiveConversation$1(args);
290
+ }
291
+ /** List active conversation ids by oldest execution update first. */
292
+ async function listActiveConversationIds(args = {}) {
293
+ return await listActiveConversationIds$1(args);
294
+ }
295
+ export { requestAnotherSlice as C, stopConversationWork as D, steerWebPendingMessages as E, removeActiveConversation as S, startConversationWork as T, hasRunnableConversationWork as _, cancelHumanFacingPendingMessages as a, recordConversationRetry as b, clearExpiredConversationLease as c, countPendingConversationMessages as d, deadLetterAttempt as f, getConversationWorkState as g, getConversation as h, beginConversationResume as i, completeConversationStop as l, ensureConversationWake as m, appendAndEnqueueExclusiveInboundMessage as n, checkInConversationWork as o, drainConversationMailbox as p, appendAndEnqueueInboundMessage as r, clearConsumedConversationWake as s, ackMessages as t, completeConversationWork as u, listActiveConversationIds as v, requestConversationWork as w, releaseConversationWork as x, recordAttemptFailure as y };
@@ -1,5 +1,5 @@
1
- import { m as logWarn } from "./logging-Ce0mXZ8J.js";
2
- import { c as QUEUE_SIGNATURE_MAX_AGE_MS, d as getQueueProvider, l as signQueueMessage, p as runWithTurnRequestDeadline, u as verifyQueueMessage } from "./job-queue-DBpHmKnd.js";
1
+ import { h as logWarn } from "./logging-DLSpkSSr.js";
2
+ import { c as QUEUE_SIGNATURE_MAX_AGE_MS, d as getQueueProvider, l as signQueueMessage, p as runWithTurnRequestDeadline, u as verifyQueueMessage } from "./job-queue-In9QKz-I.js";
3
3
  import { z } from "zod";
4
4
  import { createHash } from "node:crypto";
5
5
  // src/chat/queue/callback.ts
@@ -44,10 +44,11 @@ function queueCallback(options) {
44
44
  return {
45
45
  /** Run a message that an in-process queue already trusts. */
46
46
  consume,
47
+ consumer,
47
48
  create: () => getQueueProvider().createCallback(consumer),
48
49
  registerDev: () => {
49
50
  if (process.env.NODE_ENV !== "development") return;
50
- return getQueueProvider().registerDevConsumer(consumer);
51
+ return getQueueProvider().registerDevConsumer?.(consumer);
51
52
  }
52
53
  };
53
54
  }
@@ -109,7 +110,7 @@ function pluginTaskCallback() {
109
110
  maxDeliveries: PLUGIN_TASK_MAX_DELIVERIES,
110
111
  onRejected: logPluginTaskQueueMessageRejected,
111
112
  run: async (message) => {
112
- const { processPluginTask } = await import("./task-runner-8N5LIkSg.js").then((n) => n.r);
113
+ const { processPluginTask } = await import("./task-runner-DMI2prDO.js").then((n) => n.r);
113
114
  await processPluginTask(message);
114
115
  },
115
116
  topic: PLUGIN_TASK_QUEUE_TOPIC,
@@ -127,8 +128,12 @@ async function sendVercelPluginTask(message) {
127
128
  function createVercelPluginTaskCallback() {
128
129
  return pluginTaskCallback().create();
129
130
  }
131
+ /** Return the queue consumer for plugin tasks, for a pulling queue worker. */
132
+ function pluginTaskQueueConsumer() {
133
+ return pluginTaskCallback().consumer;
134
+ }
130
135
  /** Register the local-dev consumer for plugin tasks. */
131
136
  function registerVercelPluginTaskDevConsumer() {
132
137
  return pluginTaskCallback().registerDev();
133
138
  }
134
- export { registerVercelPluginTaskDevConsumer as a, pluginTaskParamsSchema as i, createVercelPluginTaskCallback as n, sendVercelPluginTask as o, pluginTaskId as r, queueCallback as s, PLUGIN_TASK_QUEUE_TOPIC as t };
139
+ export { pluginTaskQueueConsumer as a, queueCallback as c, pluginTaskParamsSchema as i, createVercelPluginTaskCallback as n, registerVercelPluginTaskDevConsumer as o, pluginTaskId as r, sendVercelPluginTask as s, PLUGIN_TASK_QUEUE_TOPIC as t };
@@ -1,17 +1,16 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
2
- import { $t as isToolResultMessage, Gt as getPiMessageRole, Nt as getTurnRecord, Qt as isToolResultError, X as hydrateConversationMessages, Yt as instructionTextForProjection, en as normalizeToolNameFromResult, i as readScheduledAutomation, l as blockEventAutomation, m as getEventAutomation, nn as stripRuntimeTurnContext, nt as fallbackShortTitle } from "./tasks-DDT-J3Rf.js";
3
- import { g as runBestEffort, m as logWarn } from "./logging-Ce0mXZ8J.js";
4
- import { g as parseSlackMessageTs } from "./actor-tlxzqaRe.js";
5
- import { E as agentTurnTotalTokens, T as agentTurnCostUsd, d as getConversationStore, f as getDb, r as readActorIdentity } from "./viewer-BpE6Z3qf.js";
6
- import { s as juniorConversations } from "./agent-invocations-CxKldAeB.js";
7
- import { a as juniorAutomationRuns, o as juniorAutomationVersions, s as juniorAutomations } from "./executor-TnWbvL09.js";
2
+ import { A as resolveConversationRouting, Gn as isToolResultError, Hn as instructionTextForProjection, Kn as isToolResultMessage, Rn as getPiMessageRole, Yn as stripRuntimeTurnContext, Yt as getTurnRecord, ft as hydrateConversationMessages, i as readScheduledAutomation, l as blockEventAutomation, m as getEventAutomation, qn as normalizeToolNameFromResult, vt as fallbackShortTitle } from "./tasks-SB9z-VTU.js";
3
+ import { _ as runBestEffort, h as logWarn } from "./logging-DLSpkSSr.js";
4
+ import { m as parseSlackMessageTs } from "./actor-CP9K2Idu.js";
5
+ import { F as agentTurnTotalTokens, P as agentTurnCostUsd, i as readActorIdentity, m as getDb, p as getConversationStore } from "./viewer-CpXTGlep.js";
6
+ import { s as juniorConversations } from "./agent-invocations-C1RNOCs8.js";
7
+ import { d as juniorAutomations, l as juniorAutomationRuns, u as juniorAutomationVersions } from "./executor-4vhvsMZJ.js";
8
8
  import { m as sameActorIdentity } from "./history-C84mlAwO.js";
9
- import { h as credentialSubjectSchema } from "./registry-1BEIPdbT.js";
10
- import { An as createPluginLogger, Bn as createPluginConversationEvents, Dn as createPluginState, On as createPluginEmbedder, _t as openSlackDirectMessage, fn as getDashboardTaskLink, g as coreTaskRegistrations, kn as createPluginModel, ln as JUNIOR_THREAD_STATE_TTL_MS, lt as escapeSlackMrkdwnText, nr as createPluginCache, p as getPlugins, ut as formatSlackLink, vt as postSlackMessage } from "./credentialed-enF5Bf3y.js";
11
- import { r as getStateAdapter } from "./adapter-eRFA_naf.js";
12
- import { r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-cprEaxgl.js";
13
- import { t as resolveConversationRouting } from "./turn-session-routing-a9CHX-w6.js";
14
- import { i as pluginTaskParamsSchema, o as sendVercelPluginTask, r as pluginTaskId } from "./task-queue-Bg4RS2Gy.js";
9
+ import { h as credentialSubjectSchema } from "./registry-BgecKva0.js";
10
+ import { Fn as createPluginModel, In as createPluginLogger, Kn as createPluginConversationEvents, Nn as createPluginState, Pn as createPluginEmbedder, Q as openSlackDirectMessage, U as escapeSlackMrkdwnText, W as formatSlackLink, _n as getDashboardTaskLink, cr as createPluginCache, g as coreTaskRegistrations, p as getPlugins, pn as JUNIOR_THREAD_STATE_TTL_MS, tt as postSlackMessage } from "./credentialed-lukuD-cc.js";
11
+ import { i as getStateAdapter } from "./adapter-04AcD2SO.js";
12
+ import { o as coerceThreadConversationState, r as getPersistedThreadState } from "./thread-state-BbbPh0Sn.js";
13
+ import { i as pluginTaskParamsSchema, r as pluginTaskId, s as sendVercelPluginTask } from "./task-queue-_mf28dSu.js";
15
14
  import { z } from "zod";
16
15
  import { createHash } from "node:crypto";
17
16
  import { and, asc, count, desc, eq, gte, inArray, isNotNull, lte, max, sql } from "drizzle-orm";
@@ -117,7 +116,7 @@ const EMPTY_RUN_WINDOWS = {
117
116
  30: 0,
118
117
  90: 0
119
118
  };
120
- /** Empty run windows for automations with no execution history. */
119
+ /** Empty run or cost windows for automations with no execution history. */
121
120
  function emptyAutomationRunWindows() {
122
121
  return { ...EMPTY_RUN_WINDOWS };
123
122
  }
@@ -199,7 +198,13 @@ async function readAutomationExecutionSummaries(automationIds, options = {}) {
199
198
  conversationId: juniorAutomationRuns.conversationId,
200
199
  automationId: juniorAutomationRuns.automationId
201
200
  }).from(juniorAutomationRuns).where(selected).orderBy(juniorAutomationRuns.automationId, desc(juniorAutomationRuns.completedAtMs), desc(juniorAutomationRuns.id)).as("latest_task_execution");
201
+ const conversationCost = conversationUsageCostExpr(juniorConversations.usage);
202
+ const costSince = (sinceMs) => sql`coalesce(sum(${conversationCost}) filter (where ${juniorAutomationRuns.completedAtMs} >= ${sinceMs}), 0)::double precision`;
202
203
  const rows = await db.select({
204
+ costLast1Day: costSince(oneDayAgoMs),
205
+ costLast7Days: costSince(sevenDaysAgoMs),
206
+ costLast30Days: costSince(thirtyDaysAgoMs),
207
+ costLast90Days: costSince(ninetyDaysAgoMs),
203
208
  lastRunStatus: latest.status,
204
209
  lastConversationId: latest.conversationId,
205
210
  lastExecutedAtMs: max(juniorAutomationRuns.completedAtMs),
@@ -209,8 +214,14 @@ async function readAutomationExecutionSummaries(automationIds, options = {}) {
209
214
  runsLast90Days: sql`count(*) filter (where ${juniorAutomationRuns.completedAtMs} >= ${ninetyDaysAgoMs})::int`,
210
215
  automationId: juniorAutomationRuns.automationId,
211
216
  totalRuns: sql`count(*)::int`
212
- }).from(juniorAutomationRuns).innerJoin(latest, eq(latest.automationId, juniorAutomationRuns.automationId)).where(selected).groupBy(juniorAutomationRuns.automationId, latest.conversationId, latest.status);
217
+ }).from(juniorAutomationRuns).innerJoin(latest, eq(latest.automationId, juniorAutomationRuns.automationId)).leftJoin(juniorConversations, executionConversation()).where(selected).groupBy(juniorAutomationRuns.automationId, latest.conversationId, latest.status);
213
218
  return new Map(rows.map((row) => [row.automationId, {
219
+ costUsd: {
220
+ 1: addUsd(0, row.costLast1Day),
221
+ 7: addUsd(0, row.costLast7Days),
222
+ 30: addUsd(0, row.costLast30Days),
223
+ 90: addUsd(0, row.costLast90Days)
224
+ },
214
225
  lastRunStatus: row.lastRunStatus,
215
226
  ...row.lastConversationId ? { lastConversationId: row.lastConversationId } : void 0,
216
227
  ...row.lastExecutedAtMs !== null ? { lastExecutedAtMs: row.lastExecutedAtMs } : void 0,