@sentry/junior 0.200.0 → 0.202.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.
- package/dist/{agent-hooks-6LGY2MBH.js → agent-hooks-UXITLYOK.js} +11 -11
- package/dist/api.js +25 -25
- package/dist/app.js +228 -122
- package/dist/{catalog-runtime-CIO3ERVQ.js → catalog-runtime-BG3JLLK2.js} +4 -4
- package/dist/{chunk-PMSENMWY.js → chunk-2MK3QBGA.js} +1 -1
- package/dist/{chunk-EOOWKTQC.js → chunk-3PGQSKJV.js} +9 -9
- package/dist/{chunk-ZPLAAHVP.js → chunk-3UI3WFTX.js} +5 -5
- package/dist/{chunk-SY2RQ77O.js → chunk-5NOPO64K.js} +1 -1
- package/dist/{chunk-JLUCKXGI.js → chunk-5PKWYPFT.js} +6 -6
- package/dist/{chunk-GFXDMDHR.js → chunk-63NKKFJL.js} +2 -2
- package/dist/{chunk-M7BHRB3G.js → chunk-6AYH6252.js} +4 -4
- package/dist/{chunk-RDWWCDA4.js → chunk-7DHZP5KJ.js} +2 -2
- package/dist/{chunk-RG74Q34N.js → chunk-A76OIMYN.js} +1 -1
- package/dist/{chunk-YVP6QNBZ.js → chunk-AWMS3SPP.js} +3 -3
- package/dist/{chunk-ODSGDVHT.js → chunk-B3LY5RCL.js} +5 -5
- package/dist/{chunk-4Q5IR5GA.js → chunk-BD2KT3OB.js} +1 -1
- package/dist/{chunk-5Q6KP6LH.js → chunk-BXCX5QKA.js} +1 -1
- package/dist/{chunk-TF5TXGRD.js → chunk-C6VVF43U.js} +1 -1
- package/dist/{chunk-5JDNDQHL.js → chunk-DBVY6HLX.js} +1 -1
- package/dist/{chunk-PIHLVU7T.js → chunk-DL2KLKVH.js} +6 -6
- package/dist/{chunk-3WUBDFFL.js → chunk-ELWOYVOY.js} +1 -1
- package/dist/{chunk-PSQ4SWI3.js → chunk-EWT7H65X.js} +4 -4
- package/dist/{chunk-OTTKTTVI.js → chunk-HMREVIO2.js} +2 -2
- package/dist/{chunk-LUITHZZL.js → chunk-IIWUT4FO.js} +8 -8
- package/dist/{chunk-V2VL335Y.js → chunk-JSJQEWBJ.js} +21 -21
- package/dist/{chunk-T6263C3N.js → chunk-KHKKHDLD.js} +2 -2
- package/dist/{chunk-OIILBD56.js → chunk-LA6R4A7Q.js} +3 -3
- package/dist/{chunk-X2Q4H6JQ.js → chunk-LOOU2DUR.js} +315 -166
- package/dist/{chunk-ADNSL3MX.js → chunk-M6FHWXE3.js} +9 -9
- package/dist/{chunk-JMRHEW6B.js → chunk-M76HMB7M.js} +3 -3
- package/dist/{chunk-7DO36XLF.js → chunk-MAGNK5J4.js} +1 -1
- package/dist/{chunk-OVHO76WN.js → chunk-NSXKRGRT.js} +3 -3
- package/dist/{chunk-UR43NMUR.js → chunk-OWMPFXJA.js} +4 -4
- package/dist/{chunk-K2QYWZ7F.js → chunk-PW4P4JYF.js} +14 -3
- package/dist/{chunk-VLBLCJXK.js → chunk-QB54UQUS.js} +5 -5
- package/dist/{chunk-752M26LC.js → chunk-QP3OGJXF.js} +1 -1
- package/dist/{chunk-LICM66W2.js → chunk-REOIRYPR.js} +2 -2
- package/dist/{chunk-AV552V2K.js → chunk-SCOZRLZ4.js} +3 -3
- package/dist/{chunk-IAZBUDVU.js → chunk-TXJSXBV5.js} +36 -30
- package/dist/{chunk-N5VHBUXF.js → chunk-U2GPUYAL.js} +19 -6
- package/dist/{chunk-22Y5SBDM.js → chunk-WQSHDTTI.js} +8 -8
- package/dist/{chunk-5VRPXF4T.js → chunk-YDUR3ZYW.js} +1 -1
- package/dist/cli/chat.js +33 -33
- package/dist/cli/check.js +5 -5
- package/dist/cli/plugins.js +12 -12
- package/dist/cli/snapshot-create.js +9 -9
- package/dist/cli/upgrade.js +6 -6
- package/dist/{db-SCTYCGQ5.js → db-3L2MCVRI.js} +6 -6
- package/dist/instrumentation.js +3 -3
- package/dist/nitro.js +6 -6
- package/dist/{oauth-callback-server-QXKBXP5M.js → oauth-callback-server-YVV6C6T2.js} +29 -29
- package/dist/{runner-Z3EQSZ23.js → runner-LQ7RETDP.js} +21 -21
- package/dist/{skills-CGEPG74A.js → skills-XRWYEDCD.js} +5 -5
- package/dist/spawn-RC6SJUAI.js +42 -0
- package/dist/task-runner-7DY7ARYH.js +36 -0
- package/dist/{validation-YLALMVMB.js → validation-7MNQGCJA.js} +5 -5
- package/dist/version.js +1 -1
- package/dist/{work-N6PUG4MY.js → work-COALHUCG.js} +21 -21
- package/dist/{worker-M7464FAO.js → worker-6MURZIPD.js} +10 -10
- package/migrations/0039_attachment_provider.sql +7 -0
- package/migrations/meta/0039_snapshot.json +3368 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +6 -6
- package/dist/spawn-WBEM46BW.js +0 -42
- package/dist/task-runner-2X5MUSHN.js +0 -36
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
PluginCredentialFailureError,
|
|
8
8
|
agentNameSchema,
|
|
9
9
|
createPluginAuthOrchestration
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-QB54UQUS.js";
|
|
11
11
|
import {
|
|
12
12
|
parseSandboxEgressAuthRequiredSignal,
|
|
13
13
|
parseSandboxEgressPermissionDeniedSignal,
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
searchSlackUsers,
|
|
39
39
|
selectPluginGrant,
|
|
40
40
|
toMcpProviderError
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-WQSHDTTI.js";
|
|
42
42
|
import {
|
|
43
43
|
RetryableDeliveryError,
|
|
44
44
|
actorFromRun,
|
|
@@ -53,7 +53,7 @@ import {
|
|
|
53
53
|
surfaceFromRun,
|
|
54
54
|
toolInvocationDestination,
|
|
55
55
|
uploadFilesToConversation
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-DL2KLKVH.js";
|
|
57
57
|
import {
|
|
58
58
|
CooperativeTurnYieldError,
|
|
59
59
|
NO_REPLY_MARKER,
|
|
@@ -65,7 +65,7 @@ import {
|
|
|
65
65
|
isNoReplyMarker,
|
|
66
66
|
isTurnInputCommitLostError,
|
|
67
67
|
sanitizeAssistantText
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-ELWOYVOY.js";
|
|
69
69
|
import {
|
|
70
70
|
AGENTS_REMOVAL_NOTICE,
|
|
71
71
|
AGENTS_REPLACEMENT_NOTICE,
|
|
@@ -121,7 +121,7 @@ import {
|
|
|
121
121
|
stripRuntimeTurnContext,
|
|
122
122
|
trimTrailingAssistantMessages,
|
|
123
123
|
truncateText
|
|
124
|
-
} from "./chunk-
|
|
124
|
+
} from "./chunk-5PKWYPFT.js";
|
|
125
125
|
import {
|
|
126
126
|
SCHEDULED_TASK_SYSTEM_ACTOR,
|
|
127
127
|
WORKSPACE_SNAPSHOT_FAILED_EVENT,
|
|
@@ -147,6 +147,7 @@ import {
|
|
|
147
147
|
makeStructuredToolOutput,
|
|
148
148
|
normalizeEventIdentifier,
|
|
149
149
|
pluginSupportsEvent,
|
|
150
|
+
readLiveAttachment,
|
|
150
151
|
readScheduledTask,
|
|
151
152
|
registeredEventTaskTriggerSchema,
|
|
152
153
|
registeredEventTypeSchema,
|
|
@@ -162,13 +163,13 @@ import {
|
|
|
162
163
|
workspaceSnapshotFinishedEvent,
|
|
163
164
|
workspaceSnapshotWatch,
|
|
164
165
|
writableEventTask
|
|
165
|
-
} from "./chunk-
|
|
166
|
+
} from "./chunk-TXJSXBV5.js";
|
|
166
167
|
import {
|
|
167
168
|
parseSlackThreadId
|
|
168
|
-
} from "./chunk-
|
|
169
|
+
} from "./chunk-A76OIMYN.js";
|
|
169
170
|
import {
|
|
170
171
|
appendAndEnqueueInboundMessage
|
|
171
|
-
} from "./chunk-
|
|
172
|
+
} from "./chunk-OWMPFXJA.js";
|
|
172
173
|
import {
|
|
173
174
|
SHORT_TITLE_MAX_LENGTH,
|
|
174
175
|
ToolInputError,
|
|
@@ -176,7 +177,7 @@ import {
|
|
|
176
177
|
generateShortTitle,
|
|
177
178
|
hasAgentTurnUsage,
|
|
178
179
|
resolveTaskTitle
|
|
179
|
-
} from "./chunk-
|
|
180
|
+
} from "./chunk-7DHZP5KJ.js";
|
|
180
181
|
import {
|
|
181
182
|
bindSandboxFileSystem,
|
|
182
183
|
createSandboxSession,
|
|
@@ -187,7 +188,7 @@ import {
|
|
|
187
188
|
resolve,
|
|
188
189
|
setSnapshotSpanAttributes,
|
|
189
190
|
stopSession
|
|
190
|
-
} from "./chunk-
|
|
191
|
+
} from "./chunk-LA6R4A7Q.js";
|
|
191
192
|
import {
|
|
192
193
|
privateTraceResultAttributes
|
|
193
194
|
} from "./chunk-UIE3R5XU.js";
|
|
@@ -197,7 +198,7 @@ import {
|
|
|
197
198
|
} from "./chunk-X6GDDWQH.js";
|
|
198
199
|
import {
|
|
199
200
|
getTurnRequestDeadline
|
|
200
|
-
} from "./chunk-
|
|
201
|
+
} from "./chunk-BD2KT3OB.js";
|
|
201
202
|
import {
|
|
202
203
|
getVercelConversationWorkQueue
|
|
203
204
|
} from "./chunk-DKIJ2RP5.js";
|
|
@@ -244,7 +245,7 @@ import {
|
|
|
244
245
|
updateWorkspace,
|
|
245
246
|
withSlackRetries,
|
|
246
247
|
workspaceRepoCheckoutPath
|
|
247
|
-
} from "./chunk-
|
|
248
|
+
} from "./chunk-U2GPUYAL.js";
|
|
248
249
|
import {
|
|
249
250
|
JUNIOR_THREAD_STATE_TTL_MS
|
|
250
251
|
} from "./chunk-3Y47VMHV.js";
|
|
@@ -254,12 +255,13 @@ import {
|
|
|
254
255
|
getConversationStore,
|
|
255
256
|
getDb,
|
|
256
257
|
getSqlExecutor
|
|
257
|
-
} from "./chunk-
|
|
258
|
+
} from "./chunk-M76HMB7M.js";
|
|
258
259
|
import {
|
|
259
260
|
juniorArtifacts,
|
|
261
|
+
juniorAttachments,
|
|
260
262
|
juniorIdentities,
|
|
261
263
|
juniorSchedulerRuns
|
|
262
|
-
} from "./chunk-
|
|
264
|
+
} from "./chunk-PW4P4JYF.js";
|
|
263
265
|
import {
|
|
264
266
|
SANDBOX_DATA_ROOT,
|
|
265
267
|
SANDBOX_REPOS_ROOT,
|
|
@@ -290,12 +292,12 @@ import {
|
|
|
290
292
|
throwSandboxOperationError,
|
|
291
293
|
workspaceSnapshotNotReadyUserMessage,
|
|
292
294
|
wrapSandboxSetupError
|
|
293
|
-
} from "./chunk-
|
|
295
|
+
} from "./chunk-NSXKRGRT.js";
|
|
294
296
|
import {
|
|
295
297
|
fenceLock,
|
|
296
298
|
getStateAdapter,
|
|
297
299
|
withLock
|
|
298
|
-
} from "./chunk-
|
|
300
|
+
} from "./chunk-2MK3QBGA.js";
|
|
299
301
|
import {
|
|
300
302
|
KNOWN_CONVERSATION_EVENT_TYPES,
|
|
301
303
|
contextProvenance,
|
|
@@ -328,7 +330,7 @@ import {
|
|
|
328
330
|
resolveGatewayCredential,
|
|
329
331
|
resolveGatewayModel,
|
|
330
332
|
unwrapCurrentInstruction
|
|
331
|
-
} from "./chunk-
|
|
333
|
+
} from "./chunk-63NKKFJL.js";
|
|
332
334
|
import {
|
|
333
335
|
ModelProfileNotConfiguredError,
|
|
334
336
|
TURN_REASONING_LEVELS,
|
|
@@ -347,16 +349,16 @@ import {
|
|
|
347
349
|
toGenAiMessagesTraceAttributes,
|
|
348
350
|
toGenAiPayloadMetadata,
|
|
349
351
|
toGenAiPayloadTraceAttributes
|
|
350
|
-
} from "./chunk-
|
|
352
|
+
} from "./chunk-5NOPO64K.js";
|
|
351
353
|
import {
|
|
352
354
|
discoverSkills,
|
|
353
355
|
findSkillByName,
|
|
354
356
|
loadSkillsByName,
|
|
355
357
|
parseSkillInvocation
|
|
356
|
-
} from "./chunk-
|
|
358
|
+
} from "./chunk-KHKKHDLD.js";
|
|
357
359
|
import {
|
|
358
360
|
pluginCatalogRuntime
|
|
359
|
-
} from "./chunk-
|
|
361
|
+
} from "./chunk-YDUR3ZYW.js";
|
|
360
362
|
import {
|
|
361
363
|
CredentialUnavailableError,
|
|
362
364
|
OAuthProviderError,
|
|
@@ -364,7 +366,7 @@ import {
|
|
|
364
366
|
getOAuthProviderErrorAttributes,
|
|
365
367
|
resolveAuthTokenPlaceholder,
|
|
366
368
|
resolvePluginCommandEnv
|
|
367
|
-
} from "./chunk-
|
|
369
|
+
} from "./chunk-BXCX5QKA.js";
|
|
368
370
|
import {
|
|
369
371
|
credentialContextForActor,
|
|
370
372
|
credentialUserSubjectId
|
|
@@ -400,7 +402,7 @@ import {
|
|
|
400
402
|
summarizeMessageText,
|
|
401
403
|
withLogContext,
|
|
402
404
|
withSpan
|
|
403
|
-
} from "./chunk-
|
|
405
|
+
} from "./chunk-MAGNK5J4.js";
|
|
404
406
|
import {
|
|
405
407
|
startInactiveSpan,
|
|
406
408
|
withActiveSpan
|
|
@@ -2052,6 +2054,18 @@ function buildTurnContextPrompt(params) {
|
|
|
2052
2054
|
return sections.join("\n\n");
|
|
2053
2055
|
}
|
|
2054
2056
|
|
|
2057
|
+
// src/chat/attachments/media.ts
|
|
2058
|
+
var VISION_IMAGE_MEDIA_TYPES = /* @__PURE__ */ new Set([
|
|
2059
|
+
"image/gif",
|
|
2060
|
+
"image/jpeg",
|
|
2061
|
+
"image/png",
|
|
2062
|
+
"image/webp"
|
|
2063
|
+
]);
|
|
2064
|
+
function isVisionImageMediaType(mediaType) {
|
|
2065
|
+
const normalized = mediaType.split(";", 1)[0]?.trim().toLowerCase();
|
|
2066
|
+
return normalized ? VISION_IMAGE_MEDIA_TYPES.has(normalized) : false;
|
|
2067
|
+
}
|
|
2068
|
+
|
|
2055
2069
|
// src/chat/agent/prompt.ts
|
|
2056
2070
|
var MAX_INLINE_ATTACHMENT_BASE64_CHARS = 12e4;
|
|
2057
2071
|
var MAX_ROUTER_ATTACHMENT_PREVIEW_CHARS = 2e3;
|
|
@@ -2178,7 +2192,7 @@ function buildUserTurnInput(args) {
|
|
|
2178
2192
|
});
|
|
2179
2193
|
continue;
|
|
2180
2194
|
}
|
|
2181
|
-
if (attachment.mediaType
|
|
2195
|
+
if (isVisionImageMediaType(attachment.mediaType)) {
|
|
2182
2196
|
if (!attachment.data) {
|
|
2183
2197
|
throw new Error("Image attachment is missing image data");
|
|
2184
2198
|
}
|
|
@@ -2966,8 +2980,8 @@ function sandboxProxyUrl(credentialToken) {
|
|
|
2966
2980
|
"Cannot determine base URL for sandbox credential egress (set JUNIOR_BASE_URL or deploy to Vercel)"
|
|
2967
2981
|
);
|
|
2968
2982
|
}
|
|
2969
|
-
const
|
|
2970
|
-
return new URL(
|
|
2983
|
+
const path9 = credentialToken ? `${SANDBOX_EGRESS_PROXY_PATH}/${credentialToken}` : SANDBOX_EGRESS_PROXY_PATH;
|
|
2984
|
+
return new URL(path9, baseUrl).toString();
|
|
2971
2985
|
}
|
|
2972
2986
|
function buildSandboxEgressNetworkPolicy(input) {
|
|
2973
2987
|
const allow = {
|
|
@@ -5291,8 +5305,8 @@ function parseToolContent(content) {
|
|
|
5291
5305
|
}
|
|
5292
5306
|
return content;
|
|
5293
5307
|
}
|
|
5294
|
-
function formatZodPath(
|
|
5295
|
-
return
|
|
5308
|
+
function formatZodPath(path9) {
|
|
5309
|
+
return path9.length > 0 ? path9.map(String).join(".") : "root";
|
|
5296
5310
|
}
|
|
5297
5311
|
function formatToolInputError(error) {
|
|
5298
5312
|
const details = error.issues.slice(0, 5).map((issue) => `${formatZodPath(issue.path)}: ${issue.message}`).join("; ");
|
|
@@ -6193,8 +6207,8 @@ function sliceFileContent(params) {
|
|
|
6193
6207
|
} : void 0
|
|
6194
6208
|
});
|
|
6195
6209
|
}
|
|
6196
|
-
function missingFileResult(
|
|
6197
|
-
throw new ToolInputError(`File not found: ${
|
|
6210
|
+
function missingFileResult(path9) {
|
|
6211
|
+
throw new ToolInputError(`File not found: ${path9}`);
|
|
6198
6212
|
}
|
|
6199
6213
|
|
|
6200
6214
|
// src/chat/tools/sandbox/read-file.ts
|
|
@@ -6845,9 +6859,9 @@ var MIME_BY_EXTENSION = {
|
|
|
6845
6859
|
".log": "text/plain"
|
|
6846
6860
|
};
|
|
6847
6861
|
var SandboxFileNotFoundError = class extends ToolInputError {
|
|
6848
|
-
constructor(
|
|
6849
|
-
super(`failed to read file: ${
|
|
6850
|
-
this.path =
|
|
6862
|
+
constructor(path9) {
|
|
6863
|
+
super(`failed to read file: ${path9}`);
|
|
6864
|
+
this.path = path9;
|
|
6851
6865
|
}
|
|
6852
6866
|
path;
|
|
6853
6867
|
};
|
|
@@ -8688,13 +8702,13 @@ function createViewImageTool(sandbox, supportsImageInput, deps = {}) {
|
|
|
8688
8702
|
description: "View an image file from the sandbox workspace when visual inspection is needed. Supports PNG, JPEG, GIF, and WebP images up to 5 MB.",
|
|
8689
8703
|
exposure: "direct",
|
|
8690
8704
|
inputSchema: viewImageInputSchema,
|
|
8691
|
-
async execute({ path:
|
|
8705
|
+
async execute({ path: path9 }) {
|
|
8692
8706
|
if (!supportsImageInput()) {
|
|
8693
8707
|
throw new ToolInputError(
|
|
8694
8708
|
"viewImage is unavailable because the current model does not support image inputs"
|
|
8695
8709
|
);
|
|
8696
8710
|
}
|
|
8697
|
-
const targetPath = normalizeSandboxPath(
|
|
8711
|
+
const targetPath = normalizeSandboxPath(path9);
|
|
8698
8712
|
const data = deps.readFile ? await deps.readFile(targetPath) : await sandbox.readFileToBuffer({ path: targetPath });
|
|
8699
8713
|
if (!data) {
|
|
8700
8714
|
throw new SandboxFileNotFoundError(targetPath);
|
|
@@ -13113,9 +13127,45 @@ function renderAttachmentText(input) {
|
|
|
13113
13127
|
return rendered.slice(0, MAX_ATTACHMENT_TEXT_CHARS);
|
|
13114
13128
|
}
|
|
13115
13129
|
|
|
13130
|
+
// src/chat/slack/attachments.ts
|
|
13131
|
+
import { and as and2, eq as eq2, inArray as inArray2, isNull } from "drizzle-orm";
|
|
13132
|
+
async function recordSlackAttachment(args) {
|
|
13133
|
+
await args.db.db().update(juniorAttachments).set({ visionSummary: args.visionSummary }).where(
|
|
13134
|
+
and2(
|
|
13135
|
+
eq2(juniorAttachments.id, args.attachmentId),
|
|
13136
|
+
eq2(juniorAttachments.conversationId, args.conversationId),
|
|
13137
|
+
isNull(juniorAttachments.deleteRequestedAt)
|
|
13138
|
+
)
|
|
13139
|
+
);
|
|
13140
|
+
}
|
|
13141
|
+
async function readAttachmentVisionSummary(args) {
|
|
13142
|
+
const [row] = await args.db.db().select({ visionSummary: juniorAttachments.visionSummary }).from(juniorAttachments).where(
|
|
13143
|
+
and2(
|
|
13144
|
+
eq2(juniorAttachments.id, args.attachmentId),
|
|
13145
|
+
eq2(juniorAttachments.conversationId, args.conversationId),
|
|
13146
|
+
isNull(juniorAttachments.deleteRequestedAt)
|
|
13147
|
+
)
|
|
13148
|
+
);
|
|
13149
|
+
return row?.visionSummary;
|
|
13150
|
+
}
|
|
13151
|
+
async function matchSlackAttachments(args) {
|
|
13152
|
+
if (args.providerIds.length === 0) return [];
|
|
13153
|
+
return await args.db.db().select({
|
|
13154
|
+
id: juniorAttachments.id,
|
|
13155
|
+
providerId: juniorAttachments.providerId
|
|
13156
|
+
}).from(juniorAttachments).where(
|
|
13157
|
+
and2(
|
|
13158
|
+
eq2(juniorAttachments.conversationId, args.conversationId),
|
|
13159
|
+
eq2(juniorAttachments.provider, "slack"),
|
|
13160
|
+
inArray2(juniorAttachments.providerId, args.providerIds),
|
|
13161
|
+
isNull(juniorAttachments.deleteRequestedAt)
|
|
13162
|
+
)
|
|
13163
|
+
);
|
|
13164
|
+
}
|
|
13165
|
+
|
|
13116
13166
|
// src/chat/slack/tools/thread-read.ts
|
|
13117
13167
|
var MAX_THREAD_READ_CHARS = 4e4;
|
|
13118
|
-
function sanitizeMessage(msg) {
|
|
13168
|
+
function sanitizeMessage(msg, attachmentIdsBySlackFileId) {
|
|
13119
13169
|
const attachmentText = renderAttachmentText(msg.attachments);
|
|
13120
13170
|
return {
|
|
13121
13171
|
ts: msg.ts,
|
|
@@ -13131,7 +13181,8 @@ function sanitizeMessage(msg) {
|
|
|
13131
13181
|
id: f.id,
|
|
13132
13182
|
name: f.name,
|
|
13133
13183
|
mimetype: f.mimetype,
|
|
13134
|
-
size: f.size
|
|
13184
|
+
size: f.size,
|
|
13185
|
+
...f.id && attachmentIdsBySlackFileId.get(f.id) ? { attachment_id: attachmentIdsBySlackFileId.get(f.id) } : void 0
|
|
13135
13186
|
}))
|
|
13136
13187
|
} : void 0
|
|
13137
13188
|
};
|
|
@@ -13149,7 +13200,7 @@ function truncateMessages(messages, maxChars) {
|
|
|
13149
13200
|
}
|
|
13150
13201
|
return { messages: kept, omitted: messages.length - kept.length };
|
|
13151
13202
|
}
|
|
13152
|
-
function createSlackThreadReadTool(context) {
|
|
13203
|
+
function createSlackThreadReadTool(context, attachmentDeps) {
|
|
13153
13204
|
return zodTool({
|
|
13154
13205
|
description: "Read a Slack thread from a shared archive URL or explicit channel + timestamp. Works for the current conversation and public channels.",
|
|
13155
13206
|
annotations: {
|
|
@@ -13268,7 +13319,22 @@ function createSlackThreadReadTool(context) {
|
|
|
13268
13319
|
}
|
|
13269
13320
|
const root = replies[0];
|
|
13270
13321
|
const resolvedThreadTs = threadTs ?? root?.thread_ts ?? root?.ts ?? lookupTs;
|
|
13271
|
-
const
|
|
13322
|
+
const slackFileIds = replies.flatMap(
|
|
13323
|
+
(reply) => (reply.files ?? []).map((file) => file.id).filter((fileId) => Boolean(fileId))
|
|
13324
|
+
);
|
|
13325
|
+
const storedAttachments = attachmentDeps ? await matchSlackAttachments({
|
|
13326
|
+
conversationId: attachmentDeps.conversationId,
|
|
13327
|
+
db: attachmentDeps.db,
|
|
13328
|
+
providerIds: slackFileIds
|
|
13329
|
+
}) : [];
|
|
13330
|
+
const attachmentIdsBySlackFileId = new Map(
|
|
13331
|
+
storedAttachments.flatMap(
|
|
13332
|
+
(attachment) => attachment.providerId ? [[attachment.providerId, attachment.id]] : []
|
|
13333
|
+
)
|
|
13334
|
+
);
|
|
13335
|
+
const sanitized = replies.map(
|
|
13336
|
+
(reply) => sanitizeMessage(reply, attachmentIdsBySlackFileId)
|
|
13337
|
+
);
|
|
13272
13338
|
const { messages, omitted } = truncateMessages(
|
|
13273
13339
|
sanitized,
|
|
13274
13340
|
MAX_THREAD_READ_CHARS
|
|
@@ -13290,7 +13356,7 @@ function createSlackThreadReadTool(context) {
|
|
|
13290
13356
|
}
|
|
13291
13357
|
|
|
13292
13358
|
// src/chat/tools/user-lookup.ts
|
|
13293
|
-
import { and as
|
|
13359
|
+
import { and as and3, eq as eq3, or, sql } from "drizzle-orm";
|
|
13294
13360
|
import { alias } from "drizzle-orm/pg-core";
|
|
13295
13361
|
import { z as z54 } from "zod";
|
|
13296
13362
|
var linkedSlackIdentity = alias(juniorIdentities, "user_lookup_slack_identity");
|
|
@@ -13356,12 +13422,12 @@ async function storedSlackUserByEmail(teamId, email) {
|
|
|
13356
13422
|
const emailNormalized = normalizeIdentityEmail(email);
|
|
13357
13423
|
if (!emailNormalized) return void 0;
|
|
13358
13424
|
const identities = await getSqlExecutor().db().select().from(juniorIdentities).where(
|
|
13359
|
-
|
|
13360
|
-
|
|
13361
|
-
|
|
13362
|
-
|
|
13363
|
-
|
|
13364
|
-
|
|
13425
|
+
and3(
|
|
13426
|
+
eq3(juniorIdentities.provider, "slack"),
|
|
13427
|
+
eq3(juniorIdentities.providerTenantId, teamId),
|
|
13428
|
+
eq3(juniorIdentities.kind, "user"),
|
|
13429
|
+
eq3(juniorIdentities.emailVerified, true),
|
|
13430
|
+
eq3(juniorIdentities.emailNormalized, emailNormalized)
|
|
13365
13431
|
)
|
|
13366
13432
|
).limit(2);
|
|
13367
13433
|
if (identities.length > 1) {
|
|
@@ -13413,18 +13479,18 @@ async function resolveSlack(teamId, query) {
|
|
|
13413
13479
|
async function resolveStoredProvider(teamId, provider, query) {
|
|
13414
13480
|
const rows = await getSqlExecutor().db().select({ slack: linkedSlackIdentity }).from(juniorIdentities).innerJoin(
|
|
13415
13481
|
linkedSlackIdentity,
|
|
13416
|
-
|
|
13417
|
-
|
|
13418
|
-
|
|
13419
|
-
|
|
13420
|
-
|
|
13482
|
+
and3(
|
|
13483
|
+
eq3(linkedSlackIdentity.userId, juniorIdentities.userId),
|
|
13484
|
+
eq3(linkedSlackIdentity.kind, "user"),
|
|
13485
|
+
eq3(linkedSlackIdentity.provider, "slack"),
|
|
13486
|
+
eq3(linkedSlackIdentity.providerTenantId, teamId)
|
|
13421
13487
|
)
|
|
13422
13488
|
).where(
|
|
13423
|
-
|
|
13424
|
-
|
|
13425
|
-
|
|
13489
|
+
and3(
|
|
13490
|
+
eq3(juniorIdentities.kind, "user"),
|
|
13491
|
+
eq3(juniorIdentities.provider, provider),
|
|
13426
13492
|
or(
|
|
13427
|
-
|
|
13493
|
+
eq3(juniorIdentities.providerSubjectId, query),
|
|
13428
13494
|
sql`lower(${juniorIdentities.handle}) = lower(${query})`
|
|
13429
13495
|
)
|
|
13430
13496
|
)
|
|
@@ -13558,7 +13624,7 @@ import { z as z56 } from "zod";
|
|
|
13558
13624
|
|
|
13559
13625
|
// src/chat/artifacts/store.ts
|
|
13560
13626
|
import { createHash as createHash4, randomUUID as randomUUID4 } from "crypto";
|
|
13561
|
-
import { and as
|
|
13627
|
+
import { and as and4, eq as eq4, isNull as isNull2 } from "drizzle-orm";
|
|
13562
13628
|
var MAX_IMAGE_BYTES = 10 * 1024 * 1024;
|
|
13563
13629
|
var IMAGE_TYPES = {
|
|
13564
13630
|
gif: "image/gif",
|
|
@@ -13645,9 +13711,9 @@ async function publishImage(args) {
|
|
|
13645
13711
|
const [existing] = await args.db.db().select({
|
|
13646
13712
|
id: juniorArtifacts.id
|
|
13647
13713
|
}).from(juniorArtifacts).where(
|
|
13648
|
-
|
|
13649
|
-
|
|
13650
|
-
|
|
13714
|
+
and4(
|
|
13715
|
+
eq4(juniorArtifacts.conversationId, args.conversationId),
|
|
13716
|
+
eq4(juniorArtifacts.sha256, sha256)
|
|
13651
13717
|
)
|
|
13652
13718
|
);
|
|
13653
13719
|
const id = existing?.id ?? randomUUID4();
|
|
@@ -13708,9 +13774,9 @@ async function unpublishArtifact(args) {
|
|
|
13708
13774
|
}
|
|
13709
13775
|
const now = args.now ?? /* @__PURE__ */ new Date();
|
|
13710
13776
|
const updated = await args.db.db().update(juniorArtifacts).set({ deleteRequestedAt: now }).where(
|
|
13711
|
-
|
|
13712
|
-
|
|
13713
|
-
|
|
13777
|
+
and4(
|
|
13778
|
+
eq4(juniorArtifacts.id, parsed.id),
|
|
13779
|
+
eq4(juniorArtifacts.conversationId, args.conversationId)
|
|
13714
13780
|
)
|
|
13715
13781
|
).returning({ id: juniorArtifacts.id });
|
|
13716
13782
|
if (updated.length === 0) {
|
|
@@ -13727,10 +13793,10 @@ async function readPublicArtifact(args) {
|
|
|
13727
13793
|
contentType: juniorArtifacts.contentType,
|
|
13728
13794
|
storageKey: juniorArtifacts.storageKey
|
|
13729
13795
|
}).from(juniorArtifacts).where(
|
|
13730
|
-
|
|
13731
|
-
|
|
13732
|
-
|
|
13733
|
-
|
|
13796
|
+
and4(
|
|
13797
|
+
eq4(juniorArtifacts.id, parsed.id),
|
|
13798
|
+
eq4(juniorArtifacts.public, true),
|
|
13799
|
+
isNull2(juniorArtifacts.deleteRequestedAt)
|
|
13734
13800
|
)
|
|
13735
13801
|
);
|
|
13736
13802
|
if (!row) return null;
|
|
@@ -13770,20 +13836,20 @@ function createPublishImageTool(args) {
|
|
|
13770
13836
|
},
|
|
13771
13837
|
approvalMode: "review",
|
|
13772
13838
|
description: "Publish one sandbox image to a durable public HTTPS URL. Anyone on the internet with the URL can view the image. Use only when an external destination needs a public image URL. Do not use for private file sharing or private conversation storage. Supports PNG, JPEG, GIF, and WebP up to 10 MB.",
|
|
13773
|
-
describeProposal: ({ path:
|
|
13839
|
+
describeProposal: ({ path: path9 }) => `Publish sandbox image ${path9} to a public internet URL.`,
|
|
13774
13840
|
executionMode: "sequential",
|
|
13775
13841
|
inputSchema: z56.object({
|
|
13776
13842
|
path: z56.string().min(1).describe("Exact sandbox path of an existing image file.")
|
|
13777
13843
|
}).strict(),
|
|
13778
13844
|
outputSchema: outputSchema5,
|
|
13779
|
-
async execute({ path:
|
|
13845
|
+
async execute({ path: path9 }) {
|
|
13780
13846
|
const publicBaseUrl = (args.publicBaseUrl ?? resolveBaseUrl)()?.trim();
|
|
13781
13847
|
if (!publicBaseUrl) {
|
|
13782
13848
|
throw new Error(
|
|
13783
13849
|
"publishImage requires JUNIOR_BASE_URL or a Vercel deployment URL."
|
|
13784
13850
|
);
|
|
13785
13851
|
}
|
|
13786
|
-
const targetPath = normalizeSandboxPath(
|
|
13852
|
+
const targetPath = normalizeSandboxPath(path9);
|
|
13787
13853
|
const body = await args.workspace.readFileToBuffer({ path: targetPath });
|
|
13788
13854
|
if (!body) {
|
|
13789
13855
|
throw new SandboxFileNotFoundError(targetPath);
|
|
@@ -13843,28 +13909,99 @@ function createUnpublishImageTool(args) {
|
|
|
13843
13909
|
});
|
|
13844
13910
|
}
|
|
13845
13911
|
|
|
13846
|
-
// src/chat/tools/
|
|
13912
|
+
// src/chat/tools/load-attachment.ts
|
|
13913
|
+
import path8 from "path";
|
|
13847
13914
|
import { z as z58 } from "zod";
|
|
13915
|
+
var ATTACHMENT_DIR = ".junior/attachments";
|
|
13916
|
+
async function readStream(stream) {
|
|
13917
|
+
const chunks = [];
|
|
13918
|
+
const reader = stream.getReader();
|
|
13919
|
+
for (; ; ) {
|
|
13920
|
+
const { done, value } = await reader.read();
|
|
13921
|
+
if (done) break;
|
|
13922
|
+
chunks.push(value);
|
|
13923
|
+
}
|
|
13924
|
+
return Buffer.concat(chunks);
|
|
13925
|
+
}
|
|
13926
|
+
function createLoadAttachmentTool(args) {
|
|
13927
|
+
return zodTool({
|
|
13928
|
+
description: "Load a stored attachment for this conversation into the sandbox. Use the attachment_id shown in attachment context or Slack read results.",
|
|
13929
|
+
annotations: {
|
|
13930
|
+
destructiveHint: false,
|
|
13931
|
+
idempotentHint: true,
|
|
13932
|
+
openWorldHint: false,
|
|
13933
|
+
readOnlyHint: false
|
|
13934
|
+
},
|
|
13935
|
+
inputSchema: z58.object({
|
|
13936
|
+
attachment_id: z58.string().min(1).describe("Stored attachment ID.")
|
|
13937
|
+
}),
|
|
13938
|
+
outputSchema: juniorToolOutputSchema,
|
|
13939
|
+
execute: async ({ attachment_id }) => {
|
|
13940
|
+
const attachment = await readLiveAttachment({
|
|
13941
|
+
attachmentId: attachment_id,
|
|
13942
|
+
conversationId: args.conversationId,
|
|
13943
|
+
db: args.db
|
|
13944
|
+
});
|
|
13945
|
+
if (!attachment || attachment.storageProvider !== args.storage.provider) {
|
|
13946
|
+
throw new ToolInputError("Attachment not found in this conversation.");
|
|
13947
|
+
}
|
|
13948
|
+
const body = await args.storage.get(attachment.storageKey);
|
|
13949
|
+
if (!body) {
|
|
13950
|
+
throw new ToolInputError("Stored attachment contents are unavailable.");
|
|
13951
|
+
}
|
|
13952
|
+
const data = await readStream(body);
|
|
13953
|
+
if (data.byteLength !== attachment.bytes) {
|
|
13954
|
+
throw new Error(
|
|
13955
|
+
`Attachment ${attachment.id} read ${data.byteLength} bytes, expected ${attachment.bytes}.`
|
|
13956
|
+
);
|
|
13957
|
+
}
|
|
13958
|
+
const attachmentDir = path8.posix.join(ATTACHMENT_DIR, attachment.id);
|
|
13959
|
+
const sandboxPath = path8.posix.join(
|
|
13960
|
+
attachmentDir,
|
|
13961
|
+
path8.posix.basename(attachment.filename)
|
|
13962
|
+
);
|
|
13963
|
+
const mkdir = await args.workspace.runCommand({
|
|
13964
|
+
cmd: "mkdir",
|
|
13965
|
+
args: ["-p", attachmentDir]
|
|
13966
|
+
});
|
|
13967
|
+
if (mkdir.exitCode !== 0) {
|
|
13968
|
+
throw new Error(
|
|
13969
|
+
`Failed to create attachment directory: ${mkdir.stderr}`
|
|
13970
|
+
);
|
|
13971
|
+
}
|
|
13972
|
+
await args.workspace.writeFiles([{ content: data, path: sandboxPath }]);
|
|
13973
|
+
return {
|
|
13974
|
+
path: sandboxPath,
|
|
13975
|
+
filename: attachment.filename,
|
|
13976
|
+
mime_type: attachment.contentType,
|
|
13977
|
+
bytes: attachment.bytes
|
|
13978
|
+
};
|
|
13979
|
+
}
|
|
13980
|
+
});
|
|
13981
|
+
}
|
|
13982
|
+
|
|
13983
|
+
// src/chat/tools/search-conversation-events.ts
|
|
13984
|
+
import { z as z59 } from "zod";
|
|
13848
13985
|
var DEFAULT_LIMIT3 = 25;
|
|
13849
13986
|
var MAX_LIMIT2 = 100;
|
|
13850
13987
|
var MAX_EVENT_DATA_BYTES = 4e3;
|
|
13851
13988
|
var MAX_EVENTS_JSON_BYTES = 2e4;
|
|
13852
13989
|
var MAX_IDENTITY_CHARS = 256;
|
|
13853
13990
|
var textEncoder = new TextEncoder();
|
|
13854
|
-
var knownEventTypeSchema =
|
|
13855
|
-
var projectedEventSchema =
|
|
13856
|
-
seq:
|
|
13857
|
-
history_version:
|
|
13858
|
-
created_at:
|
|
13859
|
-
idempotency_key:
|
|
13860
|
-
data:
|
|
13991
|
+
var knownEventTypeSchema = z59.enum(KNOWN_CONVERSATION_EVENT_TYPES);
|
|
13992
|
+
var projectedEventSchema = z59.object({
|
|
13993
|
+
seq: z59.number().int().nonnegative().describe("Stable event position for pagination."),
|
|
13994
|
+
history_version: z59.number().int().nonnegative().describe("Agent history generation after replacement."),
|
|
13995
|
+
created_at: z59.iso.datetime().describe("When the event was recorded."),
|
|
13996
|
+
idempotency_key: z59.string().min(1).optional().describe("Retry-stable event identity, when assigned."),
|
|
13997
|
+
data: z59.record(z59.string(), z59.unknown()).describe("Bounded event data.")
|
|
13861
13998
|
}).strict();
|
|
13862
13999
|
var searchConversationEventsOutputSchema = juniorToolOutputSchema.extend({
|
|
13863
|
-
conversation_id:
|
|
13864
|
-
events:
|
|
13865
|
-
has_older:
|
|
13866
|
-
has_newer:
|
|
13867
|
-
omitted_event_count:
|
|
14000
|
+
conversation_id: z59.string().min(1),
|
|
14001
|
+
events: z59.array(projectedEventSchema),
|
|
14002
|
+
has_older: z59.boolean().describe("Whether matching older events exist."),
|
|
14003
|
+
has_newer: z59.boolean().describe("Whether matching newer events exist."),
|
|
14004
|
+
omitted_event_count: z59.number().int().nonnegative().optional().describe("Events omitted by the response byte limit.")
|
|
13868
14005
|
});
|
|
13869
14006
|
function createSearchConversationEventsTool(context) {
|
|
13870
14007
|
return zodTool({
|
|
@@ -13877,16 +14014,16 @@ function createSearchConversationEventsTool(context) {
|
|
|
13877
14014
|
openWorldHint: false,
|
|
13878
14015
|
readOnlyHint: true
|
|
13879
14016
|
},
|
|
13880
|
-
inputSchema:
|
|
13881
|
-
conversation_id:
|
|
14017
|
+
inputSchema: z59.object({
|
|
14018
|
+
conversation_id: z59.string().trim().min(1).nullable().describe(
|
|
13882
14019
|
"Conversation ID to search. Omit or null for the current conversation."
|
|
13883
14020
|
).optional(),
|
|
13884
|
-
after_seq:
|
|
13885
|
-
before_seq:
|
|
13886
|
-
limit:
|
|
14021
|
+
after_seq: z59.number().int().nonnegative().nullable().describe("Exclusive event sequence lower bound; returns ascending.").optional(),
|
|
14022
|
+
before_seq: z59.number().int().nonnegative().nullable().describe("Exclusive event sequence upper bound.").optional(),
|
|
14023
|
+
limit: z59.number().int().min(1).max(MAX_LIMIT2).nullable().describe(
|
|
13887
14024
|
`Maximum events. Default ${DEFAULT_LIMIT3}; max ${MAX_LIMIT2}.`
|
|
13888
14025
|
).optional(),
|
|
13889
|
-
types:
|
|
14026
|
+
types: z59.array(knownEventTypeSchema).min(1).nullable().describe("Event types to include; omit for all types.").optional()
|
|
13890
14027
|
}).strict(),
|
|
13891
14028
|
outputSchema: searchConversationEventsOutputSchema,
|
|
13892
14029
|
execute: async (input) => {
|
|
@@ -14135,7 +14272,7 @@ function stripReplacementHistoryField(value) {
|
|
|
14135
14272
|
}
|
|
14136
14273
|
|
|
14137
14274
|
// src/chat/tools/handoff/tool.ts
|
|
14138
|
-
import { z as
|
|
14275
|
+
import { z as z60 } from "zod";
|
|
14139
14276
|
var HANDOFF_TOOL_NAME = "handoff";
|
|
14140
14277
|
function formatHandoffProfiles(handoff) {
|
|
14141
14278
|
return handoff.profiles.map(
|
|
@@ -14143,7 +14280,7 @@ function formatHandoffProfiles(handoff) {
|
|
|
14143
14280
|
).join("\n");
|
|
14144
14281
|
}
|
|
14145
14282
|
function createHandoffTool(handoff) {
|
|
14146
|
-
const profileSchema =
|
|
14283
|
+
const profileSchema = z60.enum(
|
|
14147
14284
|
handoff.profiles.map((profile) => profile.name)
|
|
14148
14285
|
);
|
|
14149
14286
|
const handoffResultSchema = juniorToolOutputSchema.extend({
|
|
@@ -14168,7 +14305,7 @@ function createHandoffTool(handoff) {
|
|
|
14168
14305
|
${profileList}`
|
|
14169
14306
|
].join(" "),
|
|
14170
14307
|
executionMode: "sequential",
|
|
14171
|
-
inputSchema:
|
|
14308
|
+
inputSchema: z60.object({
|
|
14172
14309
|
profile: profileSchema.describe(
|
|
14173
14310
|
"Exact configured profile name. Choose the profile whose description best fits the remaining task. If none clearly fits better, do not call handoff."
|
|
14174
14311
|
)
|
|
@@ -14191,7 +14328,7 @@ ${profileList}`
|
|
|
14191
14328
|
}
|
|
14192
14329
|
|
|
14193
14330
|
// src/chat/tools/web/fetch-tool.ts
|
|
14194
|
-
import { z as
|
|
14331
|
+
import { z as z61 } from "zod";
|
|
14195
14332
|
|
|
14196
14333
|
// src/chat/tools/web/constants.ts
|
|
14197
14334
|
var USER_AGENT = "junior-bot/0.1";
|
|
@@ -14640,9 +14777,9 @@ function createWebFetchTool(hooks, options = {}) {
|
|
|
14640
14777
|
openWorldHint: true,
|
|
14641
14778
|
readOnlyHint: true
|
|
14642
14779
|
},
|
|
14643
|
-
inputSchema:
|
|
14644
|
-
url:
|
|
14645
|
-
max_chars:
|
|
14780
|
+
inputSchema: z61.object({
|
|
14781
|
+
url: z61.string().min(1).describe("HTTP(S) URL to fetch."),
|
|
14782
|
+
max_chars: z61.coerce.number().int().min(500).max(MAX_FETCH_CHARS).describe("Optional maximum number of extracted characters to return.").optional()
|
|
14646
14783
|
}),
|
|
14647
14784
|
outputSchema: juniorToolOutputSchema,
|
|
14648
14785
|
execute: async ({ url, max_chars }) => {
|
|
@@ -14687,7 +14824,7 @@ function createWebFetchTool(hooks, options = {}) {
|
|
|
14687
14824
|
}
|
|
14688
14825
|
|
|
14689
14826
|
// src/chat/tools/web/search.ts
|
|
14690
|
-
import { z as
|
|
14827
|
+
import { z as z62 } from "zod";
|
|
14691
14828
|
import { generateText } from "ai";
|
|
14692
14829
|
import { createGatewayProvider } from "@ai-sdk/gateway";
|
|
14693
14830
|
var SEARCH_TIMEOUT_MS = 6e4;
|
|
@@ -14729,9 +14866,9 @@ function createWebSearchTool(modelId, override) {
|
|
|
14729
14866
|
openWorldHint: true,
|
|
14730
14867
|
readOnlyHint: true
|
|
14731
14868
|
},
|
|
14732
|
-
inputSchema:
|
|
14733
|
-
query:
|
|
14734
|
-
max_results:
|
|
14869
|
+
inputSchema: z62.object({
|
|
14870
|
+
query: z62.string().min(1).max(500).describe("Search query."),
|
|
14871
|
+
max_results: z62.coerce.number().int().min(1).max(MAX_RESULTS2).describe("Max results to return.").optional()
|
|
14735
14872
|
}),
|
|
14736
14873
|
outputSchema: juniorToolOutputSchema,
|
|
14737
14874
|
execute: async ({ query, max_results }) => {
|
|
@@ -14773,7 +14910,7 @@ function createWebSearchTool(modelId, override) {
|
|
|
14773
14910
|
}
|
|
14774
14911
|
|
|
14775
14912
|
// src/chat/tools/sandbox/write-file.ts
|
|
14776
|
-
import { z as
|
|
14913
|
+
import { z as z63 } from "zod";
|
|
14777
14914
|
function createWriteFileTool() {
|
|
14778
14915
|
return zodTool({
|
|
14779
14916
|
annotations: {
|
|
@@ -14784,9 +14921,9 @@ function createWriteFileTool() {
|
|
|
14784
14921
|
},
|
|
14785
14922
|
description: "Write UTF-8 content to a file in the sandbox workspace. Use for intentional file creation or deliberate full-file replacement after validation; use editFile instead for targeted changes to existing files. Do not use for exploratory analysis-only turns.",
|
|
14786
14923
|
executionMode: "sequential",
|
|
14787
|
-
inputSchema:
|
|
14788
|
-
path:
|
|
14789
|
-
content:
|
|
14924
|
+
inputSchema: z63.object({
|
|
14925
|
+
path: z63.string().min(1).describe("Path to write in the sandbox workspace."),
|
|
14926
|
+
content: z63.string().describe("UTF-8 file content to write.")
|
|
14790
14927
|
}),
|
|
14791
14928
|
outputSchema: juniorToolOutputSchema,
|
|
14792
14929
|
execute: async () => {
|
|
@@ -14798,7 +14935,7 @@ function createWriteFileTool() {
|
|
|
14798
14935
|
}
|
|
14799
14936
|
|
|
14800
14937
|
// src/chat/workspaces/tools.ts
|
|
14801
|
-
import { z as
|
|
14938
|
+
import { z as z64 } from "zod";
|
|
14802
14939
|
import {
|
|
14803
14940
|
resourceEventSubscriptionResultSchema
|
|
14804
14941
|
} from "@sentry/junior-plugin-api";
|
|
@@ -14830,16 +14967,16 @@ async function stopWorkspaceSnapshotWatch(input) {
|
|
|
14830
14967
|
});
|
|
14831
14968
|
}
|
|
14832
14969
|
}
|
|
14833
|
-
var repoSchema =
|
|
14834
|
-
provider:
|
|
14835
|
-
repo:
|
|
14836
|
-
checkout_path:
|
|
14970
|
+
var repoSchema = z64.object({
|
|
14971
|
+
provider: z64.string(),
|
|
14972
|
+
repo: z64.string(),
|
|
14973
|
+
checkout_path: z64.string()
|
|
14837
14974
|
});
|
|
14838
|
-
var workspaceSchema =
|
|
14839
|
-
id:
|
|
14840
|
-
name:
|
|
14841
|
-
setup_script:
|
|
14842
|
-
repos:
|
|
14975
|
+
var workspaceSchema = z64.object({
|
|
14976
|
+
id: z64.string(),
|
|
14977
|
+
name: z64.string(),
|
|
14978
|
+
setup_script: z64.string(),
|
|
14979
|
+
repos: z64.array(repoSchema)
|
|
14843
14980
|
});
|
|
14844
14981
|
function view(workspace) {
|
|
14845
14982
|
return {
|
|
@@ -14872,18 +15009,18 @@ function workspaceProviderNames() {
|
|
|
14872
15009
|
}
|
|
14873
15010
|
function workspaceWriteSchemas(providers) {
|
|
14874
15011
|
const providerNames = providers.map((provider) => `\`${provider}\``).join(", ");
|
|
14875
|
-
const repoInputSchema =
|
|
14876
|
-
provider:
|
|
14877
|
-
repo:
|
|
15012
|
+
const repoInputSchema = z64.object({
|
|
15013
|
+
provider: z64.enum(providers).describe(`Repository provider. Supported: ${providerNames}.`),
|
|
15014
|
+
repo: z64.string().trim().min(1).describe("Repository in owner/name format.")
|
|
14878
15015
|
}).strict();
|
|
14879
|
-
const workspaceInputSchema =
|
|
14880
|
-
name:
|
|
15016
|
+
const workspaceInputSchema = z64.object({
|
|
15017
|
+
name: z64.string().trim().min(1).describe(
|
|
14881
15018
|
"Workspace name. Use lowercase letters, digits, underscores, or hyphens."
|
|
14882
15019
|
),
|
|
14883
|
-
setup_script:
|
|
15020
|
+
setup_script: z64.string().nullable().describe(
|
|
14884
15021
|
"Optional shell script to run after repository checkout whenever this Workspace starts. Omit or use null for no setup script."
|
|
14885
15022
|
).optional(),
|
|
14886
|
-
repos:
|
|
15023
|
+
repos: z64.array(repoInputSchema).max(32).describe("Complete repository list.")
|
|
14887
15024
|
}).strict();
|
|
14888
15025
|
return { providerNames, workspaceInputSchema };
|
|
14889
15026
|
}
|
|
@@ -14958,7 +15095,7 @@ function createWorkspaceWriteTools(providers) {
|
|
|
14958
15095
|
},
|
|
14959
15096
|
description: `Replace an install-wide Workspace recipe. Repository providers: ${providerNames}. Use the Workspace ID returned by listWorkspaces.`,
|
|
14960
15097
|
inputSchema: workspaceInputSchema.extend({
|
|
14961
|
-
id:
|
|
15098
|
+
id: z64.string().uuid().describe("Workspace ID from listWorkspaces.")
|
|
14962
15099
|
}).strict(),
|
|
14963
15100
|
prepareArguments(args) {
|
|
14964
15101
|
const input = args;
|
|
@@ -14991,11 +15128,11 @@ function createWorkspaceWriteTools(providers) {
|
|
|
14991
15128
|
readOnlyHint: false
|
|
14992
15129
|
},
|
|
14993
15130
|
description: "Delete one install-wide Workspace recipe. Use the Workspace ID returned by listWorkspaces.",
|
|
14994
|
-
inputSchema:
|
|
14995
|
-
id:
|
|
15131
|
+
inputSchema: z64.object({
|
|
15132
|
+
id: z64.string().uuid().describe("Workspace ID from listWorkspaces.")
|
|
14996
15133
|
}).strict(),
|
|
14997
15134
|
outputSchema: juniorToolOutputSchema.extend({
|
|
14998
|
-
deleted:
|
|
15135
|
+
deleted: z64.literal(true)
|
|
14999
15136
|
}),
|
|
15000
15137
|
async execute({ id }) {
|
|
15001
15138
|
const deleted = await workspaceWrite(() => deleteWorkspace(id));
|
|
@@ -15020,10 +15157,10 @@ function createWorkspaceTools(context) {
|
|
|
15020
15157
|
readOnlyHint: true
|
|
15021
15158
|
},
|
|
15022
15159
|
description: "List named repository workspaces that can replace the current sandbox.",
|
|
15023
|
-
inputSchema:
|
|
15160
|
+
inputSchema: z64.object({}).strict(),
|
|
15024
15161
|
outputSchema: juniorToolOutputSchema.extend({
|
|
15025
|
-
active_workspace_id:
|
|
15026
|
-
workspaces:
|
|
15162
|
+
active_workspace_id: z64.string().nullable(),
|
|
15163
|
+
workspaces: z64.array(workspaceSchema)
|
|
15027
15164
|
}),
|
|
15028
15165
|
async execute() {
|
|
15029
15166
|
return {
|
|
@@ -15041,12 +15178,12 @@ function createWorkspaceTools(context) {
|
|
|
15041
15178
|
readOnlyHint: false
|
|
15042
15179
|
},
|
|
15043
15180
|
description: "Replace the current sandbox with a named repository Workspace. Files in the old sandbox do not carry over. Returns ready after the switch, or building with a temporary subscription when the snapshot is still being prepared. When building, wait for the ready event and call switchWorkspace again with the same name.",
|
|
15044
|
-
inputSchema:
|
|
15045
|
-
name:
|
|
15181
|
+
inputSchema: z64.object({
|
|
15182
|
+
name: z64.string().trim().min(1).describe("Exact workspace name.")
|
|
15046
15183
|
}).strict(),
|
|
15047
15184
|
outputSchema: juniorToolOutputSchema.extend({
|
|
15048
15185
|
workspace: workspaceSchema,
|
|
15049
|
-
status:
|
|
15186
|
+
status: z64.enum(["ready", "building"]),
|
|
15050
15187
|
subscription: resourceEventSubscriptionResultSchema.optional().describe(
|
|
15051
15188
|
"Present when the snapshot ready and failed events are already watched for this conversation."
|
|
15052
15189
|
)
|
|
@@ -15178,6 +15315,12 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
|
|
|
15178
15315
|
);
|
|
15179
15316
|
}
|
|
15180
15317
|
if (context.attachmentStorage) {
|
|
15318
|
+
tools.loadAttachment = createLoadAttachmentTool({
|
|
15319
|
+
conversationId: context.conversationId,
|
|
15320
|
+
db: getSqlExecutor(),
|
|
15321
|
+
storage: context.attachmentStorage,
|
|
15322
|
+
workspace: context.workspace
|
|
15323
|
+
});
|
|
15181
15324
|
tools.publishImage = createPublishImageTool({
|
|
15182
15325
|
conversationId: context.conversationId,
|
|
15183
15326
|
db: getSqlExecutor(),
|
|
@@ -15203,7 +15346,10 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
|
|
|
15203
15346
|
tools.slackCanvasRead = createSlackCanvasReadTool();
|
|
15204
15347
|
tools.slackCanvasEdit = createSlackCanvasEditTool(state);
|
|
15205
15348
|
tools.slackCanvasWrite = createSlackCanvasWriteTool(state);
|
|
15206
|
-
tools.slackThreadRead = createSlackThreadReadTool(slackContext
|
|
15349
|
+
tools.slackThreadRead = createSlackThreadReadTool(slackContext, {
|
|
15350
|
+
conversationId: context.conversationId,
|
|
15351
|
+
db: getSqlExecutor()
|
|
15352
|
+
});
|
|
15207
15353
|
tools.slackChannelJoin = createSlackChannelJoinTool(slackContext);
|
|
15208
15354
|
if (context.conversationPrivacy === "public") {
|
|
15209
15355
|
tools.searchConversationMessages = createSlackConversationMessageSearchTool(
|
|
@@ -15832,7 +15978,7 @@ function handleToolExecutionError(error, toolName, toolCallId, shouldTrace, conv
|
|
|
15832
15978
|
}
|
|
15833
15979
|
|
|
15834
15980
|
// src/chat/tools/execute-tool.ts
|
|
15835
|
-
import { z as
|
|
15981
|
+
import { z as z65 } from "zod";
|
|
15836
15982
|
var EXECUTE_TOOL_NAME = "executeTool";
|
|
15837
15983
|
function createExecuteToolTool() {
|
|
15838
15984
|
return zodTool({
|
|
@@ -15844,11 +15990,11 @@ function createExecuteToolTool() {
|
|
|
15844
15990
|
},
|
|
15845
15991
|
description: "Execute any catalog tool by exact tool_name from searchTools or a tool-result execution hint. Put tool-specific parameters inside arguments.",
|
|
15846
15992
|
executionMode: "sequential",
|
|
15847
|
-
inputSchema:
|
|
15848
|
-
tool_name:
|
|
15993
|
+
inputSchema: z65.object({
|
|
15994
|
+
tool_name: z65.string().min(1).describe(
|
|
15849
15995
|
"Exact catalog tool_name returned by searchTools or a tool-result execution hint."
|
|
15850
15996
|
),
|
|
15851
|
-
arguments:
|
|
15997
|
+
arguments: z65.record(z65.string(), z65.unknown()).describe(
|
|
15852
15998
|
'Arguments matching the selected catalog tool schema, for example { "query": "..." }.'
|
|
15853
15999
|
).optional()
|
|
15854
16000
|
}).strict(),
|
|
@@ -15888,7 +16034,7 @@ function planToolExposure(tools) {
|
|
|
15888
16034
|
}
|
|
15889
16035
|
|
|
15890
16036
|
// src/chat/tools/search-tools.ts
|
|
15891
|
-
import { z as
|
|
16037
|
+
import { z as z66 } from "zod";
|
|
15892
16038
|
var SEARCH_TOOLS_NAME = "searchTools";
|
|
15893
16039
|
var DEFAULT_MAX_RESULTS2 = 5;
|
|
15894
16040
|
var MAX_RESULTS3 = 20;
|
|
@@ -15933,29 +16079,29 @@ var SEARCH_STOP_WORDS = /* @__PURE__ */ new Set([
|
|
|
15933
16079
|
"you",
|
|
15934
16080
|
"your"
|
|
15935
16081
|
]);
|
|
15936
|
-
var searchToolsSourceSchema =
|
|
15937
|
-
id:
|
|
15938
|
-
description:
|
|
16082
|
+
var searchToolsSourceSchema = z66.object({
|
|
16083
|
+
id: z66.string(),
|
|
16084
|
+
description: z66.string()
|
|
15939
16085
|
}).strict();
|
|
15940
|
-
var searchToolsToolSchema =
|
|
15941
|
-
tool_name:
|
|
15942
|
-
description:
|
|
15943
|
-
exposure:
|
|
15944
|
-
source:
|
|
15945
|
-
input_schema:
|
|
15946
|
-
call_notes:
|
|
15947
|
-
annotations:
|
|
16086
|
+
var searchToolsToolSchema = z66.object({
|
|
16087
|
+
tool_name: z66.string(),
|
|
16088
|
+
description: z66.string(),
|
|
16089
|
+
exposure: z66.enum(["direct", "deferred", "modelOnly", "hidden"]),
|
|
16090
|
+
source: z66.string().optional(),
|
|
16091
|
+
input_schema: z66.unknown(),
|
|
16092
|
+
call_notes: z66.array(z66.string()),
|
|
16093
|
+
annotations: z66.record(z66.string(), z66.unknown())
|
|
15948
16094
|
}).strict();
|
|
15949
16095
|
var searchToolsOutputSchema = juniorToolOutputSchema.extend({
|
|
15950
|
-
query:
|
|
15951
|
-
source:
|
|
15952
|
-
sources:
|
|
15953
|
-
total_catalog_tools:
|
|
15954
|
-
total_eligible_tools:
|
|
15955
|
-
total_matches:
|
|
15956
|
-
returned_tools:
|
|
15957
|
-
execution_tool:
|
|
15958
|
-
tools:
|
|
16096
|
+
query: z66.string().nullable(),
|
|
16097
|
+
source: z66.string().nullable(),
|
|
16098
|
+
sources: z66.array(searchToolsSourceSchema),
|
|
16099
|
+
total_catalog_tools: z66.number().int().nonnegative(),
|
|
16100
|
+
total_eligible_tools: z66.number().int().nonnegative(),
|
|
16101
|
+
total_matches: z66.number().int().nonnegative(),
|
|
16102
|
+
returned_tools: z66.number().int().nonnegative(),
|
|
16103
|
+
execution_tool: z66.literal("executeTool"),
|
|
16104
|
+
tools: z66.array(searchToolsToolSchema)
|
|
15959
16105
|
}).strict();
|
|
15960
16106
|
function terms(value) {
|
|
15961
16107
|
const chunks = value.match(/[\p{L}\p{N}]+/gu) ?? [];
|
|
@@ -16166,14 +16312,14 @@ function createSearchToolsTool(catalogTools) {
|
|
|
16166
16312
|
openWorldHint: false,
|
|
16167
16313
|
readOnlyHint: true
|
|
16168
16314
|
},
|
|
16169
|
-
inputSchema:
|
|
16170
|
-
query:
|
|
16315
|
+
inputSchema: z66.object({
|
|
16316
|
+
query: z66.string().nullable().describe(
|
|
16171
16317
|
"Optional search terms describing the tool, owner, action, or arguments needed. Empty string lists catalog tools."
|
|
16172
16318
|
).optional(),
|
|
16173
|
-
source:
|
|
16319
|
+
source: z66.string().nullable().describe(
|
|
16174
16320
|
"Optional source id to search within, such as a plugin source returned in sources."
|
|
16175
16321
|
).optional(),
|
|
16176
|
-
max_results:
|
|
16322
|
+
max_results: z66.number().int().min(1).max(MAX_RESULTS3).nullable().describe("Maximum matching catalog tool descriptors to return.").optional()
|
|
16177
16323
|
}).strict(),
|
|
16178
16324
|
outputSchema: searchToolsOutputSchema,
|
|
16179
16325
|
privateTraceResult: (result) => ({
|
|
@@ -17471,7 +17617,7 @@ function createPluginEgress(deps) {
|
|
|
17471
17617
|
}
|
|
17472
17618
|
|
|
17473
17619
|
// src/chat/services/guardian-action-review.ts
|
|
17474
|
-
import { z as
|
|
17620
|
+
import { z as z67 } from "zod";
|
|
17475
17621
|
|
|
17476
17622
|
// src/chat/services/guardian-action-policy.ts
|
|
17477
17623
|
var GUARDIAN_ACTION_POLICY = `You are judging one planned Junior agent action.
|
|
@@ -17545,17 +17691,17 @@ Assess the exact action's intrinsic risk and whether the user's intent authorize
|
|
|
17545
17691
|
- Keep the reason to one concise, specific sentence grounded in the main risk or authorization fact. For ask, name the exact action, target, and material side effects the user must confirm.`;
|
|
17546
17692
|
|
|
17547
17693
|
// src/chat/services/guardian-action-review.ts
|
|
17548
|
-
var guardianDecisionSchema =
|
|
17549
|
-
decision:
|
|
17550
|
-
reason:
|
|
17551
|
-
riskLevel:
|
|
17552
|
-
userAuthorization:
|
|
17694
|
+
var guardianDecisionSchema = z67.object({
|
|
17695
|
+
decision: z67.enum(["allow", "ask", "deny"]),
|
|
17696
|
+
reason: z67.string().trim().min(1).max(500),
|
|
17697
|
+
riskLevel: z67.enum(["low", "medium", "high", "critical"]),
|
|
17698
|
+
userAuthorization: z67.enum(["high", "medium", "low", "unknown"])
|
|
17553
17699
|
}).strict();
|
|
17554
17700
|
var GUARDIAN_REVIEW_TIMEOUT_MS = 6e4;
|
|
17555
17701
|
var GUARDIAN_REVIEW_MAX_TOKENS = 2e3;
|
|
17556
17702
|
var MAX_PROPOSAL_CHARS = 192e3;
|
|
17557
17703
|
function guardianPrompt(proposal) {
|
|
17558
|
-
const proposalJson = JSON.stringify(
|
|
17704
|
+
const proposalJson = JSON.stringify(z67.json().parse(proposal), null, 2);
|
|
17559
17705
|
if (proposalJson.length > MAX_PROPOSAL_CHARS) {
|
|
17560
17706
|
throw new Error(
|
|
17561
17707
|
`Guardian action proposal exceeds ${MAX_PROPOSAL_CHARS} characters.`
|
|
@@ -20245,6 +20391,7 @@ export {
|
|
|
20245
20391
|
setConfigDefaults,
|
|
20246
20392
|
getConfigDefaults,
|
|
20247
20393
|
shouldEmitDevAgentTrace,
|
|
20394
|
+
isVisionImageMediaType,
|
|
20248
20395
|
buildSteeringPiMessage,
|
|
20249
20396
|
SANDBOX_EGRESS_PROXY_PATH,
|
|
20250
20397
|
parseSandboxEgressCredentialToken,
|
|
@@ -20269,6 +20416,8 @@ export {
|
|
|
20269
20416
|
listThreadReplies,
|
|
20270
20417
|
renderBlockText,
|
|
20271
20418
|
renderAttachmentText,
|
|
20419
|
+
recordSlackAttachment,
|
|
20420
|
+
readAttachmentVisionSummary,
|
|
20272
20421
|
readPublicArtifact,
|
|
20273
20422
|
publicArtifactHeaders,
|
|
20274
20423
|
unpublishedArtifactHeaders,
|