@sentry/junior 0.109.0 → 0.111.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 (123) hide show
  1. package/dist/{agent-hooks-FHHVLNPA.js → agent-hooks-QQ2IWKOP.js} +12 -13
  2. package/dist/api/conversations/access.d.ts +9 -0
  3. package/dist/api/conversations/aggregate.d.ts +12 -1
  4. package/dist/api/conversations/archive.d.ts +3 -5
  5. package/dist/api/conversations/detail.d.ts +156 -7
  6. package/dist/api/conversations/events.d.ts +1 -1
  7. package/dist/api/conversations/list.d.ts +57 -6
  8. package/dist/api/conversations/projection.d.ts +6 -7
  9. package/dist/api/conversations/reporting.d.ts +10 -4
  10. package/dist/api/conversations/routes.d.ts +2 -1
  11. package/dist/api/conversations/shared.d.ts +1 -1
  12. package/dist/api/conversations/stats.d.ts +37 -6
  13. package/dist/api/conversations/stats.query.d.ts +1 -1
  14. package/dist/api/conversations/usage.d.ts +9 -0
  15. package/dist/api/http.d.ts +7 -0
  16. package/dist/api/locations/detail.d.ts +102 -6
  17. package/dist/api/locations/list.d.ts +43 -5
  18. package/dist/api/locations/query.d.ts +4 -2
  19. package/dist/api/locations/routes.d.ts +2 -1
  20. package/dist/api/people/list.d.ts +28 -6
  21. package/dist/api/people/list.query.d.ts +1 -1
  22. package/dist/api/people/profile.d.ts +96 -7
  23. package/dist/api/people/profile.query.d.ts +4 -2
  24. package/dist/api/people/routes.d.ts +2 -1
  25. package/dist/api/people/shared.d.ts +1219 -2
  26. package/dist/api/route.d.ts +18 -4
  27. package/dist/api/schema/common.d.ts +6 -0
  28. package/dist/api/{conversations/schema.d.ts → schema/conversation.d.ts} +31 -3
  29. package/dist/api/{locations/schema.d.ts → schema/location.d.ts} +5 -0
  30. package/dist/api/{people/schema.d.ts → schema/person.d.ts} +37 -45
  31. package/dist/api/schema.d.ts +8 -22
  32. package/dist/api/schema.js +10 -2
  33. package/dist/api.d.ts +5 -1
  34. package/dist/api.js +767 -384
  35. package/dist/app.js +591 -447
  36. package/dist/build/virtual-config.d.ts +2 -0
  37. package/dist/catalog-runtime-D22W6QEJ.js +16 -0
  38. package/dist/chat/agent/request.d.ts +3 -6
  39. package/dist/chat/agent/resume.d.ts +11 -12
  40. package/dist/chat/agent/sandbox.d.ts +36 -11
  41. package/dist/chat/agent/tools.d.ts +5 -8
  42. package/dist/chat/config.d.ts +8 -1
  43. package/dist/chat/conversations/history.d.ts +3 -0
  44. package/dist/chat/conversations/sql/privacy.d.ts +3 -15
  45. package/dist/chat/pi/messages.d.ts +2 -2
  46. package/dist/chat/pi/sdk.d.ts +1 -1
  47. package/dist/chat/pi/sql-model-usage.d.ts +4 -1
  48. package/dist/chat/plugins/agent-hooks.d.ts +2 -2
  49. package/dist/chat/runtime/agent-continue-runner.d.ts +7 -3
  50. package/dist/chat/runtime/slack-runtime.d.ts +1 -2
  51. package/dist/chat/runtime/thread-state.d.ts +3 -7
  52. package/dist/chat/runtime/turn-preparation.d.ts +2 -2
  53. package/dist/chat/sandbox/command-result.d.ts +91 -0
  54. package/dist/chat/sandbox/errors.d.ts +3 -1
  55. package/dist/chat/sandbox/ref.d.ts +5 -0
  56. package/dist/chat/sandbox/sandbox.d.ts +19 -46
  57. package/dist/chat/sandbox/session.d.ts +16 -20
  58. package/dist/chat/sandbox/skill-sync.d.ts +2 -2
  59. package/dist/chat/sandbox/workspace.d.ts +14 -12
  60. package/dist/chat/services/auth-pause.d.ts +4 -0
  61. package/dist/chat/services/context-compaction.d.ts +1 -0
  62. package/dist/chat/services/turn-result.d.ts +3 -4
  63. package/dist/chat/task-execution/queue-signing.d.ts +10 -8
  64. package/dist/chat/task-execution/queue.d.ts +9 -7
  65. package/dist/chat/task-execution/slack-work.d.ts +9 -7
  66. package/dist/chat/task-execution/state.d.ts +75 -22
  67. package/dist/chat/task-execution/store.d.ts +34 -3
  68. package/dist/chat/task-execution/worker.d.ts +0 -1
  69. package/dist/chat/tool-support/normalize-result.d.ts +2 -2
  70. package/dist/chat/tool-support/pi-tool-adapter.d.ts +2 -2
  71. package/dist/chat/tool-support/structured-result.d.ts +1 -2
  72. package/dist/chat/tools/sandbox/file-uploads.d.ts +1 -1
  73. package/dist/chat/{runtime → tools/sandbox}/generated-artifacts.d.ts +3 -3
  74. package/dist/chat/tools/types.d.ts +1 -1
  75. package/dist/chat/tools/web/fetch-content.d.ts +5 -0
  76. package/dist/chat/tools/web/image-generate.d.ts +2 -1
  77. package/dist/chat/tools/web/search.d.ts +1 -1
  78. package/dist/{chunk-CEA3A3UA.js → chunk-2ZTTXTSZ.js} +24 -1
  79. package/dist/{chunk-IVVGFRQQ.js → chunk-42WRQLJ6.js} +10 -38
  80. package/dist/{chunk-O3JMSZLI.js → chunk-6Y5L4BOM.js} +3 -5
  81. package/dist/{chunk-HO5NT6OE.js → chunk-B45FPP2A.js} +306 -31
  82. package/dist/{chunk-WHMOBKT7.js → chunk-BTRNMS6A.js} +2 -2
  83. package/dist/{chunk-PLB7MRCQ.js → chunk-C4MZ3GP5.js} +1 -1
  84. package/dist/{chunk-HHVY4SMP.js → chunk-FPK7XY3F.js} +98 -92
  85. package/dist/{chunk-RGX4V75M.js → chunk-IFAHK54X.js} +3 -3
  86. package/dist/{chunk-ISMWX44P.js → chunk-J7APPQIJ.js} +2 -2
  87. package/dist/{chunk-TMBRFULF.js → chunk-JQFJO5WH.js} +7 -1
  88. package/dist/{chunk-FWJRXN4F.js → chunk-L6JPKANW.js} +3 -139
  89. package/dist/{chunk-7Q6WCISF.js → chunk-MIAKQNYX.js} +43 -31
  90. package/dist/chunk-MPVES2IC.js +44 -0
  91. package/dist/{chunk-JNAVF45E.js → chunk-NQLWOTY4.js} +47 -19
  92. package/dist/{chunk-IXKSQGIO.js → chunk-OOLU34J4.js} +8860 -9137
  93. package/dist/{chunk-OUHNWH46.js → chunk-PYKKM4MM.js} +1 -1
  94. package/dist/{chunk-MXW4GL53.js → chunk-PZELBSHC.js} +8 -9
  95. package/dist/{chunk-QY636HZU.js → chunk-QQIVLZW4.js} +96 -17
  96. package/dist/{chunk-72OMGPDS.js → chunk-SL3ZKNLQ.js} +19 -18
  97. package/dist/{chunk-3SXUV423.js → chunk-WSRBFHPX.js} +1 -1
  98. package/dist/{chunk-TT6GMXNA.js → chunk-XQAYFRWT.js} +2 -2
  99. package/dist/{chunk-MGUMR35T.js → chunk-Z2W4SJZ7.js} +1 -1
  100. package/dist/{chunk-OCD3OZRK.js → chunk-Z4G3WCP3.js} +1 -1
  101. package/dist/{chunk-FENLIFJD.js → chunk-ZRZ4SVWG.js} +69 -10
  102. package/dist/cli/chat.js +23 -24
  103. package/dist/cli/check.js +8 -8
  104. package/dist/cli/plugins.js +15 -16
  105. package/dist/cli/snapshot-warmup.js +11 -11
  106. package/dist/cli/upgrade.js +9 -9
  107. package/dist/db/schema/conversations.d.ts +17 -0
  108. package/dist/db/schema.d.ts +17 -0
  109. package/dist/{db-V3NU72O2.js → db-WXQOQESG.js} +8 -9
  110. package/dist/instrumentation.js +4 -4
  111. package/dist/nitro.js +15 -10
  112. package/dist/reporting-schema.d.ts +46 -0
  113. package/dist/{runner-JYBCQBLK.js → runner-4QY4XH4B.js} +23 -33
  114. package/dist/{skills-U6MDAST7.js → skills-P5MU4EBX.js} +8 -8
  115. package/dist/{validation-72N3JVRU.js → validation-PQF5OP6T.js} +8 -8
  116. package/dist/version.js +1 -1
  117. package/migrations/0007_thick_sugar_man.sql +23 -0
  118. package/migrations/meta/0007_snapshot.json +1013 -0
  119. package/migrations/meta/_journal.json +7 -0
  120. package/package.json +6 -6
  121. package/dist/catalog-runtime-DMGJSLV2.js +0 -16
  122. package/dist/chunk-OB42YVAE.js +0 -16
  123. package/dist/chunk-SYAQIR5Z.js +0 -53
@@ -1,8 +1,8 @@
1
1
  import type { FileUpload } from "chat";
2
2
  import { type GeneratedArtifactFileRef } from "@/chat/tools/sandbox/file-uploads";
3
3
  import type { SandboxCommandResult } from "@/chat/sandbox/workspace";
4
- /** Sandbox operations needed to make generated artifacts visible to later tools. */
5
- export interface GeneratedArtifactSandbox {
4
+ /** Workspace operations needed to make generated artifacts visible to later tools. */
5
+ export interface GeneratedArtifactWorkspace {
6
6
  runCommand(input: {
7
7
  args?: string[];
8
8
  cmd: string;
@@ -13,4 +13,4 @@ export interface GeneratedArtifactSandbox {
13
13
  }>): Promise<void>;
14
14
  }
15
15
  /** Persist generated artifacts into the sandbox before returning model-visible handles. */
16
- export declare function writeSandboxGeneratedArtifacts(sandbox: GeneratedArtifactSandbox, files: FileUpload[]): Promise<GeneratedArtifactFileRef[]>;
16
+ export declare function writeSandboxGeneratedArtifacts(workspace: GeneratedArtifactWorkspace, files: FileUpload[]): Promise<GeneratedArtifactFileRef[]>;
@@ -69,7 +69,7 @@ interface BaseToolRuntimeContext {
69
69
  configuration?: Record<string, unknown>;
70
70
  egress: PluginEgress;
71
71
  mcpToolManager?: McpToolManager;
72
- sandbox: SandboxWorkspace;
72
+ workspace: SandboxWorkspace;
73
73
  }
74
74
  interface SlackToolRuntimeContext extends BaseToolRuntimeContext {
75
75
  destination: SlackDestination;
@@ -17,6 +17,11 @@ export type WebFetchResponse = {
17
17
  extracted_chars: number;
18
18
  truncated: boolean;
19
19
  } & Record<string, unknown>;
20
+ /** Apply the web-fetch character limit to already extracted text content. */
21
+ export declare function truncateWebFetchContent(content: string, maxChars: number): {
22
+ content: string;
23
+ truncated: boolean;
24
+ };
20
25
  /** Extract readable content and metadata from a fetched response body. */
21
26
  export declare function extractContentDetails(body: string, contentType: string, maxChars: number): WebFetchResponseContent;
22
27
  /** Extract readable content from a fetched response body, converting HTML to markdown. */
@@ -1,6 +1,7 @@
1
1
  import type { ImageGenerateToolDeps, ToolHooks } from "@/chat/tools/types";
2
2
  /** Create the image tool with sandbox artifact guidance matched to file-send capability. */
3
- export declare function createImageGenerateTool(hooks: Required<Pick<ToolHooks, "writeGeneratedArtifacts">>, options?: {
3
+ export declare function createImageGenerateTool(hooks: Required<Pick<ToolHooks, "writeGeneratedArtifacts">>, options: {
4
+ modelId: string;
4
5
  canSendFilesToActiveConversation?: boolean;
5
6
  }, deps?: ImageGenerateToolDeps): Omit<import("../definition").AnyToolDefinition, "inputSchema" | "outputSchema" | "prepareArguments" | "execute"> & {
6
7
  inputSchema: import("../definition").JsonSchemaObject;
@@ -1,5 +1,5 @@
1
1
  import type { WebSearchToolDeps } from "@/chat/tools/types";
2
- export declare function createWebSearchTool(override?: WebSearchToolDeps): Omit<import("../definition").AnyToolDefinition, "inputSchema" | "outputSchema" | "prepareArguments" | "execute"> & {
2
+ export declare function createWebSearchTool(modelId: string, override?: WebSearchToolDeps): Omit<import("../definition").AnyToolDefinition, "inputSchema" | "outputSchema" | "prepareArguments" | "execute"> & {
3
3
  inputSchema: import("../definition").JsonSchemaObject;
4
4
  outputSchema: import("../definition").JsonSchemaObject;
5
5
  prepareArguments(args: unknown): {
@@ -59,12 +59,35 @@ var pluginOperationalRecordSetSchema = z.object({
59
59
  records: z.array(pluginOperationalRecordSchema).optional(),
60
60
  title: z.string()
61
61
  }).strict();
62
+ var pluginOperationalBarChartWidgetSchema = z.object({
63
+ categories: z.array(
64
+ z.object({
65
+ id: z.string().min(1),
66
+ label: z.string().min(1),
67
+ values: z.record(z.string(), z.number().finite())
68
+ }).strict()
69
+ ).max(100),
70
+ description: z.string().optional(),
71
+ emptyText: z.string().optional(),
72
+ id: z.string().min(1),
73
+ series: z.array(
74
+ z.object({
75
+ key: z.string().min(1),
76
+ label: z.string().min(1),
77
+ tone: pluginOperationalToneSchema.optional()
78
+ }).strict()
79
+ ).min(1).max(8),
80
+ timeRangeDays: z.array(z.union([z.literal(7), z.literal(30), z.literal(90)])).min(1).max(3).optional(),
81
+ title: z.string().min(1),
82
+ type: z.literal("bar_chart")
83
+ }).strict();
62
84
  var pluginOperationalReportSchema = z.object({
63
85
  generatedAt: z.string().optional(),
64
86
  metrics: z.array(pluginOperationalMetricSchema).optional(),
65
87
  recordSets: z.array(pluginOperationalRecordSetSchema).optional(),
66
88
  title: z.string().optional(),
67
- pluginName: z.string()
89
+ pluginName: z.string(),
90
+ widgets: z.array(pluginOperationalBarChartWidgetSchema).max(12).optional()
68
91
  }).strict();
69
92
  var pluginOperationalReportFeedSchema = z.object({
70
93
  generatedAt: z.string(),
@@ -1,34 +1,12 @@
1
- import {
2
- JUNIOR_VERSION
3
- } from "./chunk-OCD3OZRK.js";
4
-
5
- // src/deployment.ts
6
- var JUNIOR_HEARTBEAT_ROUTE = "/api/internal/heartbeat";
7
- var JUNIOR_HEARTBEAT_CRON_SCHEDULE = "* * * * *";
8
- var JUNIOR_RETENTION_ROUTE = "/api/internal/retention";
9
- var JUNIOR_RETENTION_CRON_SCHEDULE = "0 4 * * *";
10
- var JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE = "/api/internal/agent/continue";
11
- var JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE = "/api/internal/plugin/tasks";
12
- var LEGACY_JUNIOR_CONVERSATION_WORK_FUNCTION = "api/internal/agent/continue.ts";
13
- function toOptionalTrimmed(value) {
14
- const trimmed = value?.trim();
15
- return trimmed ? trimmed : void 0;
1
+ // src/chat/coerce.ts
2
+ function toOptionalString(value) {
3
+ return typeof value === "string" && value.trim() ? value : void 0;
16
4
  }
17
- function getDeploymentServiceVersion() {
18
- return toOptionalTrimmed(process.env.SENTRY_RELEASE) ?? toOptionalTrimmed(process.env.VERCEL_GIT_COMMIT_SHA);
5
+ function toOptionalNumber(value) {
6
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
19
7
  }
20
- function getDeploymentTelemetryAttributes() {
21
- const attributes = {};
22
- const serviceVersion = getDeploymentServiceVersion();
23
- const deploymentId = toOptionalTrimmed(process.env.VERCEL_DEPLOYMENT_ID);
24
- attributes["app.junior.version"] = JUNIOR_VERSION;
25
- if (serviceVersion) {
26
- attributes["service.version"] = serviceVersion;
27
- }
28
- if (deploymentId) {
29
- attributes["deployment.id"] = deploymentId;
30
- }
31
- return attributes;
8
+ function isRecord(value) {
9
+ return typeof value === "object" && value !== null;
32
10
  }
33
11
 
34
12
  // src/chat/slack/timestamp.ts
@@ -82,15 +60,9 @@ function parseSlackUserId(value) {
82
60
  }
83
61
 
84
62
  export {
85
- JUNIOR_HEARTBEAT_ROUTE,
86
- JUNIOR_HEARTBEAT_CRON_SCHEDULE,
87
- JUNIOR_RETENTION_ROUTE,
88
- JUNIOR_RETENTION_CRON_SCHEDULE,
89
- JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE,
90
- JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE,
91
- LEGACY_JUNIOR_CONVERSATION_WORK_FUNCTION,
92
- getDeploymentServiceVersion,
93
- getDeploymentTelemetryAttributes,
63
+ toOptionalString,
64
+ toOptionalNumber,
65
+ isRecord,
94
66
  parseSlackMessageTs,
95
67
  parseSlackChannelId,
96
68
  parseSlackChannelReferenceId,
@@ -1,11 +1,9 @@
1
- import {
2
- toOptionalString
3
- } from "./chunk-OB42YVAE.js";
4
1
  import {
5
2
  parseSlackChannelId,
6
3
  parseSlackMessageTs,
7
- parseSlackTeamId
8
- } from "./chunk-IVVGFRQQ.js";
4
+ parseSlackTeamId,
5
+ toOptionalString
6
+ } from "./chunk-42WRQLJ6.js";
9
7
 
10
8
  // src/chat/conversation-privacy.ts
11
9
  import { AsyncLocalStorage } from "async_hooks";
@@ -1,19 +1,21 @@
1
1
  import {
2
2
  SANDBOX_WORKSPACE_ROOT,
3
3
  getStateAdapter
4
- } from "./chunk-OUHNWH46.js";
4
+ } from "./chunk-PYKKM4MM.js";
5
5
  import {
6
6
  sleep
7
7
  } from "./chunk-4ZNGQH7C.js";
8
8
  import {
9
9
  toOptionalTrimmed
10
- } from "./chunk-JNAVF45E.js";
10
+ } from "./chunk-NQLWOTY4.js";
11
11
  import {
12
12
  pluginCatalogRuntime
13
- } from "./chunk-3SXUV423.js";
13
+ } from "./chunk-WSRBFHPX.js";
14
14
  import {
15
+ setSpanAttributes,
16
+ setSpanStatus,
15
17
  withSpan
16
- } from "./chunk-ISMWX44P.js";
18
+ } from "./chunk-J7APPQIJ.js";
17
19
 
18
20
  // src/chat/sandbox/runtime-dependencies.ts
19
21
  var GLOBAL_RUNTIME_DEPENDENCIES = [
@@ -105,37 +107,303 @@ function getVercelSandboxCredentials() {
105
107
  }
106
108
 
107
109
  // src/chat/sandbox/workspace.ts
108
- function createSandboxInstance(sandbox) {
110
+ import {
111
+ FileSystem
112
+ } from "@vercel/sandbox";
113
+
114
+ // src/chat/sandbox/http-error-details.ts
115
+ var DEFAULT_PREVIEW_LIMIT = 512;
116
+ function toTrimmedString(value, maxChars) {
117
+ if (typeof value !== "string") {
118
+ return void 0;
119
+ }
120
+ const normalized = value.trim();
121
+ if (!normalized) {
122
+ return void 0;
123
+ }
124
+ return normalized.length > maxChars ? `${normalized.slice(0, maxChars)}\u2026` : normalized;
125
+ }
126
+ function extractHttpErrorDetails(error, options = {}) {
127
+ const prefix = options.attributePrefix ?? "app.http_error";
128
+ const previewLimit = options.previewLimit ?? DEFAULT_PREVIEW_LIMIT;
129
+ const normalizedError = error instanceof Error ? error : new Error(String(error));
130
+ const err = error ?? {};
131
+ const attributes = {
132
+ "error.type": normalizedError.name || "Error",
133
+ "exception.message": toTrimmedString(normalizedError.message, previewLimit) ?? "HTTP error"
134
+ };
135
+ const response = err.response;
136
+ const statusCode = typeof response?.status === "number" ? response.status : void 0;
137
+ const statusText = toTrimmedString(response?.statusText, previewLimit);
138
+ const responseUrl = toTrimmedString(response?.url, previewLimit);
139
+ const responseText = toTrimmedString(err.text, previewLimit);
140
+ const responseJson = toTrimmedString(
141
+ err.json && typeof err.json === "object" ? JSON.stringify(err.json) : void 0,
142
+ previewLimit
143
+ );
144
+ const contentType = toTrimmedString(
145
+ response?.headers?.get?.("content-type"),
146
+ previewLimit
147
+ );
148
+ const requestIdHeader = toTrimmedString(
149
+ response?.headers?.get?.("x-request-id"),
150
+ previewLimit
151
+ );
152
+ const vercelIdHeader = toTrimmedString(
153
+ response?.headers?.get?.("x-vercel-id"),
154
+ previewLimit
155
+ );
156
+ const requestId = requestIdHeader ?? vercelIdHeader;
157
+ if (statusCode !== void 0) {
158
+ attributes["http.response.status_code"] = statusCode;
159
+ }
160
+ if (statusText) {
161
+ attributes[`${prefix}.status_text`] = statusText;
162
+ }
163
+ if (responseUrl) {
164
+ attributes["url.full"] = responseUrl;
165
+ }
166
+ if (contentType) {
167
+ attributes["http.response.header.content-type"] = [contentType];
168
+ }
169
+ if (requestIdHeader) {
170
+ attributes["http.response.header.x-request-id"] = [requestIdHeader];
171
+ }
172
+ if (vercelIdHeader) {
173
+ attributes["http.response.header.x-vercel-id"] = [vercelIdHeader];
174
+ }
175
+ if (responseText) {
176
+ attributes[`${prefix}.response_text_preview`] = responseText;
177
+ attributes[`${prefix}.response_text_length`] = responseText.length;
178
+ }
179
+ if (responseJson) {
180
+ attributes[`${prefix}.response_json_preview`] = responseJson;
181
+ }
182
+ const summaryParts = [];
183
+ if (statusCode !== void 0) {
184
+ summaryParts.push(`status=${statusCode}`);
185
+ }
186
+ if (statusText) {
187
+ summaryParts.push(`statusText=${statusText}`);
188
+ }
189
+ if (responseUrl) {
190
+ summaryParts.push(`url=${responseUrl}`);
191
+ }
192
+ if (requestId) {
193
+ summaryParts.push(`requestId=${requestId}`);
194
+ }
195
+ for (const field of options.extraFields ?? []) {
196
+ const value = toTrimmedString(err[field.sourceKey], previewLimit);
197
+ if (!value) {
198
+ continue;
199
+ }
200
+ attributes[`${prefix}.${field.attributeKey}`] = value;
201
+ summaryParts.push(`${field.summaryKey ?? field.attributeKey}=${value}`);
202
+ }
203
+ if (responseJson) {
204
+ summaryParts.push(`json=${responseJson}`);
205
+ } else if (responseText) {
206
+ summaryParts.push(`text=${responseText}`);
207
+ }
208
+ const searchableText = `${normalizedError.message} ${responseText ?? ""} ${responseJson ?? ""}`.toLowerCase();
209
+ return {
210
+ attributes,
211
+ summary: summaryParts.join(", "),
212
+ searchableText
213
+ };
214
+ }
215
+
216
+ // src/chat/sandbox/errors.ts
217
+ var SANDBOX_ERROR_FIELDS = [
218
+ {
219
+ sourceKey: "sandboxId",
220
+ attributeKey: "sandbox_id",
221
+ summaryKey: "sandboxId"
222
+ }
223
+ ];
224
+ function getSandboxErrorDetails(error) {
225
+ return extractHttpErrorDetails(error, {
226
+ attributePrefix: "app.sandbox.api_error",
227
+ extraFields: [...SANDBOX_ERROR_FIELDS]
228
+ });
229
+ }
230
+ function findInErrorChain(error, predicate) {
231
+ const seen = /* @__PURE__ */ new Set();
232
+ let current = error;
233
+ while (current && !seen.has(current)) {
234
+ if (predicate(current)) {
235
+ return true;
236
+ }
237
+ seen.add(current);
238
+ current = typeof current === "object" ? current.cause : void 0;
239
+ }
240
+ return false;
241
+ }
242
+ function isRecord(value) {
243
+ return typeof value === "object" && value !== null;
244
+ }
245
+ function isInvalidSandboxSessionError(error) {
246
+ if (!isRecord(error)) {
247
+ return false;
248
+ }
249
+ if (isRecord(error.json) && error.json.invalidToken === true) {
250
+ return true;
251
+ }
252
+ const response = error.response;
253
+ return isRecord(response) && response.status === 403 && typeof response.url === "string" && response.url.includes("/sandboxes/sessions");
254
+ }
255
+ function getFirstErrorMessage(error) {
256
+ const seen = /* @__PURE__ */ new Set();
257
+ let current = error;
258
+ while (current && !seen.has(current)) {
259
+ if (current instanceof Error) {
260
+ const message = current.message.trim();
261
+ if (message) {
262
+ return message;
263
+ }
264
+ }
265
+ seen.add(current);
266
+ current = typeof current === "object" ? current.cause : void 0;
267
+ }
268
+ return void 0;
269
+ }
270
+ function isAlreadyExistsError(error) {
271
+ const details = getSandboxErrorDetails(error);
272
+ return details.searchableText.includes("already exists") || details.searchableText.includes("file exists") || details.searchableText.includes("eexist");
273
+ }
274
+ function isSandboxUnavailableError(error) {
275
+ return findInErrorChain(error, (candidate) => {
276
+ if (isInvalidSandboxSessionError(candidate)) {
277
+ return true;
278
+ }
279
+ const details = getSandboxErrorDetails(candidate);
280
+ const searchable = `${details.searchableText} ${details.summary}`.toLowerCase();
281
+ return searchable.includes("sandbox_stopped") || searchable.includes("status=410") || searchable.includes("status code 410") || searchable.includes("no longer available") || searchable.includes("stream was closed and is not accepting commands");
282
+ });
283
+ }
284
+ function isSandboxMissingError(error) {
285
+ return findInErrorChain(error, (candidate) => {
286
+ const details = getSandboxErrorDetails(candidate);
287
+ const searchable = `${details.searchableText} ${details.summary}`.toLowerCase();
288
+ return searchable.includes("status=404") || searchable.includes("status code 404") || searchable.includes("snapshot_not_found");
289
+ });
290
+ }
291
+ function isSnapshottingError(error) {
292
+ return findInErrorChain(error, (candidate) => {
293
+ const details = getSandboxErrorDetails(candidate);
294
+ const searchable = `${details.searchableText} ${details.summary}`.toLowerCase();
295
+ return searchable.includes("sandbox_snapshotting") || searchable.includes("creating a snapshot") || searchable.includes("stopped shortly");
296
+ });
297
+ }
298
+ function isSandboxCommandStreamInterruptedError(error) {
299
+ return findInErrorChain(error, (candidate) => {
300
+ if (!(candidate instanceof Error)) {
301
+ return false;
302
+ }
303
+ return candidate.name === "StreamError" && candidate.message.toLowerCase().includes("stream ended before command finished");
304
+ });
305
+ }
306
+ function wrapSandboxSetupError(error) {
307
+ try {
308
+ const details = getSandboxErrorDetails(error);
309
+ if (details.summary) {
310
+ return new Error(`sandbox setup failed (${details.summary})`, {
311
+ cause: error
312
+ });
313
+ }
314
+ } catch {
315
+ }
316
+ let causeMessage;
317
+ try {
318
+ causeMessage = getFirstErrorMessage(error);
319
+ } catch (cause) {
320
+ causeMessage = cause instanceof Error ? cause.message : void 0;
321
+ }
322
+ if (causeMessage && causeMessage.trim() && causeMessage !== "sandbox setup failed") {
323
+ const oneLine = causeMessage.replace(/\s+/g, " ").trim();
324
+ return new Error(`sandbox setup failed (${oneLine})`, { cause: error });
325
+ }
326
+ return new Error("sandbox setup failed", { cause: error });
327
+ }
328
+ function throwSandboxOperationError(action, error, includeMissingPath = false) {
329
+ const details = getSandboxErrorDetails(error);
330
+ setSpanAttributes({
331
+ ...details.attributes,
332
+ ...includeMissingPath ? {
333
+ "app.sandbox.api_error.missing_path": details.searchableText.includes("no such file") || details.searchableText.includes("enoent")
334
+ } : {},
335
+ "app.sandbox.success": false
336
+ });
337
+ setSpanStatus("error");
338
+ throw new Error(
339
+ details.summary ? `${action} failed (${details.summary})` : `${action} failed`,
340
+ {
341
+ cause: error
342
+ }
343
+ );
344
+ }
345
+
346
+ // src/chat/sandbox/workspace.ts
347
+ function createSandboxSession(sandbox, options) {
348
+ const session = sandbox.currentSession();
349
+ const fileSystem = new FileSystem(session);
350
+ const run = async (operation) => {
351
+ try {
352
+ return await operation();
353
+ } catch (error) {
354
+ if (isSandboxUnavailableError(error)) {
355
+ options?.onUnavailable?.(session.sessionId);
356
+ }
357
+ throw error;
358
+ }
359
+ };
360
+ const fs = {
361
+ readFile: async (filePath, readOptions) => await run(async () => await fileSystem.readFile(filePath, readOptions)),
362
+ writeFile: async (filePath, content, writeOptions) => await run(
363
+ async () => await fileSystem.writeFile(filePath, content, writeOptions)
364
+ ),
365
+ readdir: async (filePath) => await run(async () => await fileSystem.readdir(filePath)),
366
+ stat: async (filePath) => await run(async () => await fileSystem.stat(filePath))
367
+ };
109
368
  return {
110
369
  sandboxId: sandbox.name,
111
- get sandboxEgressId() {
112
- return sandbox.currentSession().sessionId;
113
- },
114
- fs: sandbox.fs,
370
+ sessionId: session.sessionId,
371
+ fs,
115
372
  extendTimeout(duration) {
116
- return sandbox.extendTimeout(duration);
373
+ return run(async () => await session.extendTimeout(duration));
117
374
  },
118
375
  mkDir(path) {
119
- return sandbox.mkDir(path);
376
+ return run(async () => await session.mkDir(path));
120
377
  },
121
378
  readFileToBuffer(input) {
122
- return sandbox.readFileToBuffer(input);
379
+ return run(async () => await session.readFileToBuffer(input));
123
380
  },
124
- runCommand(input) {
125
- return sandbox.runCommand(input);
381
+ async runCommand(input) {
382
+ const result = await run(async () => await session.runCommand(input));
383
+ const [stdout, stderr] = await Promise.all([
384
+ run(async () => await result.stdout()),
385
+ run(async () => await result.stderr())
386
+ ]);
387
+ return {
388
+ exitCode: result.exitCode,
389
+ stdout,
390
+ stderr
391
+ };
126
392
  },
127
- async snapshot() {
128
- const snapshot = await sandbox.snapshot();
129
- return { snapshotId: snapshot.snapshotId };
393
+ snapshot() {
394
+ return run(async () => {
395
+ const snapshot = await session.snapshot();
396
+ return { snapshotId: snapshot.snapshotId };
397
+ });
130
398
  },
131
399
  stop() {
132
- return sandbox.stop();
400
+ return run(async () => await session.stop());
133
401
  },
134
402
  update(params) {
135
- return sandbox.update(params);
403
+ return run(async () => await session.update(params));
136
404
  },
137
405
  writeFiles(files) {
138
- return sandbox.writeFiles(files);
406
+ return run(async () => await session.writeFiles(files));
139
407
  }
140
408
  };
141
409
  }
@@ -258,8 +526,8 @@ async function runOrThrow(sandbox, params, label) {
258
526
  if (result.exitCode === 0) {
259
527
  return;
260
528
  }
261
- const stderr = (await result.stderr()).trim();
262
- const stdout = (await result.stdout()).trim();
529
+ const stderr = result.stderr.trim();
530
+ const stdout = result.stdout.trim();
263
531
  const detail = stderr || stdout || "command failed";
264
532
  throw new Error(`${label} failed: ${detail}`);
265
533
  }
@@ -268,8 +536,8 @@ async function tryRun(sandbox, params) {
268
536
  if (result.exitCode === 0) {
269
537
  return { ok: true };
270
538
  }
271
- const stderr = (await result.stderr()).trim();
272
- const stdout = (await result.stdout()).trim();
539
+ const stderr = result.stderr.trim();
540
+ const stdout = result.stdout.trim();
273
541
  return { ok: false, detail: stderr || stdout || "command failed" };
274
542
  }
275
543
  async function installGhCliViaDnf(sandbox) {
@@ -368,8 +636,8 @@ async function installRuntimeDependencies(sandbox, deps) {
368
636
  cmd: "sha256sum",
369
637
  args: [rpmPath]
370
638
  });
371
- const checksumStdout = (await checksumResult.stdout()).trim();
372
- const checksumStderr = (await checksumResult.stderr()).trim();
639
+ const checksumStdout = checksumResult.stdout.trim();
640
+ const checksumStderr = checksumResult.stderr.trim();
373
641
  if (checksumResult.exitCode !== 0) {
374
642
  throw new Error(
375
643
  `sha256sum failed: ${checksumStderr || checksumStdout || "command failed"}`
@@ -460,8 +728,8 @@ async function runRuntimePostinstall(sandbox, commands) {
460
728
  if (result.exitCode === 0) {
461
729
  continue;
462
730
  }
463
- const stderr = (await result.stderr()).trim();
464
- const stdout = (await result.stdout()).trim();
731
+ const stderr = result.stderr.trim();
732
+ const stdout = result.stdout.trim();
465
733
  const detail = stderr || stdout || "command failed";
466
734
  throw new Error(`runtime-postinstall ${command.cmd} failed: ${detail}`);
467
735
  }
@@ -479,7 +747,7 @@ async function createDependencySnapshot(profile, runtime, timeoutMs) {
479
747
  async () => {
480
748
  const sandboxCredentials = getVercelSandboxCredentials();
481
749
  const resources = getSandboxResources();
482
- const sandbox = createSandboxInstance(
750
+ const sandbox = createSandboxSession(
483
751
  await Sandbox.create({
484
752
  timeout: timeoutMs,
485
753
  runtime,
@@ -697,12 +965,19 @@ function isSnapshotMissingError(error) {
697
965
  }
698
966
 
699
967
  export {
968
+ isAlreadyExistsError,
969
+ isSandboxUnavailableError,
970
+ isSandboxMissingError,
971
+ isSnapshottingError,
972
+ isSandboxCommandStreamInterruptedError,
973
+ wrapSandboxSetupError,
974
+ throwSandboxOperationError,
975
+ getVercelSandboxCredentials,
700
976
  buildNonInteractiveShellScript,
701
977
  runNonInteractiveCommand,
702
- getVercelSandboxCredentials,
703
978
  getSandboxResources,
704
979
  GLOBAL_RUNTIME_DEPENDENCIES,
705
- createSandboxInstance,
980
+ createSandboxSession,
706
981
  getRuntimeDependencyProfileHash,
707
982
  resolveRuntimeDependencySnapshot,
708
983
  isSnapshotMissingError
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-3SXUV423.js";
3
+ } from "./chunk-WSRBFHPX.js";
4
4
  import {
5
5
  logWarn
6
- } from "./chunk-ISMWX44P.js";
6
+ } from "./chunk-J7APPQIJ.js";
7
7
  import {
8
8
  skillRoots
9
9
  } from "./chunk-3V7OFJZC.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseSlackTeamId
3
- } from "./chunk-IVVGFRQQ.js";
3
+ } from "./chunk-42WRQLJ6.js";
4
4
 
5
5
  // src/chat/actor.ts
6
6
  import { z } from "zod";