@sentry/junior 0.179.0 → 0.181.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 (137) hide show
  1. package/dist/{agent-hooks-32IDCLMW.js → agent-hooks-IQUW6ERD.js} +16 -18
  2. package/dist/api/schema/workspace.d.ts +2 -0
  3. package/dist/api/schema.js +1 -2
  4. package/dist/api.js +202 -199
  5. package/dist/app.d.ts +4 -0
  6. package/dist/app.js +300 -1259
  7. package/dist/catalog-runtime-PMQWNIXA.js +14 -0
  8. package/dist/chat/agent/sandbox.d.ts +0 -2
  9. package/dist/chat/api-turns/routing.d.ts +4 -0
  10. package/dist/chat/api-turns/work.d.ts +5 -0
  11. package/dist/chat/config.d.ts +5 -2
  12. package/dist/chat/configuration/defaults.d.ts +1 -1
  13. package/dist/chat/conversations/projection.d.ts +6 -4
  14. package/dist/chat/ingress/message-router.d.ts +3 -0
  15. package/dist/chat/model-profile.d.ts +8 -10
  16. package/dist/chat/pi/conversation-events.d.ts +3 -2
  17. package/dist/chat/plugins/agent-hooks.d.ts +1 -1
  18. package/dist/chat/plugins/task-queue.d.ts +40 -3
  19. package/dist/chat/plugins/task-runner.d.ts +1 -1
  20. package/dist/chat/queue/callback.d.ts +26 -0
  21. package/dist/chat/queue/sign.d.ts +30 -0
  22. package/dist/chat/sandbox/sandbox.d.ts +0 -2
  23. package/dist/chat/sandbox/session.d.ts +0 -2
  24. package/dist/chat/sandbox/skill-sync.d.ts +1 -1
  25. package/dist/chat/sandbox/snapshot/events.d.ts +23 -0
  26. package/dist/chat/sandbox/snapshot/job-callback.d.ts +5 -0
  27. package/dist/chat/sandbox/snapshot/job-queue.d.ts +26 -0
  28. package/dist/chat/sandbox/snapshot/job-runner.d.ts +11 -0
  29. package/dist/chat/sandbox/snapshot/not-ready-error.d.ts +6 -0
  30. package/dist/chat/sandbox/snapshot/workspace.d.ts +9 -3
  31. package/dist/chat/services/turn-router.d.ts +4 -3
  32. package/dist/chat/services/turn-session-routing.d.ts +1 -0
  33. package/dist/chat/task-execution/queue-signing.d.ts +10 -21
  34. package/dist/chat/task-execution/state.d.ts +48 -0
  35. package/dist/chat/task-execution/store.d.ts +28 -2
  36. package/dist/chat/task-execution/worker.d.ts +4 -1
  37. package/dist/chat/tools/handoff/tool.d.ts +1 -1
  38. package/dist/chat/tools/types.d.ts +2 -0
  39. package/dist/chat/workspaces/types.d.ts +2 -0
  40. package/dist/{chunk-Q5B3WTGG.js → chunk-3KCQEG6W.js} +42 -41
  41. package/dist/{chunk-XZY6G5YZ.js → chunk-3KSSALN4.js} +180 -87
  42. package/dist/{chunk-3AFVR5UC.js → chunk-3X55QRAG.js} +18 -16
  43. package/dist/{chunk-SLGGOASN.js → chunk-4IX32NSL.js} +46 -46
  44. package/dist/{chunk-6ZWRNC4D.js → chunk-6Y5B5PEX.js} +1 -1
  45. package/dist/chunk-7H2VZTWN.js +103 -0
  46. package/dist/{chunk-CGA4ERJ5.js → chunk-CEMMLV5L.js} +1 -1
  47. package/dist/{chunk-FIANEE7Z.js → chunk-CM5HNV2W.js} +6 -6
  48. package/dist/{chunk-TKB25A3L.js → chunk-CZYNWPWD.js} +2 -1
  49. package/dist/{chunk-3I7XE3PA.js → chunk-D6ZD7VXP.js} +49 -38
  50. package/dist/chunk-DKIJ2RP5.js +68 -0
  51. package/dist/{chunk-G2CAC4CV.js → chunk-DSA6WTRP.js} +74 -68
  52. package/dist/{chunk-OOUNJNMR.js → chunk-DWPN6SCH.js} +1 -1
  53. package/dist/{chunk-HQNE5APD.js → chunk-EBMRB6Z6.js} +100 -79
  54. package/dist/{chunk-ZQMG3CL5.js → chunk-EM7EECT5.js} +16 -16
  55. package/dist/{chunk-XSPSCWLH.js → chunk-ETJTXYHY.js} +4 -4
  56. package/dist/{chunk-FTGD2FBP.js → chunk-EU7KJDOG.js} +2 -2
  57. package/dist/{chunk-CJLBLELR.js → chunk-FWILPBVQ.js} +8 -61
  58. package/dist/{chunk-4GWXAILB.js → chunk-GPA3ZSYY.js} +1 -1
  59. package/dist/{chunk-U4TKB6F6.js → chunk-GREV5PJK.js} +108 -5
  60. package/dist/{chunk-KJLHIHFF.js → chunk-GWFRPQNP.js} +43 -230
  61. package/dist/{chunk-YFNAMRGE.js → chunk-HEBMSITT.js} +1 -1
  62. package/dist/chunk-HJ27A6YB.js +218 -0
  63. package/dist/{chunk-R5NWWYIS.js → chunk-HZHUMCNV.js} +5 -5
  64. package/dist/{chunk-RTRBYSF3.js → chunk-IJ6SS4WB.js} +1 -1
  65. package/dist/{chunk-B6ECUSVX.js → chunk-IKKETMQC.js} +8 -8
  66. package/dist/{chunk-R6U7N4FS.js → chunk-KKSVCHDO.js} +10 -3
  67. package/dist/{chunk-JMJNFEDC.js → chunk-KMBU4PJP.js} +9 -54
  68. package/dist/chunk-KQZX24QQ.js +164 -0
  69. package/dist/{chunk-GPLAT6H7.js → chunk-LCNPXLE7.js} +22 -18
  70. package/dist/{chunk-2HIPYNQI.js → chunk-LG5MYY6U.js} +33 -32
  71. package/dist/chunk-LZOQFC5F.js +209 -0
  72. package/dist/chunk-M3QYTBQ6.js +55 -0
  73. package/dist/{chunk-M63DETLL.js → chunk-N7TMSOZH.js} +6 -6
  74. package/dist/{chunk-FIDMHAO6.js → chunk-NQTA72Q3.js} +84 -274
  75. package/dist/{chunk-RZRYOLCE.js → chunk-PBKZQAUA.js} +2315 -1150
  76. package/dist/chunk-PEQXYSSE.js +45 -0
  77. package/dist/{chunk-3TM3FYLQ.js → chunk-PL57B6NC.js} +1 -1
  78. package/dist/{chunk-JT4WMD3C.js → chunk-PPYDHUEL.js} +144 -218
  79. package/dist/{chunk-5IRROPA5.js → chunk-Q2KY27IX.js} +129 -31
  80. package/dist/{chunk-VP4OVRDD.js → chunk-RNMASWLP.js} +69 -73
  81. package/dist/{chunk-FAS6AIMF.js → chunk-TDT2R77B.js} +8 -8
  82. package/dist/{chunk-TIEKUH4Q.js → chunk-TJHSAHQN.js} +4 -3
  83. package/dist/{chunk-H4HBKISO.js → chunk-TXKUKMVO.js} +1 -1
  84. package/dist/chunk-X6GDDWQH.js +60 -0
  85. package/dist/{chunk-GENV6KF2.js → chunk-XYTJUHRZ.js} +108 -76
  86. package/dist/cli/chat.js +47 -43
  87. package/dist/cli/check.js +13 -15
  88. package/dist/cli/env.js +0 -1
  89. package/dist/cli/init.js +0 -1
  90. package/dist/cli/main.js +2 -3
  91. package/dist/cli/plugins.js +18 -20
  92. package/dist/cli/run.js +0 -1
  93. package/dist/cli/snapshot-create.js +14 -16
  94. package/dist/cli/upgrade.js +16 -18
  95. package/dist/{conversation-work-KATFHLG3.js → conversation-work-VIOQ5ZF3.js} +0 -2
  96. package/dist/db/schema/snapshots.d.ts +17 -0
  97. package/dist/db/schema.d.ts +17 -0
  98. package/dist/{db-EJAV7JL6.js → db-QNPVCQPT.js} +8 -10
  99. package/dist/deployment.d.ts +1 -0
  100. package/dist/{discovery-GUFTFBTL.js → discovery-DWVDM7UK.js} +1 -2
  101. package/dist/{experimental-XVDOSRBS.js → experimental-SIJSRDJD.js} +0 -1
  102. package/dist/instrumentation.js +7 -9
  103. package/dist/nitro.js +39 -13
  104. package/dist/{oauth-callback-server-GAVSUBTQ.js → oauth-callback-server-KYMPJOTC.js} +34 -32
  105. package/dist/{oauth-relay-3ZU72UGL.js → oauth-relay-5XPVRPYB.js} +0 -1
  106. package/dist/{plugins-HW4VWW6G.js → plugins-YTYJMMJF.js} +1 -2
  107. package/dist/{runner-34JL64JF.js → runner-3RS2D2ZR.js} +39 -33
  108. package/dist/{sandbox-egress-signals-DXOOBSBI.js → sandbox-egress-signals-FIL7EGPR.js} +5 -6
  109. package/dist/{sentry-JMWTS32N.js → sentry-MB3NL3IR.js} +1 -2
  110. package/dist/skills-5B3Y6XX6.js +27 -0
  111. package/dist/spawn-VYARS3DU.js +37 -0
  112. package/dist/task-runner-4IXKKZHL.js +32 -0
  113. package/dist/validation-Q65QD27B.js +17 -0
  114. package/dist/vercel.js +0 -1
  115. package/dist/version.js +1 -2
  116. package/dist/work-DCMQWAAP.js +45 -0
  117. package/dist/worker-QL3CHLZL.js +22 -0
  118. package/migrations/0035_workspace_snapshot_size_bytes.sql +2 -0
  119. package/migrations/meta/0035_snapshot.json +3048 -0
  120. package/migrations/meta/_journal.json +7 -0
  121. package/package.json +7 -6
  122. package/dist/catalog-runtime-FBVA6WAQ.js +0 -16
  123. package/dist/chat/plugins/task-callback.d.ts +0 -5
  124. package/dist/chat/plugins/task-message.d.ts +0 -23
  125. package/dist/chat/plugins/task-signing.d.ts +0 -31
  126. package/dist/chat/sandbox/snapshot/waiting-error.d.ts +0 -15
  127. package/dist/chat/services/workspace-snapshot-wait.d.ts +0 -27
  128. package/dist/chunk-5I6ORJUY.js +0 -127
  129. package/dist/chunk-6GWA276C.js +0 -72
  130. package/dist/chunk-MLKGABMK.js +0 -9
  131. package/dist/chunk-UT6X7XN7.js +0 -51
  132. package/dist/chunk-WR76IVA5.js +0 -130
  133. package/dist/skills-U545HALM.js +0 -29
  134. package/dist/spawn-I2S4IDUQ.js +0 -37
  135. package/dist/validation-EVXVGA44.js +0 -19
  136. package/dist/work-QOAUPDBU.js +0 -45
  137. package/dist/worker-5GX2IKLZ.js +0 -24
@@ -0,0 +1,218 @@
1
+ import {
2
+ abandonTurnRecord,
3
+ extractAssistantText
4
+ } from "./chunk-NQTA72Q3.js";
5
+
6
+ // src/chat/state/turn-id.ts
7
+ function buildDeterministicTurnId(messageId) {
8
+ const sanitized = messageId.replace(/[^a-zA-Z0-9_-]/g, "_");
9
+ return `turn_${sanitized}`;
10
+ }
11
+ function buildDeterministicAssistantMessageId(turnId) {
12
+ return `${turnId}:assistant:1`;
13
+ }
14
+
15
+ // src/chat/runtime/turn.ts
16
+ var ConversationTurnBoundaryError = class extends Error {
17
+ eventId;
18
+ failureCode;
19
+ constructor(args) {
20
+ super(
21
+ args.cause instanceof Error ? args.cause.message : String(args.cause),
22
+ {
23
+ cause: args.cause
24
+ }
25
+ );
26
+ this.name = "ConversationTurnBoundaryError";
27
+ this.eventId = args.eventId;
28
+ this.failureCode = args.failureCode;
29
+ }
30
+ };
31
+ function getConversationTurnBoundaryError(error) {
32
+ return error instanceof ConversationTurnBoundaryError ? error : void 0;
33
+ }
34
+ var CooperativeTurnYieldError = class extends Error {
35
+ code = "cooperative_turn_yield";
36
+ constructor(message = "Agent turn yielded at a safe boundary") {
37
+ super(message);
38
+ this.name = "CooperativeTurnYieldError";
39
+ }
40
+ };
41
+ function isCooperativeTurnYieldError(error) {
42
+ return error instanceof CooperativeTurnYieldError;
43
+ }
44
+ var TurnInputCommitLostError = class extends Error {
45
+ code = "turn_input_commit_lost";
46
+ constructor(message = "Turn input commit lost its durable owner") {
47
+ super(message);
48
+ this.name = "TurnInputCommitLostError";
49
+ }
50
+ };
51
+ function isTurnInputCommitLostError(error) {
52
+ return error instanceof TurnInputCommitLostError;
53
+ }
54
+ var TurnInputDeferredError = class extends Error {
55
+ code = "turn_input_deferred";
56
+ constructor(message = "Turn input is deferred until the active resume ends") {
57
+ super(message);
58
+ this.name = "TurnInputDeferredError";
59
+ }
60
+ };
61
+ function isTurnInputDeferredError(error) {
62
+ return error instanceof TurnInputDeferredError;
63
+ }
64
+ function startActiveTurn(args) {
65
+ args.conversation.processing.activeTurnId = args.nextTurnId;
66
+ }
67
+ function clearActiveTurn(conversation, sessionId) {
68
+ if (!sessionId || conversation.processing.activeTurnId === sessionId) {
69
+ conversation.processing.activeTurnId = void 0;
70
+ }
71
+ }
72
+ function markTurnClosed(args) {
73
+ clearActiveTurn(args.conversation, args.sessionId);
74
+ args.conversation.processing.lastCompletedAtMs = args.nowMs;
75
+ }
76
+ function markTurnCompleted(args) {
77
+ clearActiveTurn(args.conversation, args.sessionId);
78
+ args.conversation.processing.lastCompletedAtMs = args.nowMs;
79
+ }
80
+ function markTurnFailed(args) {
81
+ clearActiveTurn(args.conversation, args.sessionId);
82
+ args.conversation.processing.lastCompletedAtMs = args.nowMs;
83
+ args.markConversationMessage(args.conversation, args.userMessageId, {
84
+ replied: false,
85
+ skippedReason: "reply failed"
86
+ });
87
+ }
88
+
89
+ // src/chat/no-reply.ts
90
+ var NO_REPLY_MARKER = "[[NO_REPLY]]";
91
+ function isNoReplyMarker(text) {
92
+ return text.trim() === NO_REPLY_MARKER;
93
+ }
94
+ function containsNoReplyMarker(text) {
95
+ return text.includes(NO_REPLY_MARKER);
96
+ }
97
+
98
+ // src/chat/services/assistant-reply.ts
99
+ var THINKING_XML_BLOCK_PATTERN = /[ \t]*<thinking\b[^>]*>[\s\S]*?<\/thinking>[ \t]*(?:\r?\n)?/gi;
100
+ var FENCED_CODE_BLOCK_PATTERN = /```[\s\S]*?```/g;
101
+ function sanitizeAssistantText(text) {
102
+ let result = "";
103
+ let cursor = 0;
104
+ for (const match of text.matchAll(FENCED_CODE_BLOCK_PATTERN)) {
105
+ const start = match.index;
106
+ if (start === void 0) continue;
107
+ result += text.slice(cursor, start).replace(THINKING_XML_BLOCK_PATTERN, "");
108
+ result += match[0];
109
+ cursor = start + match[0].length;
110
+ }
111
+ return (result + text.slice(cursor).replace(THINKING_XML_BLOCK_PATTERN, "")).trim();
112
+ }
113
+ function decideReply(message) {
114
+ if (message.content.some((part) => part.type === "toolCall")) {
115
+ return { kind: "suppress" };
116
+ }
117
+ const text = sanitizeAssistantText(extractAssistantText(message));
118
+ if (!text) return { kind: "empty" };
119
+ if (isNoReplyMarker(text) || containsNoReplyMarker(text)) {
120
+ return { kind: "suppress" };
121
+ }
122
+ return { kind: "deliver", text };
123
+ }
124
+ function getAssistantReplyText(message) {
125
+ const decision = decideReply(message);
126
+ return decision.kind === "deliver" ? decision.text : void 0;
127
+ }
128
+
129
+ // src/chat/services/pending-auth.ts
130
+ var AUTH_LINK_REUSE_WINDOW_MS = 10 * 60 * 1e3;
131
+ var NON_REQUEST_SKIPPED_REASON_PREFIXES = [
132
+ "directed_to_other_party:",
133
+ "side_conversation:"
134
+ ];
135
+ function isSkippedNonRequest(reason) {
136
+ return NON_REQUEST_SKIPPED_REASON_PREFIXES.some(
137
+ (prefix) => reason?.startsWith(prefix)
138
+ );
139
+ }
140
+ function canReusePendingAuthLink(args) {
141
+ const { pendingAuth } = args;
142
+ if (!pendingAuth) {
143
+ return false;
144
+ }
145
+ return pendingAuth.kind === args.kind && pendingAuth.provider === args.provider && pendingAuth.actorId === args.actorId && pendingAuth.scope === args.scope && pendingAuth.sessionId === args.sessionId && pendingAuth.linkSentAtMs + AUTH_LINK_REUSE_WINDOW_MS > (args.nowMs ?? Date.now());
146
+ }
147
+ function getConversationPendingAuth(args) {
148
+ const pendingAuth = args.conversation.processing.pendingAuth;
149
+ if (!pendingAuth) {
150
+ return void 0;
151
+ }
152
+ if (pendingAuth.kind !== args.kind || pendingAuth.provider !== args.provider || pendingAuth.actorId !== args.actorId || pendingAuth.scope !== args.scope) {
153
+ return void 0;
154
+ }
155
+ return pendingAuth;
156
+ }
157
+ function clearPendingAuth(conversation, sessionId) {
158
+ if (!conversation.processing.pendingAuth) {
159
+ return;
160
+ }
161
+ if (sessionId && conversation.processing.pendingAuth.sessionId !== sessionId) {
162
+ return;
163
+ }
164
+ conversation.processing.pendingAuth = void 0;
165
+ }
166
+ async function abandonReplacedPendingAuth(args) {
167
+ if (args.previousPendingAuth && args.previousPendingAuth.sessionId !== args.nextPendingAuth.sessionId && args.conversationId) {
168
+ await abandonTurnRecord({
169
+ conversationId: args.conversationId,
170
+ turnId: args.previousPendingAuth.sessionId,
171
+ errorMessage: "Abandoned by a newer auth-blocked request in the same conversation."
172
+ });
173
+ }
174
+ }
175
+ function isPendingAuthLatestRequest(conversation, pendingAuth) {
176
+ for (let index = conversation.messages.length - 1; index >= 0; index -= 1) {
177
+ const message = conversation.messages[index];
178
+ if (message?.role !== "user") {
179
+ continue;
180
+ }
181
+ if (message.author?.isBot) {
182
+ continue;
183
+ }
184
+ if (isSkippedNonRequest(message.meta?.skippedReason)) {
185
+ continue;
186
+ }
187
+ return buildDeterministicTurnId(message.id) === pendingAuth.sessionId;
188
+ }
189
+ return false;
190
+ }
191
+
192
+ export {
193
+ buildDeterministicTurnId,
194
+ buildDeterministicAssistantMessageId,
195
+ ConversationTurnBoundaryError,
196
+ getConversationTurnBoundaryError,
197
+ CooperativeTurnYieldError,
198
+ isCooperativeTurnYieldError,
199
+ TurnInputCommitLostError,
200
+ isTurnInputCommitLostError,
201
+ TurnInputDeferredError,
202
+ isTurnInputDeferredError,
203
+ startActiveTurn,
204
+ markTurnClosed,
205
+ markTurnCompleted,
206
+ markTurnFailed,
207
+ NO_REPLY_MARKER,
208
+ isNoReplyMarker,
209
+ containsNoReplyMarker,
210
+ sanitizeAssistantText,
211
+ decideReply,
212
+ getAssistantReplyText,
213
+ canReusePendingAuthLink,
214
+ getConversationPendingAuth,
215
+ clearPendingAuth,
216
+ abandonReplacedPendingAuth,
217
+ isPendingAuthLatestRequest
218
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createAndEnqueueAgentInvocation
3
- } from "./chunk-GPLAT6H7.js";
3
+ } from "./chunk-LCNPXLE7.js";
4
4
  import {
5
5
  actorFromRun,
6
6
  toolInvocationDestination
@@ -18,16 +18,16 @@ function bindSpawnAgent(run, options) {
18
18
  const invocation = await createAndEnqueueAgentInvocation(
19
19
  {
20
20
  actor,
21
- ...input.name ? { agentName: input.name } : {},
22
- ...run.credentialContext ? { credentialContext: run.credentialContext } : {},
21
+ ...input.name ? { agentName: input.name } : void 0,
22
+ ...run.credentialContext ? { credentialContext: run.credentialContext } : void 0,
23
23
  destination: toolInvocationDestination(run),
24
24
  ...run.destinationVisibility ? {
25
25
  destinationVisibility: run.destinationVisibility
26
- } : {},
26
+ } : void 0,
27
27
  idempotencyKey: `${run.turnId}:${call.toolCallId}`,
28
28
  input: input.task,
29
29
  parentConversationId: run.conversationId,
30
- ...input.reasoningLevel ? { reasoningLevel: input.reasoningLevel } : {},
30
+ ...input.reasoningLevel ? { reasoningLevel: input.reasoningLevel } : void 0,
31
31
  source: run.source
32
32
  },
33
33
  { ...options, queue }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-YFNAMRGE.js";
3
+ } from "./chunk-HEBMSITT.js";
4
4
 
5
5
  // src/chat/plugins/validation.ts
6
6
  import { isDeepStrictEqual } from "util";
@@ -6,14 +6,14 @@ import {
6
6
  isStale,
7
7
  runNonInteractiveCommand,
8
8
  sleep
9
- } from "./chunk-JMJNFEDC.js";
9
+ } from "./chunk-KMBU4PJP.js";
10
10
  import {
11
11
  getStateAdapter
12
- } from "./chunk-3TM3FYLQ.js";
12
+ } from "./chunk-PL57B6NC.js";
13
13
  import {
14
14
  setSpanAttributes,
15
15
  withSpan
16
- } from "./chunk-HQNE5APD.js";
16
+ } from "./chunk-EBMRB6Z6.js";
17
17
 
18
18
  // src/chat/sandbox/resources.ts
19
19
  var configuredResources;
@@ -57,9 +57,9 @@ function setSnapshotSpanAttributes(snapshot) {
57
57
  "app.sandbox.source": snapshot.snapshotId ? "snapshot" : "created",
58
58
  "app.sandbox.snapshot.cache_hit": snapshot.cacheHit,
59
59
  "app.sandbox.snapshot.resolve_outcome": snapshot.resolveOutcome,
60
- ...snapshot.profileHash ? { "app.sandbox.snapshot.profile_hash": snapshot.profileHash } : {},
60
+ ...snapshot.profileHash ? { "app.sandbox.snapshot.profile_hash": snapshot.profileHash } : void 0,
61
61
  "app.sandbox.snapshot.dependency_count": snapshot.dependencyCount,
62
- ...snapshot.rebuildReason ? { "app.sandbox.snapshot.rebuild_reason": snapshot.rebuildReason } : {}
62
+ ...snapshot.rebuildReason ? { "app.sandbox.snapshot.rebuild_reason": snapshot.rebuildReason } : void 0
63
63
  });
64
64
  }
65
65
  async function trace(name, op, attributes, callback) {
@@ -283,7 +283,7 @@ async function postinstall(sandbox, commands, signal, timeoutMs) {
283
283
  pathPrefix: `${SANDBOX_WORKSPACE_ROOT}/.junior/bin:$PATH`,
284
284
  signal,
285
285
  timeoutMs,
286
- ...command.sudo !== void 0 ? { sudo: command.sudo } : {}
286
+ ...command.sudo !== void 0 ? { sudo: command.sudo } : void 0
287
287
  });
288
288
  if (result.exitCode !== 0) {
289
289
  const detail = result.stderr.trim() || result.stdout.trim() || "command failed";
@@ -460,7 +460,7 @@ async function build(value, runtime, timeoutMs, signal, prepare) {
460
460
  runtime,
461
461
  signal,
462
462
  ...sandboxCredentials ?? {},
463
- ...resources ? { resources } : {}
463
+ ...resources ? { resources } : void 0
464
464
  })
465
465
  );
466
466
  try {
@@ -680,7 +680,7 @@ async function resolve(params) {
680
680
  ),
681
681
  createdAtMs: lockResult.createdAtMs,
682
682
  buildDurationMs: lockResult.buildDurationMs,
683
- ...rebuildReason ? { rebuildReason } : {}
683
+ ...rebuildReason ? { rebuildReason } : void 0
684
684
  };
685
685
  }
686
686
  );
@@ -1,10 +1,10 @@
1
- import {
2
- DEFAULT_SQL_STATEMENT_TIMEOUT_MS
3
- } from "./chunk-GENV6KF2.js";
4
1
  import {
5
2
  juniorDestinations,
6
3
  timestamptz
7
4
  } from "./chunk-VFUK3X5B.js";
5
+ import {
6
+ DEFAULT_SQL_STATEMENT_TIMEOUT_MS
7
+ } from "./chunk-XYTJUHRZ.js";
8
8
 
9
9
  // src/db/neon.ts
10
10
  import { AsyncLocalStorage } from "async_hooks";
@@ -655,6 +655,7 @@ var juniorSchedulerRuns = pgTable16(
655
655
  // src/db/schema/snapshots.ts
656
656
  import { sql as sql6 } from "drizzle-orm";
657
657
  import {
658
+ bigint as bigint4,
658
659
  check as check2,
659
660
  index as index13,
660
661
  integer as integer6,
@@ -699,6 +700,8 @@ var juniorSnapshots = pgTable18(
699
700
  // Ready artifact facts.
700
701
  snapshotId: text18("snapshot_id"),
701
702
  buildDurationMs: integer6("build_duration_ms"),
703
+ // Provider snapshot size when the capture response includes it.
704
+ sizeBytes: bigint4("size_bytes", { mode: "number" }),
702
705
  generatedAt: timestamptz("generated_at"),
703
706
  // Builder references for check-in and snapshot-owner cleanup.
704
707
  buildStartedAt: timestamptz("build_started_at"),
@@ -730,6 +733,10 @@ var juniorSnapshots = pgTable18(
730
733
  "junior_snapshots_build_duration_check",
731
734
  sql6`${table.buildDurationMs} is null or ${table.buildDurationMs} >= 0`
732
735
  ),
736
+ check2(
737
+ "junior_snapshots_size_bytes_check",
738
+ sql6`${table.sizeBytes} is null or ${table.sizeBytes} >= 0`
739
+ ),
733
740
  // Provider snapshot ids are unique. Nulls stay allowed for in-flight rows.
734
741
  uniqueIndex8("junior_snapshots_snapshot_id_uidx").on(table.snapshotId),
735
742
  index13("junior_snapshots_workspace_idx").on(table.workspaceId),
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  toOptionalTrimmed
3
- } from "./chunk-GENV6KF2.js";
3
+ } from "./chunk-XYTJUHRZ.js";
4
4
  import {
5
5
  pluginCatalogRuntime
6
- } from "./chunk-YFNAMRGE.js";
6
+ } from "./chunk-HEBMSITT.js";
7
7
  import {
8
8
  setSpanAttributes,
9
9
  setSpanStatus
10
- } from "./chunk-HQNE5APD.js";
10
+ } from "./chunk-EBMRB6Z6.js";
11
11
 
12
12
  // src/chat/sandbox/paths.ts
13
13
  function normalizeWorkspaceRoot(input) {
@@ -98,10 +98,10 @@ function buildNonInteractiveCommand(input) {
98
98
  async function runNonInteractiveCommand(sandbox, input) {
99
99
  const command = {
100
100
  ...buildNonInteractiveCommand(input),
101
- ...input.cwd ? { cwd: input.cwd } : {},
102
- ...input.signal ? { signal: input.signal } : {},
103
- ...input.sudo !== void 0 ? { sudo: input.sudo } : {},
104
- ...input.timeoutMs !== void 0 ? { timeoutMs: input.timeoutMs } : {}
101
+ ...input.cwd ? { cwd: input.cwd } : void 0,
102
+ ...input.signal ? { signal: input.signal } : void 0,
103
+ ...input.sudo !== void 0 ? { sudo: input.sudo } : void 0,
104
+ ...input.timeoutMs !== void 0 ? { timeoutMs: input.timeoutMs } : void 0
105
105
  };
106
106
  return await sandbox.runCommand(command);
107
107
  }
@@ -344,7 +344,7 @@ function create(runtime, workspace) {
344
344
  rebuildEpoch,
345
345
  dependencies,
346
346
  postinstall,
347
- ...workspace ? { workspace: workspaceRecipe(workspace) } : {}
347
+ ...workspace ? { workspace: workspaceRecipe(workspace) } : void 0
348
348
  })
349
349
  ).digest("hex");
350
350
  return {
@@ -399,44 +399,6 @@ function getVercelSandboxCredentials() {
399
399
  return void 0;
400
400
  }
401
401
 
402
- // src/chat/sandbox/snapshot/waiting-error.ts
403
- var WorkspaceSnapshotWaitingError = class extends Error {
404
- code = "workspace_snapshot_waiting";
405
- workspaceName;
406
- constructor(workspaceName) {
407
- super(
408
- `Workspace ${workspaceName} snapshot is still building; yielded for requeue`
409
- );
410
- this.name = "WorkspaceSnapshotWaitingError";
411
- this.workspaceName = workspaceName;
412
- }
413
- };
414
- function isWorkspaceSnapshotWaitingResult(details) {
415
- if (!details || typeof details !== "object" || Array.isArray(details)) {
416
- return false;
417
- }
418
- const record = details;
419
- return record.timed_out === true && record.waiting === "workspace_snapshot" && typeof record.workspace?.name === "string" && record.workspace.name.length > 0;
420
- }
421
- function workspaceNameFromWaitingResult(details) {
422
- if (!isWorkspaceSnapshotWaitingResult(details)) return void 0;
423
- const name = details.workspace?.name;
424
- return typeof name === "string" ? name : void 0;
425
- }
426
- function isWorkspaceSnapshotWaitingError(error) {
427
- const seen = /* @__PURE__ */ new Set();
428
- let current = error;
429
- while (current && !seen.has(current)) {
430
- if (current instanceof WorkspaceSnapshotWaitingError) return true;
431
- if (current instanceof Error && (current.name === "WorkspaceSnapshotWaitingError" || current.code === "workspace_snapshot_waiting")) {
432
- return true;
433
- }
434
- seen.add(current);
435
- current = typeof current === "object" ? current.cause : void 0;
436
- }
437
- return false;
438
- }
439
-
440
402
  // src/chat/sandbox/http-error-details.ts
441
403
  var DEFAULT_PREVIEW_LIMIT = 512;
442
404
  function toTrimmedString(value, maxChars) {
@@ -653,9 +615,6 @@ function isSandboxCommandStreamInterruptedError(error) {
653
615
  });
654
616
  }
655
617
  function wrapSandboxSetupError(error) {
656
- if (isWorkspaceSnapshotWaitingError(error)) {
657
- return error instanceof Error ? error : new Error(String(error));
658
- }
659
618
  try {
660
619
  const details = getSandboxErrorDetails(error);
661
620
  if (details.summary) {
@@ -683,7 +642,7 @@ function throwSandboxOperationError(action, error, includeMissingPath = false) {
683
642
  ...details.attributes,
684
643
  ...includeMissingPath ? {
685
644
  "app.sandbox.api_error.missing_path": details.searchableText.includes("no such file") || details.searchableText.includes("enoent")
686
- } : {},
645
+ } : void 0,
687
646
  "app.sandbox.success": false
688
647
  });
689
648
  setSpanStatus("error");
@@ -703,10 +662,6 @@ export {
703
662
  sandboxSkillDir,
704
663
  sandboxSkillFile,
705
664
  sandboxSkillPathResolution,
706
- WorkspaceSnapshotWaitingError,
707
- isWorkspaceSnapshotWaitingResult,
708
- workspaceNameFromWaitingResult,
709
- isWorkspaceSnapshotWaitingError,
710
665
  sleep,
711
666
  buildCommandScript,
712
667
  buildNonInteractiveShellScript,
@@ -0,0 +1,164 @@
1
+ import {
2
+ QUEUE_SIGNATURE_MAX_AGE_MS,
3
+ createVercelQueueClient,
4
+ signQueueMessage,
5
+ verifyQueueMessage
6
+ } from "./chunk-7H2VZTWN.js";
7
+ import {
8
+ runWithTurnRequestDeadline
9
+ } from "./chunk-GPA3ZSYY.js";
10
+ import {
11
+ logWarn
12
+ } from "./chunk-EBMRB6Z6.js";
13
+
14
+ // src/chat/plugins/task-queue.ts
15
+ import { createHash } from "crypto";
16
+ import { z } from "zod";
17
+
18
+ // src/chat/queue/callback.ts
19
+ import {
20
+ handleCallback,
21
+ registerDevConsumer
22
+ } from "@vercel/queue";
23
+ function queueCallback(options) {
24
+ const handler = async (value, metadata) => {
25
+ if (options.skip?.(metadata)) {
26
+ return;
27
+ }
28
+ const checked = options.verify(value);
29
+ if (checked.status === "rejected") {
30
+ options.onRejected(checked.reason, metadata);
31
+ return;
32
+ }
33
+ if (checked.status === "unavailable") {
34
+ throw new Error(
35
+ `Queue message verification unavailable: ${checked.reason}`
36
+ );
37
+ }
38
+ try {
39
+ await runWithTurnRequestDeadline(
40
+ () => options.run(checked.message, metadata)
41
+ );
42
+ } catch (error) {
43
+ const reason = options.permanentError?.(error);
44
+ if (!reason) {
45
+ throw error;
46
+ }
47
+ options.onRejected(reason, metadata, error);
48
+ }
49
+ };
50
+ const retry = (error, metadata) => {
51
+ const reason = options.permanentError?.(error);
52
+ if (reason) {
53
+ options.onRejected(reason, metadata, error);
54
+ return { acknowledge: true };
55
+ }
56
+ if (options.maxDeliveries !== null && metadata.deliveryCount >= options.maxDeliveries) {
57
+ return { acknowledge: true };
58
+ }
59
+ return void 0;
60
+ };
61
+ const visibility = options.visibilityTimeoutSeconds === void 0 ? {} : { visibilityTimeoutSeconds: options.visibilityTimeoutSeconds };
62
+ return {
63
+ create: () => handleCallback(handler, { retry, ...visibility }),
64
+ registerDev: () => {
65
+ if (process.env.NODE_ENV !== "development") {
66
+ return void 0;
67
+ }
68
+ return registerDevConsumer({
69
+ client: createVercelQueueClient(),
70
+ consumerGroup: options.consumerGroup,
71
+ handler,
72
+ retry,
73
+ topic: options.topic,
74
+ ...visibility
75
+ });
76
+ }
77
+ };
78
+ }
79
+
80
+ // src/chat/plugins/task-queue.ts
81
+ var PLUGIN_TASK_QUEUE_TOPIC = "junior_plugin_tasks";
82
+ var PLUGIN_TASK_DEV_CONSUMER_GROUP = "junior_plugin_tasks_dev";
83
+ var PLUGIN_TASK_MAX_DELIVERIES = 5;
84
+ var PLUGIN_TASK_SIGN_CONTEXT = "junior.plugin_task_queue.v1";
85
+ var PLUGIN_TASK_SIGN_VERSION = "v1";
86
+ var pluginTaskParamsSchema = z.object({
87
+ conversationId: z.string().min(1),
88
+ sessionId: z.string().min(1)
89
+ }).strict();
90
+ var pluginTaskQueueMessageSchema = z.object({
91
+ name: z.string().min(1),
92
+ params: pluginTaskParamsSchema,
93
+ plugin: z.string().min(1)
94
+ }).strict();
95
+ var pluginTaskSign = {
96
+ context: PLUGIN_TASK_SIGN_CONTEXT,
97
+ schema: pluginTaskQueueMessageSchema,
98
+ signatureVersion: PLUGIN_TASK_SIGN_VERSION,
99
+ parts: (message) => [
100
+ message.plugin,
101
+ message.name,
102
+ message.params.conversationId,
103
+ message.params.sessionId
104
+ ]
105
+ };
106
+ function pluginTaskId(args) {
107
+ const digest = createHash("sha256").update(args.plugin).update("\0").update(args.name).update("\0").update(args.params.conversationId).update("\0").update(args.params.sessionId).digest("hex").slice(0, 32);
108
+ return `plugin-task_${digest}`;
109
+ }
110
+ function signPluginTaskQueueMessage(message, nowMs = Date.now()) {
111
+ return signQueueMessage(pluginTaskSign, message, nowMs);
112
+ }
113
+ function verifyPluginTaskQueueMessage(value, nowMs = Date.now()) {
114
+ return verifyQueueMessage(pluginTaskSign, value, nowMs);
115
+ }
116
+ function logPluginTaskQueueMessageRejected(reason, metadata) {
117
+ logWarn("plugin.task.queue_message.rejected", {
118
+ "app.queue.consumer_group": metadata.consumerGroup,
119
+ "app.queue.delivery_count": metadata.deliveryCount,
120
+ "app.queue.message_id": metadata.messageId,
121
+ "app.queue.reject_reason": reason,
122
+ "app.queue.topic_name": metadata.topicName
123
+ });
124
+ }
125
+ function pluginTaskCallback() {
126
+ return queueCallback({
127
+ consumerGroup: PLUGIN_TASK_DEV_CONSUMER_GROUP,
128
+ maxDeliveries: PLUGIN_TASK_MAX_DELIVERIES,
129
+ onRejected: logPluginTaskQueueMessageRejected,
130
+ // Load the runner on first use so this module can send without a cycle.
131
+ run: async (message) => {
132
+ const { processPluginTask } = await import("./task-runner-4IXKKZHL.js");
133
+ await processPluginTask(message);
134
+ },
135
+ topic: PLUGIN_TASK_QUEUE_TOPIC,
136
+ verify: verifyPluginTaskQueueMessage
137
+ });
138
+ }
139
+ async function sendVercelPluginTask(message) {
140
+ await createVercelQueueClient().send(
141
+ PLUGIN_TASK_QUEUE_TOPIC,
142
+ signPluginTaskQueueMessage(message),
143
+ {
144
+ idempotencyKey: pluginTaskId(message),
145
+ retentionSeconds: QUEUE_SIGNATURE_MAX_AGE_MS / 1e3
146
+ }
147
+ );
148
+ }
149
+ function createVercelPluginTaskCallback() {
150
+ return pluginTaskCallback().create();
151
+ }
152
+ function registerVercelPluginTaskDevConsumer() {
153
+ return pluginTaskCallback().registerDev();
154
+ }
155
+
156
+ export {
157
+ queueCallback,
158
+ PLUGIN_TASK_QUEUE_TOPIC,
159
+ pluginTaskParamsSchema,
160
+ pluginTaskId,
161
+ sendVercelPluginTask,
162
+ createVercelPluginTaskCallback,
163
+ registerVercelPluginTaskDevConsumer
164
+ };