@sentry/junior 0.200.0 → 0.201.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-HMG23EIR.js} +11 -11
- package/dist/api.js +25 -25
- package/dist/app.js +207 -122
- package/dist/{catalog-runtime-CIO3ERVQ.js → catalog-runtime-7TIXWSYG.js} +4 -4
- package/dist/{chunk-PIHLVU7T.js → chunk-3XPQV262.js} +6 -6
- package/dist/{chunk-PMSENMWY.js → chunk-44W7JB5V.js} +1 -1
- package/dist/{chunk-LICM66W2.js → chunk-4DDQVL3Q.js} +2 -2
- package/dist/{chunk-22Y5SBDM.js → chunk-5LXHEN3P.js} +8 -8
- package/dist/{chunk-5JDNDQHL.js → chunk-6CYKW2J7.js} +1 -1
- package/dist/{chunk-JLUCKXGI.js → chunk-6QQYL2XW.js} +6 -6
- package/dist/{chunk-RDWWCDA4.js → chunk-73RVLY6A.js} +2 -2
- package/dist/{chunk-T6263C3N.js → chunk-7V4KWIXL.js} +2 -2
- package/dist/{chunk-ADNSL3MX.js → chunk-7YNSWPVU.js} +8 -8
- package/dist/{chunk-TF5TXGRD.js → chunk-APX6WBD7.js} +1 -1
- package/dist/{chunk-UR43NMUR.js → chunk-BQFWG7MB.js} +4 -4
- package/dist/{chunk-4Q5IR5GA.js → chunk-FNAEGMGB.js} +1 -1
- package/dist/{chunk-V2VL335Y.js → chunk-GHZ677GD.js} +21 -21
- package/dist/{chunk-5Q6KP6LH.js → chunk-H5SDC32F.js} +1 -1
- package/dist/{chunk-OIILBD56.js → chunk-I7F3JVYE.js} +3 -3
- package/dist/{chunk-ZPLAAHVP.js → chunk-IXGQ4NTO.js} +5 -5
- package/dist/{chunk-PSQ4SWI3.js → chunk-J4AWOSCT.js} +4 -4
- package/dist/{chunk-N5VHBUXF.js → chunk-JYJG6LAG.js} +19 -6
- package/dist/{chunk-OVHO76WN.js → chunk-KKI5K43Z.js} +3 -3
- package/dist/{chunk-YVP6QNBZ.js → chunk-KS5RPVQI.js} +3 -3
- package/dist/{chunk-RG74Q34N.js → chunk-LINEEYW6.js} +1 -1
- package/dist/{chunk-OTTKTTVI.js → chunk-NN5Y32TJ.js} +1 -1
- package/dist/{chunk-AV552V2K.js → chunk-OZ2QJWQF.js} +3 -3
- package/dist/{chunk-GFXDMDHR.js → chunk-PJIU4AGA.js} +2 -2
- package/dist/{chunk-IAZBUDVU.js → chunk-Q3BTNRDK.js} +36 -30
- package/dist/{chunk-SY2RQ77O.js → chunk-QHCI2E2A.js} +1 -1
- package/dist/{chunk-752M26LC.js → chunk-RAWQD5DS.js} +1 -1
- package/dist/{chunk-7DO36XLF.js → chunk-SIMN6AUL.js} +1 -1
- package/dist/{chunk-ODSGDVHT.js → chunk-T4WKGKAW.js} +5 -5
- package/dist/{chunk-3WUBDFFL.js → chunk-UEIDAG2O.js} +1 -1
- package/dist/{chunk-K2QYWZ7F.js → chunk-UJRD4NN4.js} +14 -3
- package/dist/{chunk-JMRHEW6B.js → chunk-VGNL3QUM.js} +3 -3
- package/dist/{chunk-LUITHZZL.js → chunk-VQ2XYXLB.js} +8 -8
- package/dist/{chunk-M7BHRB3G.js → chunk-VRD7FJZ2.js} +4 -4
- package/dist/{chunk-X2Q4H6JQ.js → chunk-X2PTNIN5.js} +311 -166
- package/dist/{chunk-5VRPXF4T.js → chunk-Y6EUAX5O.js} +1 -1
- package/dist/{chunk-VLBLCJXK.js → chunk-ZPGGVW34.js} +5 -5
- package/dist/{chunk-EOOWKTQC.js → chunk-ZXSPPXX3.js} +9 -9
- 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-S5DGFIFR.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-JDEUY5KP.js} +29 -29
- package/dist/{runner-Z3EQSZ23.js → runner-OQZRPML2.js} +21 -21
- package/dist/{skills-CGEPG74A.js → skills-4VE2VHGF.js} +5 -5
- package/dist/spawn-4WCYSTFY.js +42 -0
- package/dist/task-runner-7SDXKQ3L.js +36 -0
- package/dist/{validation-YLALMVMB.js → validation-CX2H5J6S.js} +5 -5
- package/dist/version.js +1 -1
- package/dist/{work-N6PUG4MY.js → work-GUHO34OE.js} +21 -21
- package/dist/{worker-M7464FAO.js → worker-F44XXKBH.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 +5 -5
- 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-ZPGGVW34.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-5LXHEN3P.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-3XPQV262.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-UEIDAG2O.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-6QQYL2XW.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-Q3BTNRDK.js";
|
|
166
167
|
import {
|
|
167
168
|
parseSlackThreadId
|
|
168
|
-
} from "./chunk-
|
|
169
|
+
} from "./chunk-LINEEYW6.js";
|
|
169
170
|
import {
|
|
170
171
|
appendAndEnqueueInboundMessage
|
|
171
|
-
} from "./chunk-
|
|
172
|
+
} from "./chunk-BQFWG7MB.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-73RVLY6A.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-I7F3JVYE.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-FNAEGMGB.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-JYJG6LAG.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-VGNL3QUM.js";
|
|
258
259
|
import {
|
|
259
260
|
juniorArtifacts,
|
|
261
|
+
juniorAttachments,
|
|
260
262
|
juniorIdentities,
|
|
261
263
|
juniorSchedulerRuns
|
|
262
|
-
} from "./chunk-
|
|
264
|
+
} from "./chunk-UJRD4NN4.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-KKI5K43Z.js";
|
|
294
296
|
import {
|
|
295
297
|
fenceLock,
|
|
296
298
|
getStateAdapter,
|
|
297
299
|
withLock
|
|
298
|
-
} from "./chunk-
|
|
300
|
+
} from "./chunk-44W7JB5V.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-PJIU4AGA.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-QHCI2E2A.js";
|
|
351
353
|
import {
|
|
352
354
|
discoverSkills,
|
|
353
355
|
findSkillByName,
|
|
354
356
|
loadSkillsByName,
|
|
355
357
|
parseSkillInvocation
|
|
356
|
-
} from "./chunk-
|
|
358
|
+
} from "./chunk-7V4KWIXL.js";
|
|
357
359
|
import {
|
|
358
360
|
pluginCatalogRuntime
|
|
359
|
-
} from "./chunk-
|
|
361
|
+
} from "./chunk-Y6EUAX5O.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-H5SDC32F.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-SIMN6AUL.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,95 @@ 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 attachmentDir = path8.posix.join(ATTACHMENT_DIR, attachment.id);
|
|
13953
|
+
const sandboxPath = path8.posix.join(
|
|
13954
|
+
attachmentDir,
|
|
13955
|
+
path8.posix.basename(attachment.filename)
|
|
13956
|
+
);
|
|
13957
|
+
const mkdir = await args.workspace.runCommand({
|
|
13958
|
+
cmd: "mkdir",
|
|
13959
|
+
args: ["-p", attachmentDir]
|
|
13960
|
+
});
|
|
13961
|
+
if (mkdir.exitCode !== 0) {
|
|
13962
|
+
throw new Error(
|
|
13963
|
+
`Failed to create attachment directory: ${mkdir.stderr}`
|
|
13964
|
+
);
|
|
13965
|
+
}
|
|
13966
|
+
await args.workspace.writeFiles([
|
|
13967
|
+
{ content: await readStream(body), path: sandboxPath }
|
|
13968
|
+
]);
|
|
13969
|
+
return {
|
|
13970
|
+
path: sandboxPath,
|
|
13971
|
+
filename: attachment.filename,
|
|
13972
|
+
mime_type: attachment.contentType,
|
|
13973
|
+
bytes: attachment.bytes
|
|
13974
|
+
};
|
|
13975
|
+
}
|
|
13976
|
+
});
|
|
13977
|
+
}
|
|
13978
|
+
|
|
13979
|
+
// src/chat/tools/search-conversation-events.ts
|
|
13980
|
+
import { z as z59 } from "zod";
|
|
13848
13981
|
var DEFAULT_LIMIT3 = 25;
|
|
13849
13982
|
var MAX_LIMIT2 = 100;
|
|
13850
13983
|
var MAX_EVENT_DATA_BYTES = 4e3;
|
|
13851
13984
|
var MAX_EVENTS_JSON_BYTES = 2e4;
|
|
13852
13985
|
var MAX_IDENTITY_CHARS = 256;
|
|
13853
13986
|
var textEncoder = new TextEncoder();
|
|
13854
|
-
var knownEventTypeSchema =
|
|
13855
|
-
var projectedEventSchema =
|
|
13856
|
-
seq:
|
|
13857
|
-
history_version:
|
|
13858
|
-
created_at:
|
|
13859
|
-
idempotency_key:
|
|
13860
|
-
data:
|
|
13987
|
+
var knownEventTypeSchema = z59.enum(KNOWN_CONVERSATION_EVENT_TYPES);
|
|
13988
|
+
var projectedEventSchema = z59.object({
|
|
13989
|
+
seq: z59.number().int().nonnegative().describe("Stable event position for pagination."),
|
|
13990
|
+
history_version: z59.number().int().nonnegative().describe("Agent history generation after replacement."),
|
|
13991
|
+
created_at: z59.iso.datetime().describe("When the event was recorded."),
|
|
13992
|
+
idempotency_key: z59.string().min(1).optional().describe("Retry-stable event identity, when assigned."),
|
|
13993
|
+
data: z59.record(z59.string(), z59.unknown()).describe("Bounded event data.")
|
|
13861
13994
|
}).strict();
|
|
13862
13995
|
var searchConversationEventsOutputSchema = juniorToolOutputSchema.extend({
|
|
13863
|
-
conversation_id:
|
|
13864
|
-
events:
|
|
13865
|
-
has_older:
|
|
13866
|
-
has_newer:
|
|
13867
|
-
omitted_event_count:
|
|
13996
|
+
conversation_id: z59.string().min(1),
|
|
13997
|
+
events: z59.array(projectedEventSchema),
|
|
13998
|
+
has_older: z59.boolean().describe("Whether matching older events exist."),
|
|
13999
|
+
has_newer: z59.boolean().describe("Whether matching newer events exist."),
|
|
14000
|
+
omitted_event_count: z59.number().int().nonnegative().optional().describe("Events omitted by the response byte limit.")
|
|
13868
14001
|
});
|
|
13869
14002
|
function createSearchConversationEventsTool(context) {
|
|
13870
14003
|
return zodTool({
|
|
@@ -13877,16 +14010,16 @@ function createSearchConversationEventsTool(context) {
|
|
|
13877
14010
|
openWorldHint: false,
|
|
13878
14011
|
readOnlyHint: true
|
|
13879
14012
|
},
|
|
13880
|
-
inputSchema:
|
|
13881
|
-
conversation_id:
|
|
14013
|
+
inputSchema: z59.object({
|
|
14014
|
+
conversation_id: z59.string().trim().min(1).nullable().describe(
|
|
13882
14015
|
"Conversation ID to search. Omit or null for the current conversation."
|
|
13883
14016
|
).optional(),
|
|
13884
|
-
after_seq:
|
|
13885
|
-
before_seq:
|
|
13886
|
-
limit:
|
|
14017
|
+
after_seq: z59.number().int().nonnegative().nullable().describe("Exclusive event sequence lower bound; returns ascending.").optional(),
|
|
14018
|
+
before_seq: z59.number().int().nonnegative().nullable().describe("Exclusive event sequence upper bound.").optional(),
|
|
14019
|
+
limit: z59.number().int().min(1).max(MAX_LIMIT2).nullable().describe(
|
|
13887
14020
|
`Maximum events. Default ${DEFAULT_LIMIT3}; max ${MAX_LIMIT2}.`
|
|
13888
14021
|
).optional(),
|
|
13889
|
-
types:
|
|
14022
|
+
types: z59.array(knownEventTypeSchema).min(1).nullable().describe("Event types to include; omit for all types.").optional()
|
|
13890
14023
|
}).strict(),
|
|
13891
14024
|
outputSchema: searchConversationEventsOutputSchema,
|
|
13892
14025
|
execute: async (input) => {
|
|
@@ -14135,7 +14268,7 @@ function stripReplacementHistoryField(value) {
|
|
|
14135
14268
|
}
|
|
14136
14269
|
|
|
14137
14270
|
// src/chat/tools/handoff/tool.ts
|
|
14138
|
-
import { z as
|
|
14271
|
+
import { z as z60 } from "zod";
|
|
14139
14272
|
var HANDOFF_TOOL_NAME = "handoff";
|
|
14140
14273
|
function formatHandoffProfiles(handoff) {
|
|
14141
14274
|
return handoff.profiles.map(
|
|
@@ -14143,7 +14276,7 @@ function formatHandoffProfiles(handoff) {
|
|
|
14143
14276
|
).join("\n");
|
|
14144
14277
|
}
|
|
14145
14278
|
function createHandoffTool(handoff) {
|
|
14146
|
-
const profileSchema =
|
|
14279
|
+
const profileSchema = z60.enum(
|
|
14147
14280
|
handoff.profiles.map((profile) => profile.name)
|
|
14148
14281
|
);
|
|
14149
14282
|
const handoffResultSchema = juniorToolOutputSchema.extend({
|
|
@@ -14168,7 +14301,7 @@ function createHandoffTool(handoff) {
|
|
|
14168
14301
|
${profileList}`
|
|
14169
14302
|
].join(" "),
|
|
14170
14303
|
executionMode: "sequential",
|
|
14171
|
-
inputSchema:
|
|
14304
|
+
inputSchema: z60.object({
|
|
14172
14305
|
profile: profileSchema.describe(
|
|
14173
14306
|
"Exact configured profile name. Choose the profile whose description best fits the remaining task. If none clearly fits better, do not call handoff."
|
|
14174
14307
|
)
|
|
@@ -14191,7 +14324,7 @@ ${profileList}`
|
|
|
14191
14324
|
}
|
|
14192
14325
|
|
|
14193
14326
|
// src/chat/tools/web/fetch-tool.ts
|
|
14194
|
-
import { z as
|
|
14327
|
+
import { z as z61 } from "zod";
|
|
14195
14328
|
|
|
14196
14329
|
// src/chat/tools/web/constants.ts
|
|
14197
14330
|
var USER_AGENT = "junior-bot/0.1";
|
|
@@ -14640,9 +14773,9 @@ function createWebFetchTool(hooks, options = {}) {
|
|
|
14640
14773
|
openWorldHint: true,
|
|
14641
14774
|
readOnlyHint: true
|
|
14642
14775
|
},
|
|
14643
|
-
inputSchema:
|
|
14644
|
-
url:
|
|
14645
|
-
max_chars:
|
|
14776
|
+
inputSchema: z61.object({
|
|
14777
|
+
url: z61.string().min(1).describe("HTTP(S) URL to fetch."),
|
|
14778
|
+
max_chars: z61.coerce.number().int().min(500).max(MAX_FETCH_CHARS).describe("Optional maximum number of extracted characters to return.").optional()
|
|
14646
14779
|
}),
|
|
14647
14780
|
outputSchema: juniorToolOutputSchema,
|
|
14648
14781
|
execute: async ({ url, max_chars }) => {
|
|
@@ -14687,7 +14820,7 @@ function createWebFetchTool(hooks, options = {}) {
|
|
|
14687
14820
|
}
|
|
14688
14821
|
|
|
14689
14822
|
// src/chat/tools/web/search.ts
|
|
14690
|
-
import { z as
|
|
14823
|
+
import { z as z62 } from "zod";
|
|
14691
14824
|
import { generateText } from "ai";
|
|
14692
14825
|
import { createGatewayProvider } from "@ai-sdk/gateway";
|
|
14693
14826
|
var SEARCH_TIMEOUT_MS = 6e4;
|
|
@@ -14729,9 +14862,9 @@ function createWebSearchTool(modelId, override) {
|
|
|
14729
14862
|
openWorldHint: true,
|
|
14730
14863
|
readOnlyHint: true
|
|
14731
14864
|
},
|
|
14732
|
-
inputSchema:
|
|
14733
|
-
query:
|
|
14734
|
-
max_results:
|
|
14865
|
+
inputSchema: z62.object({
|
|
14866
|
+
query: z62.string().min(1).max(500).describe("Search query."),
|
|
14867
|
+
max_results: z62.coerce.number().int().min(1).max(MAX_RESULTS2).describe("Max results to return.").optional()
|
|
14735
14868
|
}),
|
|
14736
14869
|
outputSchema: juniorToolOutputSchema,
|
|
14737
14870
|
execute: async ({ query, max_results }) => {
|
|
@@ -14773,7 +14906,7 @@ function createWebSearchTool(modelId, override) {
|
|
|
14773
14906
|
}
|
|
14774
14907
|
|
|
14775
14908
|
// src/chat/tools/sandbox/write-file.ts
|
|
14776
|
-
import { z as
|
|
14909
|
+
import { z as z63 } from "zod";
|
|
14777
14910
|
function createWriteFileTool() {
|
|
14778
14911
|
return zodTool({
|
|
14779
14912
|
annotations: {
|
|
@@ -14784,9 +14917,9 @@ function createWriteFileTool() {
|
|
|
14784
14917
|
},
|
|
14785
14918
|
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
14919
|
executionMode: "sequential",
|
|
14787
|
-
inputSchema:
|
|
14788
|
-
path:
|
|
14789
|
-
content:
|
|
14920
|
+
inputSchema: z63.object({
|
|
14921
|
+
path: z63.string().min(1).describe("Path to write in the sandbox workspace."),
|
|
14922
|
+
content: z63.string().describe("UTF-8 file content to write.")
|
|
14790
14923
|
}),
|
|
14791
14924
|
outputSchema: juniorToolOutputSchema,
|
|
14792
14925
|
execute: async () => {
|
|
@@ -14798,7 +14931,7 @@ function createWriteFileTool() {
|
|
|
14798
14931
|
}
|
|
14799
14932
|
|
|
14800
14933
|
// src/chat/workspaces/tools.ts
|
|
14801
|
-
import { z as
|
|
14934
|
+
import { z as z64 } from "zod";
|
|
14802
14935
|
import {
|
|
14803
14936
|
resourceEventSubscriptionResultSchema
|
|
14804
14937
|
} from "@sentry/junior-plugin-api";
|
|
@@ -14830,16 +14963,16 @@ async function stopWorkspaceSnapshotWatch(input) {
|
|
|
14830
14963
|
});
|
|
14831
14964
|
}
|
|
14832
14965
|
}
|
|
14833
|
-
var repoSchema =
|
|
14834
|
-
provider:
|
|
14835
|
-
repo:
|
|
14836
|
-
checkout_path:
|
|
14966
|
+
var repoSchema = z64.object({
|
|
14967
|
+
provider: z64.string(),
|
|
14968
|
+
repo: z64.string(),
|
|
14969
|
+
checkout_path: z64.string()
|
|
14837
14970
|
});
|
|
14838
|
-
var workspaceSchema =
|
|
14839
|
-
id:
|
|
14840
|
-
name:
|
|
14841
|
-
setup_script:
|
|
14842
|
-
repos:
|
|
14971
|
+
var workspaceSchema = z64.object({
|
|
14972
|
+
id: z64.string(),
|
|
14973
|
+
name: z64.string(),
|
|
14974
|
+
setup_script: z64.string(),
|
|
14975
|
+
repos: z64.array(repoSchema)
|
|
14843
14976
|
});
|
|
14844
14977
|
function view(workspace) {
|
|
14845
14978
|
return {
|
|
@@ -14872,18 +15005,18 @@ function workspaceProviderNames() {
|
|
|
14872
15005
|
}
|
|
14873
15006
|
function workspaceWriteSchemas(providers) {
|
|
14874
15007
|
const providerNames = providers.map((provider) => `\`${provider}\``).join(", ");
|
|
14875
|
-
const repoInputSchema =
|
|
14876
|
-
provider:
|
|
14877
|
-
repo:
|
|
15008
|
+
const repoInputSchema = z64.object({
|
|
15009
|
+
provider: z64.enum(providers).describe(`Repository provider. Supported: ${providerNames}.`),
|
|
15010
|
+
repo: z64.string().trim().min(1).describe("Repository in owner/name format.")
|
|
14878
15011
|
}).strict();
|
|
14879
|
-
const workspaceInputSchema =
|
|
14880
|
-
name:
|
|
15012
|
+
const workspaceInputSchema = z64.object({
|
|
15013
|
+
name: z64.string().trim().min(1).describe(
|
|
14881
15014
|
"Workspace name. Use lowercase letters, digits, underscores, or hyphens."
|
|
14882
15015
|
),
|
|
14883
|
-
setup_script:
|
|
15016
|
+
setup_script: z64.string().nullable().describe(
|
|
14884
15017
|
"Optional shell script to run after repository checkout whenever this Workspace starts. Omit or use null for no setup script."
|
|
14885
15018
|
).optional(),
|
|
14886
|
-
repos:
|
|
15019
|
+
repos: z64.array(repoInputSchema).max(32).describe("Complete repository list.")
|
|
14887
15020
|
}).strict();
|
|
14888
15021
|
return { providerNames, workspaceInputSchema };
|
|
14889
15022
|
}
|
|
@@ -14958,7 +15091,7 @@ function createWorkspaceWriteTools(providers) {
|
|
|
14958
15091
|
},
|
|
14959
15092
|
description: `Replace an install-wide Workspace recipe. Repository providers: ${providerNames}. Use the Workspace ID returned by listWorkspaces.`,
|
|
14960
15093
|
inputSchema: workspaceInputSchema.extend({
|
|
14961
|
-
id:
|
|
15094
|
+
id: z64.string().uuid().describe("Workspace ID from listWorkspaces.")
|
|
14962
15095
|
}).strict(),
|
|
14963
15096
|
prepareArguments(args) {
|
|
14964
15097
|
const input = args;
|
|
@@ -14991,11 +15124,11 @@ function createWorkspaceWriteTools(providers) {
|
|
|
14991
15124
|
readOnlyHint: false
|
|
14992
15125
|
},
|
|
14993
15126
|
description: "Delete one install-wide Workspace recipe. Use the Workspace ID returned by listWorkspaces.",
|
|
14994
|
-
inputSchema:
|
|
14995
|
-
id:
|
|
15127
|
+
inputSchema: z64.object({
|
|
15128
|
+
id: z64.string().uuid().describe("Workspace ID from listWorkspaces.")
|
|
14996
15129
|
}).strict(),
|
|
14997
15130
|
outputSchema: juniorToolOutputSchema.extend({
|
|
14998
|
-
deleted:
|
|
15131
|
+
deleted: z64.literal(true)
|
|
14999
15132
|
}),
|
|
15000
15133
|
async execute({ id }) {
|
|
15001
15134
|
const deleted = await workspaceWrite(() => deleteWorkspace(id));
|
|
@@ -15020,10 +15153,10 @@ function createWorkspaceTools(context) {
|
|
|
15020
15153
|
readOnlyHint: true
|
|
15021
15154
|
},
|
|
15022
15155
|
description: "List named repository workspaces that can replace the current sandbox.",
|
|
15023
|
-
inputSchema:
|
|
15156
|
+
inputSchema: z64.object({}).strict(),
|
|
15024
15157
|
outputSchema: juniorToolOutputSchema.extend({
|
|
15025
|
-
active_workspace_id:
|
|
15026
|
-
workspaces:
|
|
15158
|
+
active_workspace_id: z64.string().nullable(),
|
|
15159
|
+
workspaces: z64.array(workspaceSchema)
|
|
15027
15160
|
}),
|
|
15028
15161
|
async execute() {
|
|
15029
15162
|
return {
|
|
@@ -15041,12 +15174,12 @@ function createWorkspaceTools(context) {
|
|
|
15041
15174
|
readOnlyHint: false
|
|
15042
15175
|
},
|
|
15043
15176
|
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:
|
|
15177
|
+
inputSchema: z64.object({
|
|
15178
|
+
name: z64.string().trim().min(1).describe("Exact workspace name.")
|
|
15046
15179
|
}).strict(),
|
|
15047
15180
|
outputSchema: juniorToolOutputSchema.extend({
|
|
15048
15181
|
workspace: workspaceSchema,
|
|
15049
|
-
status:
|
|
15182
|
+
status: z64.enum(["ready", "building"]),
|
|
15050
15183
|
subscription: resourceEventSubscriptionResultSchema.optional().describe(
|
|
15051
15184
|
"Present when the snapshot ready and failed events are already watched for this conversation."
|
|
15052
15185
|
)
|
|
@@ -15178,6 +15311,12 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
|
|
|
15178
15311
|
);
|
|
15179
15312
|
}
|
|
15180
15313
|
if (context.attachmentStorage) {
|
|
15314
|
+
tools.loadAttachment = createLoadAttachmentTool({
|
|
15315
|
+
conversationId: context.conversationId,
|
|
15316
|
+
db: getSqlExecutor(),
|
|
15317
|
+
storage: context.attachmentStorage,
|
|
15318
|
+
workspace: context.workspace
|
|
15319
|
+
});
|
|
15181
15320
|
tools.publishImage = createPublishImageTool({
|
|
15182
15321
|
conversationId: context.conversationId,
|
|
15183
15322
|
db: getSqlExecutor(),
|
|
@@ -15203,7 +15342,10 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
|
|
|
15203
15342
|
tools.slackCanvasRead = createSlackCanvasReadTool();
|
|
15204
15343
|
tools.slackCanvasEdit = createSlackCanvasEditTool(state);
|
|
15205
15344
|
tools.slackCanvasWrite = createSlackCanvasWriteTool(state);
|
|
15206
|
-
tools.slackThreadRead = createSlackThreadReadTool(slackContext
|
|
15345
|
+
tools.slackThreadRead = createSlackThreadReadTool(slackContext, {
|
|
15346
|
+
conversationId: context.conversationId,
|
|
15347
|
+
db: getSqlExecutor()
|
|
15348
|
+
});
|
|
15207
15349
|
tools.slackChannelJoin = createSlackChannelJoinTool(slackContext);
|
|
15208
15350
|
if (context.conversationPrivacy === "public") {
|
|
15209
15351
|
tools.searchConversationMessages = createSlackConversationMessageSearchTool(
|
|
@@ -15832,7 +15974,7 @@ function handleToolExecutionError(error, toolName, toolCallId, shouldTrace, conv
|
|
|
15832
15974
|
}
|
|
15833
15975
|
|
|
15834
15976
|
// src/chat/tools/execute-tool.ts
|
|
15835
|
-
import { z as
|
|
15977
|
+
import { z as z65 } from "zod";
|
|
15836
15978
|
var EXECUTE_TOOL_NAME = "executeTool";
|
|
15837
15979
|
function createExecuteToolTool() {
|
|
15838
15980
|
return zodTool({
|
|
@@ -15844,11 +15986,11 @@ function createExecuteToolTool() {
|
|
|
15844
15986
|
},
|
|
15845
15987
|
description: "Execute any catalog tool by exact tool_name from searchTools or a tool-result execution hint. Put tool-specific parameters inside arguments.",
|
|
15846
15988
|
executionMode: "sequential",
|
|
15847
|
-
inputSchema:
|
|
15848
|
-
tool_name:
|
|
15989
|
+
inputSchema: z65.object({
|
|
15990
|
+
tool_name: z65.string().min(1).describe(
|
|
15849
15991
|
"Exact catalog tool_name returned by searchTools or a tool-result execution hint."
|
|
15850
15992
|
),
|
|
15851
|
-
arguments:
|
|
15993
|
+
arguments: z65.record(z65.string(), z65.unknown()).describe(
|
|
15852
15994
|
'Arguments matching the selected catalog tool schema, for example { "query": "..." }.'
|
|
15853
15995
|
).optional()
|
|
15854
15996
|
}).strict(),
|
|
@@ -15888,7 +16030,7 @@ function planToolExposure(tools) {
|
|
|
15888
16030
|
}
|
|
15889
16031
|
|
|
15890
16032
|
// src/chat/tools/search-tools.ts
|
|
15891
|
-
import { z as
|
|
16033
|
+
import { z as z66 } from "zod";
|
|
15892
16034
|
var SEARCH_TOOLS_NAME = "searchTools";
|
|
15893
16035
|
var DEFAULT_MAX_RESULTS2 = 5;
|
|
15894
16036
|
var MAX_RESULTS3 = 20;
|
|
@@ -15933,29 +16075,29 @@ var SEARCH_STOP_WORDS = /* @__PURE__ */ new Set([
|
|
|
15933
16075
|
"you",
|
|
15934
16076
|
"your"
|
|
15935
16077
|
]);
|
|
15936
|
-
var searchToolsSourceSchema =
|
|
15937
|
-
id:
|
|
15938
|
-
description:
|
|
16078
|
+
var searchToolsSourceSchema = z66.object({
|
|
16079
|
+
id: z66.string(),
|
|
16080
|
+
description: z66.string()
|
|
15939
16081
|
}).strict();
|
|
15940
|
-
var searchToolsToolSchema =
|
|
15941
|
-
tool_name:
|
|
15942
|
-
description:
|
|
15943
|
-
exposure:
|
|
15944
|
-
source:
|
|
15945
|
-
input_schema:
|
|
15946
|
-
call_notes:
|
|
15947
|
-
annotations:
|
|
16082
|
+
var searchToolsToolSchema = z66.object({
|
|
16083
|
+
tool_name: z66.string(),
|
|
16084
|
+
description: z66.string(),
|
|
16085
|
+
exposure: z66.enum(["direct", "deferred", "modelOnly", "hidden"]),
|
|
16086
|
+
source: z66.string().optional(),
|
|
16087
|
+
input_schema: z66.unknown(),
|
|
16088
|
+
call_notes: z66.array(z66.string()),
|
|
16089
|
+
annotations: z66.record(z66.string(), z66.unknown())
|
|
15948
16090
|
}).strict();
|
|
15949
16091
|
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:
|
|
16092
|
+
query: z66.string().nullable(),
|
|
16093
|
+
source: z66.string().nullable(),
|
|
16094
|
+
sources: z66.array(searchToolsSourceSchema),
|
|
16095
|
+
total_catalog_tools: z66.number().int().nonnegative(),
|
|
16096
|
+
total_eligible_tools: z66.number().int().nonnegative(),
|
|
16097
|
+
total_matches: z66.number().int().nonnegative(),
|
|
16098
|
+
returned_tools: z66.number().int().nonnegative(),
|
|
16099
|
+
execution_tool: z66.literal("executeTool"),
|
|
16100
|
+
tools: z66.array(searchToolsToolSchema)
|
|
15959
16101
|
}).strict();
|
|
15960
16102
|
function terms(value) {
|
|
15961
16103
|
const chunks = value.match(/[\p{L}\p{N}]+/gu) ?? [];
|
|
@@ -16166,14 +16308,14 @@ function createSearchToolsTool(catalogTools) {
|
|
|
16166
16308
|
openWorldHint: false,
|
|
16167
16309
|
readOnlyHint: true
|
|
16168
16310
|
},
|
|
16169
|
-
inputSchema:
|
|
16170
|
-
query:
|
|
16311
|
+
inputSchema: z66.object({
|
|
16312
|
+
query: z66.string().nullable().describe(
|
|
16171
16313
|
"Optional search terms describing the tool, owner, action, or arguments needed. Empty string lists catalog tools."
|
|
16172
16314
|
).optional(),
|
|
16173
|
-
source:
|
|
16315
|
+
source: z66.string().nullable().describe(
|
|
16174
16316
|
"Optional source id to search within, such as a plugin source returned in sources."
|
|
16175
16317
|
).optional(),
|
|
16176
|
-
max_results:
|
|
16318
|
+
max_results: z66.number().int().min(1).max(MAX_RESULTS3).nullable().describe("Maximum matching catalog tool descriptors to return.").optional()
|
|
16177
16319
|
}).strict(),
|
|
16178
16320
|
outputSchema: searchToolsOutputSchema,
|
|
16179
16321
|
privateTraceResult: (result) => ({
|
|
@@ -17471,7 +17613,7 @@ function createPluginEgress(deps) {
|
|
|
17471
17613
|
}
|
|
17472
17614
|
|
|
17473
17615
|
// src/chat/services/guardian-action-review.ts
|
|
17474
|
-
import { z as
|
|
17616
|
+
import { z as z67 } from "zod";
|
|
17475
17617
|
|
|
17476
17618
|
// src/chat/services/guardian-action-policy.ts
|
|
17477
17619
|
var GUARDIAN_ACTION_POLICY = `You are judging one planned Junior agent action.
|
|
@@ -17545,17 +17687,17 @@ Assess the exact action's intrinsic risk and whether the user's intent authorize
|
|
|
17545
17687
|
- 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
17688
|
|
|
17547
17689
|
// src/chat/services/guardian-action-review.ts
|
|
17548
|
-
var guardianDecisionSchema =
|
|
17549
|
-
decision:
|
|
17550
|
-
reason:
|
|
17551
|
-
riskLevel:
|
|
17552
|
-
userAuthorization:
|
|
17690
|
+
var guardianDecisionSchema = z67.object({
|
|
17691
|
+
decision: z67.enum(["allow", "ask", "deny"]),
|
|
17692
|
+
reason: z67.string().trim().min(1).max(500),
|
|
17693
|
+
riskLevel: z67.enum(["low", "medium", "high", "critical"]),
|
|
17694
|
+
userAuthorization: z67.enum(["high", "medium", "low", "unknown"])
|
|
17553
17695
|
}).strict();
|
|
17554
17696
|
var GUARDIAN_REVIEW_TIMEOUT_MS = 6e4;
|
|
17555
17697
|
var GUARDIAN_REVIEW_MAX_TOKENS = 2e3;
|
|
17556
17698
|
var MAX_PROPOSAL_CHARS = 192e3;
|
|
17557
17699
|
function guardianPrompt(proposal) {
|
|
17558
|
-
const proposalJson = JSON.stringify(
|
|
17700
|
+
const proposalJson = JSON.stringify(z67.json().parse(proposal), null, 2);
|
|
17559
17701
|
if (proposalJson.length > MAX_PROPOSAL_CHARS) {
|
|
17560
17702
|
throw new Error(
|
|
17561
17703
|
`Guardian action proposal exceeds ${MAX_PROPOSAL_CHARS} characters.`
|
|
@@ -20245,6 +20387,7 @@ export {
|
|
|
20245
20387
|
setConfigDefaults,
|
|
20246
20388
|
getConfigDefaults,
|
|
20247
20389
|
shouldEmitDevAgentTrace,
|
|
20390
|
+
isVisionImageMediaType,
|
|
20248
20391
|
buildSteeringPiMessage,
|
|
20249
20392
|
SANDBOX_EGRESS_PROXY_PATH,
|
|
20250
20393
|
parseSandboxEgressCredentialToken,
|
|
@@ -20269,6 +20412,8 @@ export {
|
|
|
20269
20412
|
listThreadReplies,
|
|
20270
20413
|
renderBlockText,
|
|
20271
20414
|
renderAttachmentText,
|
|
20415
|
+
recordSlackAttachment,
|
|
20416
|
+
readAttachmentVisionSummary,
|
|
20272
20417
|
readPublicArtifact,
|
|
20273
20418
|
publicArtifactHeaders,
|
|
20274
20419
|
unpublishedArtifactHeaders,
|