@sentry/junior 0.268.0 → 0.269.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 (82) hide show
  1. package/README.md +2 -9
  2. package/dist/{adapter-04AcD2SO.js → adapter-2-CG25be.js} +3 -49
  3. package/dist/{admin-DIU1QyG3.js → admin-DSs8S5Uy.js} +1 -1
  4. package/dist/{agent-runner-CAYfFmU7.js → agent-runner-CrDrPUtY.js} +3208 -2826
  5. package/dist/api/schema.d.ts +2 -3
  6. package/dist/api/schema.js +7 -7
  7. package/dist/api.d.ts +3 -1
  8. package/dist/api.js +157 -298
  9. package/dist/{app-z6Uuyq3j.d.ts → app-BrMMzjYm.d.ts} +8 -2
  10. package/dist/app.d.ts +1 -1
  11. package/dist/app.js +121 -207
  12. package/dist/{automation-CmeFBSEh.js → automation-p87hg_AV.js} +74 -74
  13. package/dist/{briefs-DQbV2jNr.js → briefs-PtODdLNu.js} +4 -4
  14. package/dist/{catalog-runtime-BD9GSpc6.js → catalog-runtime-BsoSmTM0.js} +1 -1
  15. package/dist/cli/chat.js +16 -26
  16. package/dist/cli/check.js +3 -3
  17. package/dist/cli/main.js +5 -3
  18. package/dist/cli/plugins.js +4 -4
  19. package/dist/cli/snapshot-create.js +4 -4
  20. package/dist/cli/upgrade.d.ts +1 -1
  21. package/dist/cli/upgrade.js +3 -3
  22. package/dist/{client-C1yDYjoS.js → client-Cqf4TboL.js} +20 -15
  23. package/dist/{config-DrTeF80T.js → config-CPsE4T5L.js} +2 -2
  24. package/dist/{connections-D46f8vvi.js → connections-upFXLmhG.js} +10 -10
  25. package/dist/{conversation-DSo310Ps.js → conversation-CTpD_PGk.js} +7 -84
  26. package/dist/{conversation-privacy-CxlOCiUo.js → conversation-privacy-D6zJc8ff.js} +1 -1
  27. package/dist/{credential-sync-sm9fegLY.js → credential-sync-CS_6IC-f.js} +15 -14
  28. package/dist/{credentialed-lukuD-cc.js → credentialed-BU-OW7HP.js} +548 -71
  29. package/dist/{store-xMuuXRE0.d.ts → db-BzOCzVb1.d.ts} +4 -0
  30. package/dist/{executor-4vhvsMZJ.js → executor-CNS7ONt-.js} +6 -6
  31. package/dist/instrumentation.js +2 -2
  32. package/dist/{interruption-marker-CkncDT8d.js → interruption-marker-g6Xup3Fk.js} +1 -1
  33. package/dist/{job-queue-In9QKz-I.js → job-queue-DI-k-Bbk.js} +2 -2
  34. package/dist/{list-BkgnXEEB.js → list-CGoQdXTp.js} +193 -656
  35. package/dist/locks-D-0h111u.js +48 -0
  36. package/dist/{logging-DLSpkSSr.js → logging-n7knse-O.js} +1 -1
  37. package/dist/{history-C84mlAwO.js → media-85PDJxO_.js} +83 -1
  38. package/dist/{message-BObyg59s.js → message-BpaWd8TT.js} +4 -4
  39. package/dist/nitro.d.ts +1 -1
  40. package/dist/nitro.js +3 -3
  41. package/dist/{oauth-callback-server-B-WbSdoH.js → oauth-callback-server-CpGmEw_i.js} +2 -2
  42. package/dist/{prompt-BW9jFsqZ.js → prompt-BlQB0QQt.js} +1 -1
  43. package/dist/{registry-BgecKva0.js → registry-By36_xsm.js} +1 -1
  44. package/dist/reporting-schema-CZREhYc-.js +104 -0
  45. package/dist/{web-message-id-DlHNANtd.js → reporting-window-CVarfId9.js} +130 -7
  46. package/dist/{resolve-Cpa4Bu1O.js → resolve-CUIBcdPd.js} +3 -3
  47. package/dist/{result-D3TSmZZ8.js → result-BemsOMOO.js} +30 -11
  48. package/dist/{runner-DS5OKhEp.js → runner-BVok7PAA.js} +12 -11
  49. package/dist/{sandbox-egress-signals-CnDjY5rx.js → sandbox-egress-signals-BSUWQI95.js} +1 -1
  50. package/dist/{schema-0050HFnB.js → schema-ChnFo5f2.js} +36 -20
  51. package/dist/{schema-ZngqcOWM.d.ts → schema-jK4-1u_H.d.ts} +126 -12
  52. package/dist/{service-account-CKV2WTY7.js → service-account-DHvlLnZw.js} +4 -3
  53. package/dist/{service-account-DGjnDw9y.js → service-account-hMmESDcr.js} +3 -3
  54. package/dist/{session-stop-Dam1EI7B.js → session-stop-BQW_iFcd.js} +15 -15
  55. package/dist/{skills-CfAnfImD.js → skills-DmJJIuLF.js} +2 -2
  56. package/dist/{spawn-cmq9p4Ly.js → spawn-ChCm46i-.js} +2 -2
  57. package/dist/{store-C5PN02QO.js → store-1DVhoKOL.js} +3 -3
  58. package/dist/{store-zPEoJPBB.js → store-DCo2n5iJ.js} +3 -3
  59. package/dist/{task-queue-_mf28dSu.js → task-queue-HMC4QjFm.js} +3 -3
  60. package/dist/task-runner-cA6yjn_E.js +269 -0
  61. package/dist/{thread-state-BbbPh0Sn.js → thread-state-CHy8LS0C.js} +5 -5
  62. package/dist/{turn-failure-response-BKKmnMB5.js → turn-failure-response-Dr7erLWs.js} +9 -9
  63. package/dist/{turn-lifecycle-oP0kVeGz.js → turn-lifecycle-bf2fIYi_.js} +1 -1
  64. package/dist/{tasks-SB9z-VTU.js → turn-session-routing-BqO0qXLk.js} +928 -116
  65. package/dist/{validation--JsAGLwc.js → validation-DHR1ivfh.js} +1 -1
  66. package/dist/{version-jHwJp4hC.js → version-CXCHLgWm.js} +1 -1
  67. package/dist/version.js +1 -1
  68. package/dist/{viewer-CpXTGlep.js → viewer-DSbD6DF6.js} +201 -27
  69. package/dist/{work-3N-GHY9m.js → work-BE_qTYGi.js} +17 -36
  70. package/dist/{worker-CCdbcItd.js → worker-Cm9_sWXg.js} +15 -7
  71. package/migrations/0069_system_identity.sql +25 -0
  72. package/migrations/0070_review_item_foreign_keys.sql +5 -0
  73. package/migrations/AGENTS.md +17 -0
  74. package/migrations/meta/0069_snapshot.json +3979 -0
  75. package/migrations/meta/0070_snapshot.json +3997 -0
  76. package/migrations/meta/_journal.json +15 -1
  77. package/package.json +4 -4
  78. package/dist/db-BU4LQD8s.d.ts +0 -6
  79. package/dist/history-BgI33Kie.d.ts +0 -78
  80. package/dist/reporting-window-DVCD_10C.js +0 -227
  81. package/dist/task-runner-DMI2prDO.js +0 -1073
  82. package/migrations/README.md +0 -30
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
2
- import { h as logWarn } from "./logging-DLSpkSSr.js";
2
+ import { h as logWarn } from "./logging-n7knse-O.js";
3
3
  import { s as skillRoots } from "./package-discovery-DJBompdd.js";
4
- import { n as pluginCatalogRuntime } from "./catalog-runtime-BD9GSpc6.js";
4
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-BsoSmTM0.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 { Bt as actorFromRun, Vt as toolInvocationDestination } from "./agent-runner-CAYfFmU7.js";
3
- import { n as createAndEnqueueAgentInvocation } from "./work-3N-GHY9m.js";
2
+ import { At as actorFromRun, jt as toolInvocationDestination } from "./agent-runner-CrDrPUtY.js";
3
+ import { n as createAndEnqueueAgentInvocation } from "./work-BE_qTYGi.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 { h as getSqlExecutor, p as getConversationStore } from "./viewer-CpXTGlep.js";
2
+ import { C as getSqlExecutor, x as getConversationStore } from "./viewer-DSbD6DF6.js";
3
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";
4
+ import "./executor-CNS7ONt-.js";
5
+ import { p as credentialContextSchema } from "./registry-By36_xsm.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";
@@ -1,6 +1,6 @@
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";
1
+ import { $n as recordAttemptFailure$1, Bn as clearExpiredConversationLease$1, Fn as appendInboundMessage, Gn as getConversation$1, Hn as completeConversationWork$1, In as beginConversationResume$1, Kn as getConversationWorkState$1, Ln as cancelHumanFacingPendingMessages$1, Nn as ackMessages$1, Pn as appendExclusiveInboundMessage, Qn as markConversationWorkEnqueued$1, Rn as checkInConversationWork$1, Un as deadLetterAttempt$1, Vn as completeConversationStop$1, Wn as drainConversationMailbox$1, Zn as listActiveConversationIds$1, ar as startConversationWork$1, er as recordConversationRetry$1, ir as requestConversationWork$1, nr as removeActiveConversation$1, or as steerWebPendingMessages$1, rr as requestAnotherSlice$1, sr as stopConversationWork$1, tr as releaseConversationWork$1, zn as clearConsumedConversationWake$1 } from "./turn-session-routing-BqO0qXLk.js";
2
+ import { x as getConversationStore } from "./viewer-DSbD6DF6.js";
3
+ import "./job-queue-DI-k-Bbk.js";
4
4
  // src/chat/task-execution/store.ts
5
5
  function metadataStore(options) {
6
6
  return options.conversationStore ?? getConversationStore();
@@ -1,5 +1,5 @@
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";
1
+ import { h as logWarn } from "./logging-n7knse-O.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-DI-k-Bbk.js";
3
3
  import { z } from "zod";
4
4
  import { createHash } from "node:crypto";
5
5
  // src/chat/queue/callback.ts
@@ -110,7 +110,7 @@ function pluginTaskCallback() {
110
110
  maxDeliveries: PLUGIN_TASK_MAX_DELIVERIES,
111
111
  onRejected: logPluginTaskQueueMessageRejected,
112
112
  run: async (message) => {
113
- const { processPluginTask } = await import("./task-runner-DMI2prDO.js").then((n) => n.r);
113
+ const { processPluginTask } = await import("./task-runner-cA6yjn_E.js").then((n) => n.r);
114
114
  await processPluginTask(message);
115
115
  },
116
116
  topic: PLUGIN_TASK_QUEUE_TOPIC,
@@ -0,0 +1,269 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
2
+ import { Er as normalizeToolNameFromResult, Gt as hydrateConversationMessages, On as getTurnRecord, Or as stripRuntimeTurnContext, Tr as isToolResultMessage, _r as getPiMessageRole, t as resolveConversationRouting, u as getDispatchRecord, wr as isToolResultError, xr as instructionTextForProjection } from "./turn-session-routing-BqO0qXLk.js";
3
+ import { m as parseSlackMessageTs } from "./actor-CP9K2Idu.js";
4
+ import { S as getDb, i as readActorIdentity, x as getConversationStore } from "./viewer-DSbD6DF6.js";
5
+ import { _ as sameActorIdentity } from "./media-85PDJxO_.js";
6
+ import { ar as createPluginLogger, g as coreTaskRegistrations, hr as createPluginConversationEvents, ir as createPluginModel, jr as createPluginCache, nr as createPluginState, p as getPlugins, rr as createPluginEmbedder } from "./credentialed-BU-OW7HP.js";
7
+ import { r as getStateAdapter } from "./adapter-2-CG25be.js";
8
+ import { o as coerceThreadConversationState, r as getPersistedThreadState } from "./thread-state-CHy8LS0C.js";
9
+ import { i as pluginTaskParamsSchema, r as pluginTaskId, s as sendVercelPluginTask } from "./task-queue-HMC4QjFm.js";
10
+ import { pluginRunContextSchema } from "@sentry/junior-plugin-api";
11
+ // src/chat/plugins/task-runner.ts
12
+ /**
13
+ * Plugin background-task orchestration.
14
+ *
15
+ * Core schedules tasks from completed sessions and exposes plugins only a
16
+ * bounded run projection rather than live runtime internals or queue
17
+ * payloads.
18
+ */
19
+ var task_runner_exports = /* @__PURE__ */ __exportAll({
20
+ processPluginTask: () => processPluginTask,
21
+ scheduleSessionCompletedPluginTasks: () => scheduleSessionCompletedPluginTasks
22
+ });
23
+ const PLUGIN_TASK_LOCK_TTL_MS = 3e5;
24
+ function isRecord(value) {
25
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
26
+ }
27
+ function textPart(value) {
28
+ if (isRecord(value) && value.type === "text" && typeof value.text === "string") return value.text;
29
+ }
30
+ function messageText(message) {
31
+ const content = message.content;
32
+ if (typeof content === "string") return sanitizeText(content);
33
+ if (!Array.isArray(content)) return "";
34
+ return sanitizeText(content.map(textPart).filter(Boolean).join("\n"));
35
+ }
36
+ function toolResultText(message) {
37
+ const record = message;
38
+ return sanitizeText([
39
+ messageText(message),
40
+ record.output,
41
+ record.result,
42
+ record.stdout,
43
+ record.stderr,
44
+ record.toolResult
45
+ ].filter((value) => typeof value === "string" && value.length > 0).join("\n"));
46
+ }
47
+ function sanitizeText(text) {
48
+ return text.replace(/<data_base64>[\s\S]*?<\/data_base64>/g, "<data_base64>[omitted]</data_base64>").replace(/data:image\/[a-z0-9.+-]+;base64,[a-z0-9+/=]+/gi, "[image data omitted]").replaceAll("\0", " ").trim();
49
+ }
50
+ /** Build the transcript provenance for a user message from its Pi provenance. */
51
+ function messageProvenance(provenance) {
52
+ return {
53
+ authority: provenance.authority,
54
+ ...provenance.actor ? { actor: provenance.actor } : void 0
55
+ };
56
+ }
57
+ function runTranscriptEntry(message, provenance, runActor) {
58
+ const role = getPiMessageRole(message);
59
+ if (role === "user" || role === "assistant") {
60
+ const text = role === "user" ? instructionTextForProjection(messageText(message)) : messageText(message);
61
+ if (!text) return;
62
+ if (role === "assistant") return {
63
+ type: "message",
64
+ role,
65
+ text
66
+ };
67
+ return {
68
+ type: "message",
69
+ role,
70
+ text,
71
+ provenance: messageProvenance(provenance),
72
+ isRunActor: sameActorIdentity(provenance.actor, runActor)
73
+ };
74
+ }
75
+ if (!isToolResultMessage(message)) return;
76
+ const toolName = normalizeToolNameFromResult(message);
77
+ if (!toolName) return;
78
+ const text = toolResultText(message);
79
+ return {
80
+ type: "toolResult",
81
+ toolName,
82
+ isError: isToolResultError(message),
83
+ ...text ? { text } : void 0
84
+ };
85
+ }
86
+ /**
87
+ * Slice the current turn's Pi messages with their aligned provenance and strip
88
+ * runtime turn context, keeping each surviving message paired with the exact
89
+ * provenance recorded for it. Stripping can drop or rewrite messages, so the
90
+ * pairing is applied per message rather than by post-strip index.
91
+ */
92
+ function turnMessagesWithProvenance(record) {
93
+ const startIndex = record.turnStartMessageIndex ?? 0;
94
+ const messages = record.piMessages.slice(startIndex);
95
+ const provenance = record.piMessageProvenance.slice(startIndex);
96
+ const paired = [];
97
+ for (const [index, message] of messages.entries()) for (const stripped of stripRuntimeTurnContext([message])) paired.push({
98
+ message: stripped,
99
+ provenance: provenance[index] ?? { authority: "context" }
100
+ });
101
+ return paired;
102
+ }
103
+ /** Recover the Slack context author identity from a persisted thread message. */
104
+ function slackContextAuthor(location, message) {
105
+ const userId = message.author?.userId?.trim();
106
+ if (!userId) return;
107
+ return {
108
+ platform: "slack",
109
+ teamId: location.teamId,
110
+ userId,
111
+ ...message.author?.userName ? { userName: message.author.userName } : void 0,
112
+ ...message.author?.fullName ? { fullName: message.author.fullName } : void 0
113
+ };
114
+ }
115
+ function slackTimestampMs(value) {
116
+ const timestamp = parseSlackMessageTs(value);
117
+ if (!timestamp) return;
118
+ const timestampMs = Number(timestamp) * 1e3;
119
+ return Number.isFinite(timestampMs) ? timestampMs : void 0;
120
+ }
121
+ function conversationMessageTimestampMs(message) {
122
+ if (message.meta?.slackTs !== void 0) return slackTimestampMs(message.meta.slackTs);
123
+ return Number.isFinite(message.createdAtMs) ? message.createdAtMs : void 0;
124
+ }
125
+ function messageExistedAtRunCompletion(message, completedAtMs) {
126
+ const messageTimestampMs = conversationMessageTimestampMs(message);
127
+ return messageTimestampMs !== void 0 && messageTimestampMs <= completedAtMs;
128
+ }
129
+ /**
130
+ * Project bounded public-thread context into the run transcript.
131
+ *
132
+ * Prior public Slack messages from the current Conversation are durable
133
+ * evidence a completed run may have acted on, so passive consumers can cite
134
+ * them. They are always context authority (never instruction), and private or
135
+ * local Conversations add nothing here.
136
+ */
137
+ async function loadConversationContextTranscriptEntries(record, location, visibility, runActor) {
138
+ if (location?.provider !== "slack" || visibility !== "public") return [];
139
+ const state = await getPersistedThreadState(record.conversationId);
140
+ const conversation = coerceThreadConversationState(state);
141
+ await hydrateConversationMessages({
142
+ conversation,
143
+ conversationId: record.conversationId
144
+ });
145
+ const entries = [];
146
+ for (const message of conversation.messages) {
147
+ if (message.role !== "user") continue;
148
+ if (!messageExistedAtRunCompletion(message, record.updatedAtMs)) continue;
149
+ const text = sanitizeText(message.text);
150
+ if (!text) continue;
151
+ const author = slackContextAuthor(location, message);
152
+ entries.push({
153
+ type: "message",
154
+ role: "user",
155
+ text,
156
+ provenance: {
157
+ authority: "context",
158
+ ...author ? { actor: author } : void 0
159
+ },
160
+ isRunActor: sameActorIdentity(author, runActor)
161
+ });
162
+ }
163
+ return entries;
164
+ }
165
+ async function withPluginTaskLock(taskId, callback) {
166
+ const state = getStateAdapter();
167
+ await state.connect();
168
+ const lock = await state.acquireLock(`plugin:task:${taskId}`, PLUGIN_TASK_LOCK_TTL_MS);
169
+ if (!lock) throw new Error(`Could not acquire plugin task lock for ${taskId}`);
170
+ try {
171
+ return await callback();
172
+ } finally {
173
+ await state.releaseLock(lock);
174
+ }
175
+ }
176
+ /** Load the bounded completed-run projection exposed to plugin tasks. */
177
+ async function loadPluginRun(params) {
178
+ const record = await getTurnRecord(params.conversationId, params.sessionId);
179
+ if (!record) throw new Error("Completed plugin task session record is unavailable");
180
+ if (record.state !== "completed") throw new Error("Completed plugin task session record is not completed");
181
+ const conversationStore = getConversationStore();
182
+ const routing = await resolveConversationRouting({
183
+ conversationId: params.conversationId,
184
+ conversationStore
185
+ });
186
+ if (!routing) throw new Error(`Conversation ${params.conversationId} is missing durable routing metadata`);
187
+ const source = record.source ?? routing.source;
188
+ if (!source) throw new Error("Completed plugin task session record is missing Source");
189
+ const conversation = await conversationStore.get({ conversationId: params.conversationId });
190
+ const runActor = record.actor ?? record.actors[0] ?? (record.dispatchId ? (await getDispatchRecord(record.dispatchId))?.actor : void 0);
191
+ const actorUser = runActor ? (await readActorIdentity(runActor))?.user : void 0;
192
+ const runEntries = turnMessagesWithProvenance(record).map(({ message, provenance }) => runTranscriptEntry(message, provenance, runActor)).filter((entry) => Boolean(entry));
193
+ const runMessageTexts = new Set(runEntries.filter((entry) => entry.type === "message").map((entry) => entry.text));
194
+ const contextEntries = (await loadConversationContextTranscriptEntries(record, conversation?.location, conversation?.visibility, runActor)).filter((entry) => entry.type !== "message" || !runMessageTexts.has(entry.text));
195
+ return pluginRunContextSchema.parse({
196
+ ...actorUser ? { actorUserId: actorUser.id } : void 0,
197
+ completedAtMs: record.updatedAtMs,
198
+ conversationId: record.conversationId,
199
+ destination: routing.destination,
200
+ ...routing.location ? { locationId: routing.location.id } : void 0,
201
+ actors: record.actors,
202
+ ...runActor ? { actor: runActor } : void 0,
203
+ runId: record.turnId,
204
+ source,
205
+ transcript: [...contextEntries, ...runEntries]
206
+ });
207
+ }
208
+ /** Build the plugin-facing context for one claimed task attempt. */
209
+ function taskPluginContext(plugin, message, options = {}) {
210
+ const pluginName = plugin.manifest.name;
211
+ const sessionParams = pluginTaskParamsSchema.parse(message.params);
212
+ return {
213
+ db: getDb(),
214
+ embedder: createPluginEmbedder(pluginName, { signal: options.signal }),
215
+ events: createPluginConversationEvents({
216
+ conversationId: sessionParams.conversationId,
217
+ operationId: pluginTaskId(message),
218
+ plugin,
219
+ turnId: sessionParams.sessionId
220
+ }),
221
+ id: pluginTaskId(message),
222
+ log: createPluginLogger(pluginName),
223
+ model: createPluginModel(pluginName, plugin.model, { signal: options.signal }),
224
+ name: message.name,
225
+ plugin: { name: pluginName },
226
+ cache: createPluginCache(pluginName),
227
+ run: { async load() {
228
+ return await loadPluginRun(sessionParams);
229
+ } },
230
+ state: createPluginState(pluginName)
231
+ };
232
+ }
233
+ function findPluginTask(message) {
234
+ const plugin = [...coreTaskRegistrations(), ...getPlugins()].find((candidate) => candidate.manifest.name === message.plugin);
235
+ if (!plugin?.tasks || !Object.hasOwn(plugin.tasks, message.name)) return;
236
+ return {
237
+ plugin,
238
+ task: plugin.tasks[message.name]
239
+ };
240
+ }
241
+ /** Schedule all plugin tasks interested in a completed agent-run session. */
242
+ async function scheduleSessionCompletedPluginTasks(params, options = {}) {
243
+ const coreParams = pluginTaskParamsSchema.parse(params);
244
+ const taskRegistrations = [...getPlugins(), ...coreTaskRegistrations()].flatMap((plugin) => Object.keys(plugin.tasks ?? {}).map((name) => ({
245
+ name,
246
+ plugin
247
+ })));
248
+ if (taskRegistrations.length === 0) return;
249
+ const record = await getTurnRecord(coreParams.conversationId, coreParams.sessionId);
250
+ if (!record || record.state !== "completed") throw new Error("Completed plugin task session record is not ready");
251
+ const send = options.send ?? sendVercelPluginTask;
252
+ const messages = taskRegistrations.map(({ name, plugin }) => ({
253
+ name,
254
+ params: coreParams,
255
+ plugin: plugin.manifest.name
256
+ }));
257
+ await Promise.all(messages.map(async (message) => {
258
+ await send(message);
259
+ }));
260
+ }
261
+ /** Execute one parsed plugin task request. */
262
+ async function processPluginTask(message, options = {}) {
263
+ await withPluginTaskLock(pluginTaskId(message), async () => {
264
+ const resolved = findPluginTask(message);
265
+ if (!resolved?.task) throw new Error(`Plugin task "${message.plugin}.${message.name}" is not registered`);
266
+ await resolved.task.run(taskPluginContext(resolved.plugin, message, options));
267
+ });
268
+ }
269
+ export { scheduleSessionCompletedPluginTasks as n, task_runner_exports as r, processPluginTask as t };
@@ -1,8 +1,8 @@
1
- import { fr as createDurableLocationConfigurationService, pt as persistConversationMessages } from "./tasks-SB9z-VTU.js";
2
- import { B as isRecord, H as toOptionalString, V as toOptionalNumber } from "./logging-DLSpkSSr.js";
3
- import { m as getDb } from "./viewer-CpXTGlep.js";
4
- import { pn as JUNIOR_THREAD_STATE_TTL_MS } from "./credentialed-lukuD-cc.js";
5
- import { i as getStateAdapter } from "./adapter-04AcD2SO.js";
1
+ import { Gr as createDurableLocationConfigurationService, Kt as persistConversationMessages } from "./turn-session-routing-BqO0qXLk.js";
2
+ import { B as isRecord, H as toOptionalString, V as toOptionalNumber } from "./logging-n7knse-O.js";
3
+ import { S as getDb } from "./viewer-DSbD6DF6.js";
4
+ import { In as JUNIOR_THREAD_STATE_TTL_MS } from "./credentialed-BU-OW7HP.js";
5
+ import { r as getStateAdapter } from "./adapter-2-CG25be.js";
6
6
  // src/chat/state/conversation.ts
7
7
  function defaultConversationState() {
8
8
  return {
@@ -1,13 +1,13 @@
1
- import { Bt as clearPendingAuth, Et as markConversationMessage, ft as hydrateConversationMessages, tr as buildDeterministicTurnId } from "./tasks-SB9z-VTU.js";
2
- import { _ as getProviderErrorAttributes, g as findProviderError, m as ProviderError, v as getProviderErrorUserMessage } from "./client-C1yDYjoS.js";
3
- import { B as isRecord, t as buildTurnFailureResponse } from "./logging-DLSpkSSr.js";
1
+ import { Gt as hydrateConversationMessages, Pr as buildDeterministicTurnId, an as markConversationMessage, yn as clearPendingAuth } from "./turn-session-routing-BqO0qXLk.js";
2
+ import { _ as getProviderErrorAttributes, g as findProviderError, m as ProviderError, v as getProviderErrorUserMessage } from "./client-Cqf4TboL.js";
3
+ import { B as isRecord, t as buildTurnFailureResponse } from "./logging-n7knse-O.js";
4
4
  import { m as parseSlackMessageTs } from "./actor-CP9K2Idu.js";
5
- import { d as getConversationEventStore, m as getDb } from "./viewer-CpXTGlep.js";
6
- import { rr as listConversationAnnotations } from "./credentialed-lukuD-cc.js";
7
- import { B as removedCardSchema, V as resolveMessageCards, z as readMessageCardRefs } from "./conversation-DSo310Ps.js";
8
- import { D as parseAgentInvocationResultMessageId, J as markTurnClosed, Y as markTurnCompleted, c as getAgentInvocation, m as getAgentInvocationTurnId } from "./store-C5PN02QO.js";
9
- import { t as getInterruptionMarker } from "./interruption-marker-CkncDT8d.js";
10
- import { a as persistThreadStateById, o as coerceThreadConversationState, r as getPersistedThreadState } from "./thread-state-BbbPh0Sn.js";
5
+ import { S as getDb, y as getConversationEventStore } from "./viewer-DSbD6DF6.js";
6
+ import { Er as listConversationAnnotations } from "./credentialed-BU-OW7HP.js";
7
+ import { B as removedCardSchema, V as resolveMessageCards, z as readMessageCardRefs } from "./conversation-CTpD_PGk.js";
8
+ import { D as parseAgentInvocationResultMessageId, J as markTurnClosed, Y as markTurnCompleted, c as getAgentInvocation, m as getAgentInvocationTurnId } from "./store-1DVhoKOL.js";
9
+ import { t as getInterruptionMarker } from "./interruption-marker-g6Xup3Fk.js";
10
+ import { a as persistThreadStateById, o as coerceThreadConversationState, r as getPersistedThreadState } from "./thread-state-CHy8LS0C.js";
11
11
  // src/chat/conversations/pending-cards.ts
12
12
  /**
13
13
  * Add the cards that tool results selected since the last visible assistant
@@ -1,4 +1,4 @@
1
- import { d as getConversationEventStore } from "./viewer-CpXTGlep.js";
1
+ import { y as getConversationEventStore } from "./viewer-DSbD6DF6.js";
2
2
  // src/chat/conversations/turn-lifecycle.ts
3
3
  /** Persist correlated turn lifecycle facts with retry-safe terminal exclusion. */
4
4
  var ConversationTurnLifecycleService = class {