@sentry/junior 0.161.0 → 0.163.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/README.md +2 -0
- package/dist/{agent-hooks-O75UJNC6.js → agent-hooks-6IX5CV7G.js} +10 -10
- package/dist/api/acp/route.d.ts +13 -0
- package/dist/api/locations/detail.d.ts +1 -1
- package/dist/api/schema/conversation.d.ts +3 -0
- package/dist/api/schema/location.d.ts +1 -0
- package/dist/api/schema/person.d.ts +1 -0
- package/dist/api.js +204 -403
- package/dist/app.d.ts +2 -2
- package/dist/app.js +480 -38
- package/dist/{catalog-runtime-Z3FHU4ZY.js → catalog-runtime-NEPZNTOM.js} +5 -5
- package/dist/chat/agent/sandbox.d.ts +4 -0
- package/dist/chat/api-turns/cancellation.d.ts +27 -0
- package/dist/chat/api-turns/routing.d.ts +31 -0
- package/dist/chat/api-turns/work.d.ts +12 -29
- package/dist/chat/app/conversation-work.d.ts +6 -1
- package/dist/chat/app/production.d.ts +2 -2
- package/dist/chat/conversations/history.d.ts +3 -0
- package/dist/chat/conversations/message-search.d.ts +6 -0
- package/dist/chat/conversations/turn-lifecycle.d.ts +1 -1
- package/dist/chat/experimental.d.ts +1 -1
- package/dist/chat/plugins/agent-hooks.d.ts +4 -0
- package/dist/chat/repository-instructions.d.ts +1 -1
- package/dist/chat/sandbox/paths.d.ts +1 -0
- package/dist/chat/sandbox/prepare-workspace.d.ts +11 -0
- package/dist/chat/sandbox/ref.d.ts +1 -0
- package/dist/chat/sandbox/sandbox.d.ts +4 -0
- package/dist/chat/sandbox/session.d.ts +4 -0
- package/dist/chat/sandbox/snapshot/profile.d.ts +4 -3
- package/dist/chat/sandbox/snapshot/resolve.d.ts +4 -0
- package/dist/chat/sandbox/workspace.d.ts +4 -0
- package/dist/chat/slack/tools/conversation-message-search.d.ts +9 -0
- package/dist/chat/tools/types.d.ts +5 -0
- package/dist/chat/workspaces/checkout-path.d.ts +4 -0
- package/dist/chat/workspaces/store.d.ts +8 -0
- package/dist/chat/workspaces/tools.d.ts +4 -0
- package/dist/chat/workspaces/types.d.ts +13 -0
- package/dist/{chunk-WKN4ZQTZ.js → chunk-2FBPN2Y4.js} +4 -1
- package/dist/{chunk-QHXT7LLF.js → chunk-2HBJQEBE.js} +1 -1
- package/dist/{chunk-VXFDVY4C.js → chunk-3OZNFCPR.js} +6 -6
- package/dist/{chunk-EAIQBR66.js → chunk-3T7RJVDJ.js} +1 -1
- package/dist/{chunk-DGKLYDX7.js → chunk-4P2XNVTO.js} +2 -2
- package/dist/{chunk-FLMD25Y5.js → chunk-ATWHPSMF.js} +40 -2
- package/dist/{chunk-IRHX2S46.js → chunk-BLZUFHM7.js} +1 -1
- package/dist/chunk-BVREIWBD.js +131 -0
- package/dist/{chunk-QQ7SY5IZ.js → chunk-EKGJVUVS.js} +9 -6
- package/dist/{chunk-ZBCLWBMV.js → chunk-FEIHINKR.js} +5 -5
- package/dist/{chunk-MVG5UPLM.js → chunk-GCLHNRMU.js} +1 -1
- package/dist/{chunk-YSWHAOPQ.js → chunk-ICJ3KCA2.js} +1 -1
- package/dist/{chunk-G35DUPNB.js → chunk-IIT23D3M.js} +4 -4
- package/dist/{chunk-OYQEO72I.js → chunk-IX4XI42N.js} +417 -136
- package/dist/{chunk-U2XOBFDK.js → chunk-JI5EPI3O.js} +50 -5
- package/dist/{chunk-IW7C5C7E.js → chunk-KD3ROG6P.js} +17 -17
- package/dist/{chunk-4WAZ6DGX.js → chunk-MWVQ35U6.js} +543 -164
- package/dist/{chunk-STZVUVMS.js → chunk-MXFL7LNZ.js} +12 -7
- package/dist/{chunk-HSFYTIS2.js → chunk-NL53P7PS.js} +1 -1
- package/dist/{chunk-6WTDZKFR.js → chunk-O4IK4O7C.js} +1 -1
- package/dist/{chunk-OPIJ6HY3.js → chunk-O5ZZL7IR.js} +9 -9
- package/dist/{chunk-CGAIDDLD.js → chunk-RK7KPI6G.js} +1 -1
- package/dist/{chunk-V67ORYKQ.js → chunk-RTPJRLOP.js} +9 -9
- package/dist/{chunk-6ILVZOF6.js → chunk-SR6WRBJW.js} +4 -4
- package/dist/{chunk-RULQD7OX.js → chunk-THS4CKN4.js} +46 -87
- package/dist/{chunk-IYFKONIL.js → chunk-TPDNZCZU.js} +1 -1
- package/dist/{chunk-DNSIU27S.js → chunk-TPT6EF7K.js} +1 -1
- package/dist/{chunk-5IDFPCON.js → chunk-VRS6WDK5.js} +1 -1
- package/dist/{chunk-O7JTSJPU.js → chunk-WPGYWDJR.js} +6 -6
- package/dist/{chunk-OY2DBUV4.js → chunk-XY2IVIAY.js} +5 -5
- package/dist/{chunk-RVENVPNO.js → chunk-YAUQXZVT.js} +2 -2
- package/dist/{chunk-WVSQ2SCS.js → chunk-ZDKTZG3G.js} +1 -1
- package/dist/{chunk-MNY5M7RB.js → chunk-ZF6IC27P.js} +87 -10
- package/dist/cli/chat.js +32 -32
- package/dist/cli/check.js +6 -6
- package/dist/cli/plugins.js +13 -13
- package/dist/cli/snapshot-create.js +10 -10
- package/dist/cli/upgrade.js +7 -7
- package/dist/db/schema/workspaces.d.ts +169 -0
- package/dist/db/schema.d.ts +169 -1
- package/dist/{db-KKOZRE62.js → db-6VBMHVW2.js} +7 -7
- package/dist/{experimental-HH6OM6UH.js → experimental-XVDOSRBS.js} +1 -1
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-5AUZDWXA.js → oauth-callback-server-5NCCUIM2.js} +24 -24
- package/dist/{runner-K5H5NDEC.js → runner-6ONEB6TQ.js} +13 -13
- package/dist/{skills-OZGPB6G4.js → skills-Y5R36UH4.js} +6 -6
- package/dist/spawn-RFMBQ6B3.js +37 -0
- package/dist/{validation-TVHCNCYL.js → validation-HLHEQDEK.js} +6 -6
- package/dist/version.js +1 -1
- package/dist/{work-DXCQMJ5U.js → work-VIEFYTFG.js} +18 -18
- package/dist/worker-MRSKPKQZ.js +24 -0
- package/migrations/0029_dizzy_barracuda.sql +19 -0
- package/migrations/meta/0029_snapshot.json +2709 -0
- package/migrations/meta/_journal.json +8 -1
- package/package.json +8 -5
- package/dist/chunk-EM225ITJ.js +0 -56
- package/dist/spawn-RCQSC2L5.js +0 -37
- package/dist/worker-24HZ5HRI.js +0 -24
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
PluginCredentialFailureError,
|
|
8
8
|
agentNameSchema,
|
|
9
9
|
createPluginAuthOrchestration
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-XY2IVIAY.js";
|
|
11
11
|
import {
|
|
12
12
|
authorizationId
|
|
13
13
|
} from "./chunk-DIB4GX3G.js";
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
searchSlackUsers,
|
|
33
33
|
selectPluginGrant,
|
|
34
34
|
toMcpProviderError
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-RTPJRLOP.js";
|
|
36
36
|
import {
|
|
37
37
|
RetryableDeliveryError,
|
|
38
38
|
actorFromRun,
|
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
getSlackMessagePermalink,
|
|
49
49
|
resolveBaseUrl,
|
|
50
50
|
uploadFilesToConversation
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-3OZNFCPR.js";
|
|
52
52
|
import {
|
|
53
53
|
parseSandboxEgressAuthRequiredSignal,
|
|
54
54
|
parseSandboxEgressPermissionDeniedSignal,
|
|
@@ -57,8 +57,6 @@ import {
|
|
|
57
57
|
} from "./chunk-7MA4HV4W.js";
|
|
58
58
|
import {
|
|
59
59
|
bindSandboxFileSystem,
|
|
60
|
-
buildCommandScript,
|
|
61
|
-
buildNonInteractiveShellScript,
|
|
62
60
|
createSandboxSession,
|
|
63
61
|
ensureDockerDaemon,
|
|
64
62
|
getSandboxResources,
|
|
@@ -71,10 +69,10 @@ import {
|
|
|
71
69
|
isSandboxUnavailableError,
|
|
72
70
|
isSnapshottingError,
|
|
73
71
|
resolve,
|
|
74
|
-
|
|
72
|
+
stopSession,
|
|
75
73
|
throwSandboxOperationError,
|
|
76
74
|
wrapSandboxSetupError
|
|
77
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-THS4CKN4.js";
|
|
78
76
|
import {
|
|
79
77
|
SCHEDULED_TASK_SYSTEM_ACTOR,
|
|
80
78
|
compactEventTask,
|
|
@@ -107,10 +105,10 @@ import {
|
|
|
107
105
|
scheduledTaskAttributes,
|
|
108
106
|
storeAttachments,
|
|
109
107
|
writableEventTask
|
|
110
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-FEIHINKR.js";
|
|
111
109
|
import {
|
|
112
110
|
parseSlackThreadId
|
|
113
|
-
} from "./chunk-
|
|
111
|
+
} from "./chunk-ICJ3KCA2.js";
|
|
114
112
|
import {
|
|
115
113
|
AGENTS_REMOVAL_NOTICE,
|
|
116
114
|
AGENTS_REPLACEMENT_NOTICE,
|
|
@@ -181,7 +179,7 @@ import {
|
|
|
181
179
|
stripRuntimeTurnContext,
|
|
182
180
|
trimTrailingAssistantMessages,
|
|
183
181
|
truncateText
|
|
184
|
-
} from "./chunk-
|
|
182
|
+
} from "./chunk-MXFL7LNZ.js";
|
|
185
183
|
import {
|
|
186
184
|
JUNIOR_THREAD_STATE_TTL_MS
|
|
187
185
|
} from "./chunk-3Y47VMHV.js";
|
|
@@ -203,8 +201,10 @@ import {
|
|
|
203
201
|
normalizeSlackConversationId,
|
|
204
202
|
readActorIdentity,
|
|
205
203
|
resolveChannelCapabilities,
|
|
206
|
-
|
|
207
|
-
|
|
204
|
+
tryWorkspaceRepoCheckoutPath,
|
|
205
|
+
withSlackRetries,
|
|
206
|
+
workspaceRepoCheckoutPath
|
|
207
|
+
} from "./chunk-ZF6IC27P.js";
|
|
208
208
|
import {
|
|
209
209
|
KNOWN_CONVERSATION_EVENT_TYPES,
|
|
210
210
|
contextProvenance,
|
|
@@ -216,23 +216,29 @@ import {
|
|
|
216
216
|
instructionActors,
|
|
217
217
|
instructionProvenanceFor,
|
|
218
218
|
sameActorIdentity
|
|
219
|
-
} from "./chunk-
|
|
219
|
+
} from "./chunk-JI5EPI3O.js";
|
|
220
220
|
import {
|
|
221
221
|
juniorArtifacts,
|
|
222
|
-
juniorIdentities
|
|
223
|
-
|
|
222
|
+
juniorIdentities,
|
|
223
|
+
juniorWorkspaceRepos,
|
|
224
|
+
juniorWorkspaces
|
|
225
|
+
} from "./chunk-ATWHPSMF.js";
|
|
224
226
|
import {
|
|
225
227
|
SANDBOX_DATA_ROOT,
|
|
228
|
+
SANDBOX_REPOS_ROOT,
|
|
226
229
|
SANDBOX_SKILLS_ROOT,
|
|
227
230
|
SANDBOX_WORKSPACE_ROOT,
|
|
231
|
+
buildCommandScript,
|
|
232
|
+
buildNonInteractiveShellScript,
|
|
233
|
+
runNonInteractiveCommand,
|
|
228
234
|
sandboxSkillDir,
|
|
229
235
|
sandboxSkillFile,
|
|
230
236
|
sandboxSkillPathResolution,
|
|
231
237
|
sleep
|
|
232
|
-
} from "./chunk-
|
|
238
|
+
} from "./chunk-BVREIWBD.js";
|
|
233
239
|
import {
|
|
234
240
|
getStateAdapter
|
|
235
|
-
} from "./chunk-
|
|
241
|
+
} from "./chunk-TPDNZCZU.js";
|
|
236
242
|
import {
|
|
237
243
|
ACTIVE_TURN_COMPACTION_SUMMARY_PREFIX,
|
|
238
244
|
COMPACTION_SUMMARY_PREFIX,
|
|
@@ -265,7 +271,7 @@ import {
|
|
|
265
271
|
resolveGatewayCredential,
|
|
266
272
|
resolveGatewayModel,
|
|
267
273
|
unwrapCurrentInstruction
|
|
268
|
-
} from "./chunk-
|
|
274
|
+
} from "./chunk-YAUQXZVT.js";
|
|
269
275
|
import {
|
|
270
276
|
canExposeConversationPayload,
|
|
271
277
|
resolveConversationPrivacy,
|
|
@@ -275,16 +281,16 @@ import {
|
|
|
275
281
|
toGenAiMessagesTraceAttributes,
|
|
276
282
|
toGenAiPayloadMetadata,
|
|
277
283
|
toGenAiPayloadTraceAttributes
|
|
278
|
-
} from "./chunk-
|
|
284
|
+
} from "./chunk-3T7RJVDJ.js";
|
|
279
285
|
import {
|
|
280
286
|
discoverSkills,
|
|
281
287
|
findSkillByName,
|
|
282
288
|
loadSkillsByName,
|
|
283
289
|
parseSkillInvocation
|
|
284
|
-
} from "./chunk-
|
|
290
|
+
} from "./chunk-4P2XNVTO.js";
|
|
285
291
|
import {
|
|
286
292
|
pluginCatalogRuntime
|
|
287
|
-
} from "./chunk-
|
|
293
|
+
} from "./chunk-RK7KPI6G.js";
|
|
288
294
|
import {
|
|
289
295
|
CredentialUnavailableError,
|
|
290
296
|
OAuthProviderError,
|
|
@@ -292,7 +298,7 @@ import {
|
|
|
292
298
|
getOAuthProviderErrorAttributes,
|
|
293
299
|
resolveAuthTokenPlaceholder,
|
|
294
300
|
resolvePluginCommandEnv
|
|
295
|
-
} from "./chunk-
|
|
301
|
+
} from "./chunk-O4IK4O7C.js";
|
|
296
302
|
import {
|
|
297
303
|
credentialUserSubjectId
|
|
298
304
|
} from "./chunk-BDUENQD3.js";
|
|
@@ -320,7 +326,7 @@ import {
|
|
|
320
326
|
summarizeMessageText,
|
|
321
327
|
withLogContext,
|
|
322
328
|
withSpan
|
|
323
|
-
} from "./chunk-
|
|
329
|
+
} from "./chunk-TPT6EF7K.js";
|
|
324
330
|
import {
|
|
325
331
|
startInactiveSpan,
|
|
326
332
|
withActiveSpan
|
|
@@ -2935,6 +2941,33 @@ async function resolveSandboxCommandEnvironment() {
|
|
|
2935
2941
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
2936
2942
|
import { Sandbox } from "@vercel/sandbox";
|
|
2937
2943
|
|
|
2944
|
+
// src/chat/sandbox/prepare-workspace.ts
|
|
2945
|
+
async function prepareWorkspaceSnapshot(params) {
|
|
2946
|
+
const { sandbox, workspace, signal } = params;
|
|
2947
|
+
signal?.throwIfAborted();
|
|
2948
|
+
await params.applyNetworkPolicy(sandbox);
|
|
2949
|
+
await params.prepareRepositories?.(sandbox, workspace, signal);
|
|
2950
|
+
if (params.removeCredentialRoute) {
|
|
2951
|
+
await sandbox.update({ networkPolicy: "allow-all" });
|
|
2952
|
+
}
|
|
2953
|
+
if (!workspace.setupScript.trim()) return;
|
|
2954
|
+
const result = await sandbox.runCommand({
|
|
2955
|
+
cmd: "bash",
|
|
2956
|
+
args: ["-euo", "pipefail", "-c", workspace.setupScript],
|
|
2957
|
+
cwd: SANDBOX_WORKSPACE_ROOT,
|
|
2958
|
+
env: {
|
|
2959
|
+
JUNIOR_REPOS_ROOT: SANDBOX_REPOS_ROOT,
|
|
2960
|
+
JUNIOR_WORKSPACE_ROOT: SANDBOX_WORKSPACE_ROOT
|
|
2961
|
+
},
|
|
2962
|
+
signal
|
|
2963
|
+
});
|
|
2964
|
+
if (result.exitCode !== 0) {
|
|
2965
|
+
throw new Error(
|
|
2966
|
+
`Workspace setup failed: ${result.stderr.trim() || `exit ${result.exitCode}`}`
|
|
2967
|
+
);
|
|
2968
|
+
}
|
|
2969
|
+
}
|
|
2970
|
+
|
|
2938
2971
|
// src/chat/sandbox/skill-sync.ts
|
|
2939
2972
|
import fs3 from "fs/promises";
|
|
2940
2973
|
import path3 from "path";
|
|
@@ -3130,9 +3163,7 @@ var SANDBOX_NAME_PREFIX = "junior-";
|
|
|
3130
3163
|
var MAX_KEEPALIVE_INTERVAL_MS = 3e4;
|
|
3131
3164
|
var MIN_KEEPALIVE_INTERVAL_MS = 1e3;
|
|
3132
3165
|
function sandboxFetchOptions(signal) {
|
|
3133
|
-
if (!signal) {
|
|
3134
|
-
return {};
|
|
3135
|
-
}
|
|
3166
|
+
if (!signal) return {};
|
|
3136
3167
|
return {
|
|
3137
3168
|
fetch: (input, init) => {
|
|
3138
3169
|
const requestSignal = init?.signal ?? (input instanceof Request ? input.signal : void 0);
|
|
@@ -3144,14 +3175,11 @@ function sandboxFetchOptions(signal) {
|
|
|
3144
3175
|
};
|
|
3145
3176
|
}
|
|
3146
3177
|
function truncateOutput(output, maxLength) {
|
|
3147
|
-
if (output.length <= maxLength) {
|
|
3148
|
-
return { value: output, truncated: false };
|
|
3149
|
-
}
|
|
3150
|
-
const truncatedLength = output.length - maxLength;
|
|
3178
|
+
if (output.length <= maxLength) return { value: output, truncated: false };
|
|
3151
3179
|
return {
|
|
3152
3180
|
value: `${output.slice(0, maxLength)}
|
|
3153
3181
|
|
|
3154
|
-
[output truncated: ${
|
|
3182
|
+
[output truncated: ${output.length - maxLength} characters removed]`,
|
|
3155
3183
|
truncated: true
|
|
3156
3184
|
};
|
|
3157
3185
|
}
|
|
@@ -3183,13 +3211,12 @@ function createSandboxRuntime(options) {
|
|
|
3183
3211
|
let closed = false;
|
|
3184
3212
|
const timeoutMs = options.timeoutMs ?? 1e3 * 60 * 30;
|
|
3185
3213
|
const traceContext = options.traceContext ?? {};
|
|
3186
|
-
|
|
3214
|
+
let activeWorkspace = options.workspace;
|
|
3215
|
+
let dependencyProfileHash = hash(SANDBOX_RUNTIME, activeWorkspace);
|
|
3187
3216
|
const resolveCommandEnv = options.commandEnv ?? (async () => ({}));
|
|
3188
3217
|
const withSandboxSpan = (name, op, attributes, callback) => withSpan(name, op, traceContext, callback, attributes);
|
|
3189
3218
|
const invalidateSession = (sessionId) => {
|
|
3190
|
-
if (sessionId && activeSandbox
|
|
3191
|
-
return;
|
|
3192
|
-
}
|
|
3219
|
+
if (sessionId && activeSandbox?.session.sessionId !== sessionId) return;
|
|
3193
3220
|
activeSandbox = null;
|
|
3194
3221
|
if (keepAliveTimer) {
|
|
3195
3222
|
clearTimeout(keepAliveTimer);
|
|
@@ -3200,21 +3227,21 @@ function createSandboxRuntime(options) {
|
|
|
3200
3227
|
onUnavailable: invalidateSession
|
|
3201
3228
|
});
|
|
3202
3229
|
const createSandboxName = () => `${SANDBOX_NAME_PREFIX}${randomUUID2()}`;
|
|
3203
|
-
const preflightNetworkPolicy = (sandboxName) =>
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
const nextRef = {
|
|
3208
|
-
id: nextSandbox.sandboxId,
|
|
3209
|
-
...dependencyProfileHash ? { profileHash: dependencyProfileHash } : {}
|
|
3210
|
-
};
|
|
3211
|
-
sandboxRef = nextRef;
|
|
3212
|
-
if (reportedSandboxRef?.id === nextRef.id && reportedSandboxRef.profileHash === nextRef.profileHash) {
|
|
3230
|
+
const preflightNetworkPolicy = (sandboxName) => options.createNetworkPolicy?.(sandboxName);
|
|
3231
|
+
const persistSandboxRef = async (nextRef) => {
|
|
3232
|
+
if (reportedSandboxRef?.id === nextRef.id && reportedSandboxRef.profileHash === nextRef.profileHash && reportedSandboxRef.workspaceId === nextRef.workspaceId) {
|
|
3233
|
+
sandboxRef = nextRef;
|
|
3213
3234
|
return;
|
|
3214
3235
|
}
|
|
3215
3236
|
await options.onSandboxRefChanged?.(nextRef);
|
|
3237
|
+
sandboxRef = nextRef;
|
|
3216
3238
|
reportedSandboxRef = nextRef;
|
|
3217
3239
|
};
|
|
3240
|
+
const sandboxReference = (session, workspace, hash2) => ({
|
|
3241
|
+
id: session.sandboxId,
|
|
3242
|
+
...hash2 ? { profileHash: hash2 } : {},
|
|
3243
|
+
...workspace?.id ? { workspaceId: workspace.id } : {}
|
|
3244
|
+
});
|
|
3218
3245
|
const rememberSandbox = (nextSandbox, networkPolicyKey) => {
|
|
3219
3246
|
activeSandbox = { session: nextSandbox, networkPolicyKey };
|
|
3220
3247
|
return nextSandbox;
|
|
@@ -3327,7 +3354,15 @@ function createSandboxRuntime(options) {
|
|
|
3327
3354
|
});
|
|
3328
3355
|
};
|
|
3329
3356
|
const createSandboxFromResolvedSnapshot = async (params) => {
|
|
3330
|
-
const {
|
|
3357
|
+
const {
|
|
3358
|
+
runtime,
|
|
3359
|
+
snapshot,
|
|
3360
|
+
sandboxCredentials,
|
|
3361
|
+
sandboxName,
|
|
3362
|
+
signal,
|
|
3363
|
+
workspace,
|
|
3364
|
+
prepareWorkspace
|
|
3365
|
+
} = params;
|
|
3331
3366
|
signal?.throwIfAborted();
|
|
3332
3367
|
if (!snapshot.snapshotId) {
|
|
3333
3368
|
const networkPolicy = preflightNetworkPolicy(sandboxName);
|
|
@@ -3362,7 +3397,9 @@ function createSandboxRuntime(options) {
|
|
|
3362
3397
|
timeoutMs,
|
|
3363
3398
|
forceRebuild: true,
|
|
3364
3399
|
staleSnapshotId: snapshot.snapshotId,
|
|
3365
|
-
signal
|
|
3400
|
+
signal,
|
|
3401
|
+
workspace,
|
|
3402
|
+
prepareWorkspace
|
|
3366
3403
|
});
|
|
3367
3404
|
if (!rebuiltSnapshot.snapshotId) {
|
|
3368
3405
|
throw error;
|
|
@@ -3376,10 +3413,18 @@ function createSandboxRuntime(options) {
|
|
|
3376
3413
|
);
|
|
3377
3414
|
}
|
|
3378
3415
|
};
|
|
3379
|
-
const
|
|
3416
|
+
const createSandboxCandidate = async (workspace, hash2, signal) => {
|
|
3380
3417
|
const runtime = SANDBOX_RUNTIME;
|
|
3381
3418
|
const sandboxCredentials = getVercelSandboxCredentials();
|
|
3382
3419
|
const sandboxName = createSandboxName();
|
|
3420
|
+
const prepareWorkspace = workspace ? async (sandbox) => await prepareWorkspaceSnapshot({
|
|
3421
|
+
sandbox,
|
|
3422
|
+
workspace,
|
|
3423
|
+
signal,
|
|
3424
|
+
applyNetworkPolicy,
|
|
3425
|
+
prepareRepositories: options.onWorkspacePrepare,
|
|
3426
|
+
removeCredentialRoute: Boolean(options.createNetworkPolicy)
|
|
3427
|
+
}) : void 0;
|
|
3383
3428
|
let createdSandbox;
|
|
3384
3429
|
try {
|
|
3385
3430
|
createdSandbox = await withSandboxSpan(
|
|
@@ -3394,7 +3439,9 @@ function createSandboxRuntime(options) {
|
|
|
3394
3439
|
const snapshot = await resolve({
|
|
3395
3440
|
runtime,
|
|
3396
3441
|
timeoutMs,
|
|
3397
|
-
signal
|
|
3442
|
+
signal,
|
|
3443
|
+
workspace,
|
|
3444
|
+
prepareWorkspace
|
|
3398
3445
|
});
|
|
3399
3446
|
signal?.throwIfAborted();
|
|
3400
3447
|
setSnapshotAttributes(snapshot);
|
|
@@ -3403,47 +3450,74 @@ function createSandboxRuntime(options) {
|
|
|
3403
3450
|
snapshot,
|
|
3404
3451
|
sandboxCredentials,
|
|
3405
3452
|
sandboxName,
|
|
3406
|
-
signal
|
|
3453
|
+
signal,
|
|
3454
|
+
workspace,
|
|
3455
|
+
prepareWorkspace
|
|
3407
3456
|
});
|
|
3408
3457
|
}
|
|
3409
3458
|
);
|
|
3410
3459
|
} catch (error) {
|
|
3411
3460
|
return failSetup(error);
|
|
3412
3461
|
}
|
|
3413
|
-
|
|
3462
|
+
const ref = sandboxReference(createdSandbox, workspace, hash2);
|
|
3463
|
+
if (!workspace) {
|
|
3464
|
+
try {
|
|
3465
|
+
await persistSandboxRef(ref);
|
|
3466
|
+
} catch (error) {
|
|
3467
|
+
await stopSession(createdSandbox);
|
|
3468
|
+
throw error;
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3414
3471
|
let networkPolicyKey;
|
|
3415
3472
|
try {
|
|
3416
3473
|
networkPolicyKey = await applyNetworkPolicy(createdSandbox);
|
|
3417
3474
|
await prepareSandbox(createdSandbox);
|
|
3418
3475
|
} catch (error) {
|
|
3476
|
+
if (workspace) await stopSession(createdSandbox);
|
|
3419
3477
|
return failSetup(error);
|
|
3420
3478
|
}
|
|
3421
|
-
return
|
|
3479
|
+
return {
|
|
3480
|
+
session: createdSandbox,
|
|
3481
|
+
networkPolicyKey,
|
|
3482
|
+
profileHash: hash2,
|
|
3483
|
+
ref,
|
|
3484
|
+
workspace
|
|
3485
|
+
};
|
|
3486
|
+
};
|
|
3487
|
+
const createFreshSandbox = async (signal) => {
|
|
3488
|
+
const candidate = await createSandboxCandidate(
|
|
3489
|
+
activeWorkspace,
|
|
3490
|
+
dependencyProfileHash,
|
|
3491
|
+
signal
|
|
3492
|
+
);
|
|
3493
|
+
try {
|
|
3494
|
+
await persistSandboxRef(candidate.ref);
|
|
3495
|
+
return rememberSandbox(candidate.session, candidate.networkPolicyKey);
|
|
3496
|
+
} catch (error) {
|
|
3497
|
+
await stopSession(candidate.session);
|
|
3498
|
+
throw error;
|
|
3499
|
+
}
|
|
3422
3500
|
};
|
|
3423
3501
|
const discardHintIfProfileChanged = () => {
|
|
3424
3502
|
if (activeSandbox || !sandboxRef || dependencyProfileHash === sandboxRef.profileHash) {
|
|
3425
3503
|
return;
|
|
3426
3504
|
}
|
|
3505
|
+
const attrs = {
|
|
3506
|
+
...sandboxRef.profileHash ? { "app.sandbox.previous_profile_hash": sandboxRef.profileHash } : {},
|
|
3507
|
+
...dependencyProfileHash ? { "app.sandbox.current_profile_hash": dependencyProfileHash } : {}
|
|
3508
|
+
};
|
|
3427
3509
|
setSpanAttributes({
|
|
3428
3510
|
"app.sandbox.reused": false,
|
|
3429
3511
|
"app.sandbox.recreate.reason": "dependency_profile_mismatch",
|
|
3430
|
-
...
|
|
3431
|
-
"app.sandbox.previous_profile_hash": sandboxRef.profileHash
|
|
3432
|
-
} : {},
|
|
3433
|
-
...dependencyProfileHash ? { "app.sandbox.current_profile_hash": dependencyProfileHash } : {}
|
|
3512
|
+
...attrs
|
|
3434
3513
|
});
|
|
3435
3514
|
logInfo("sandbox.hint.discarded", {
|
|
3436
3515
|
"app.decision.reason": "dependency_profile_mismatch",
|
|
3437
|
-
...
|
|
3438
|
-
"app.sandbox.previous_profile_hash": sandboxRef.profileHash
|
|
3439
|
-
} : {},
|
|
3440
|
-
...dependencyProfileHash ? { "app.sandbox.current_profile_hash": dependencyProfileHash } : {}
|
|
3516
|
+
...attrs
|
|
3441
3517
|
});
|
|
3442
3518
|
sandboxRef = void 0;
|
|
3443
3519
|
};
|
|
3444
|
-
const tryReuseCachedSandbox =
|
|
3445
|
-
return activeSandbox?.session ?? null;
|
|
3446
|
-
};
|
|
3520
|
+
const tryReuseCachedSandbox = () => activeSandbox?.session ?? null;
|
|
3447
3521
|
const tryRestoreHintedSandbox = async (signal) => {
|
|
3448
3522
|
const ref = sandboxRef;
|
|
3449
3523
|
if (!ref) {
|
|
@@ -3481,9 +3555,9 @@ function createSandboxRuntime(options) {
|
|
|
3481
3555
|
}
|
|
3482
3556
|
let networkPolicyKey;
|
|
3483
3557
|
try {
|
|
3484
|
-
await reportSandboxRef(hintedSandbox);
|
|
3485
3558
|
networkPolicyKey = await applyNetworkPolicy(hintedSandbox);
|
|
3486
3559
|
await prepareSandbox(hintedSandbox);
|
|
3560
|
+
await persistSandboxRef({ ...ref, id: hintedSandbox.sandboxId });
|
|
3487
3561
|
return rememberSandbox(hintedSandbox, networkPolicyKey);
|
|
3488
3562
|
} catch (error) {
|
|
3489
3563
|
if (isSandboxUnavailableError(error)) {
|
|
@@ -3589,33 +3663,25 @@ function createSandboxRuntime(options) {
|
|
|
3589
3663
|
stderrTruncated: stderr.truncated
|
|
3590
3664
|
};
|
|
3591
3665
|
};
|
|
3592
|
-
const extendKeepAlive = async (
|
|
3666
|
+
const extendKeepAlive = async (session) => {
|
|
3593
3667
|
const keepAliveMs = parseKeepAliveMs();
|
|
3594
|
-
if (keepAliveMs === 0)
|
|
3595
|
-
return;
|
|
3596
|
-
}
|
|
3668
|
+
if (keepAliveMs === 0) return;
|
|
3597
3669
|
try {
|
|
3598
3670
|
await withSandboxSpan(
|
|
3599
3671
|
"sandbox.keepalive.extend",
|
|
3600
3672
|
"sandbox.keepalive",
|
|
3601
|
-
{
|
|
3602
|
-
"app.sandbox.keepalive_ms": keepAliveMs
|
|
3603
|
-
},
|
|
3673
|
+
{ "app.sandbox.keepalive_ms": keepAliveMs },
|
|
3604
3674
|
async () => {
|
|
3605
|
-
await
|
|
3675
|
+
await session.extendTimeout(keepAliveMs);
|
|
3606
3676
|
}
|
|
3607
3677
|
);
|
|
3608
3678
|
} catch (error) {
|
|
3609
|
-
if (isSandboxUnavailableError(error))
|
|
3610
|
-
throw error;
|
|
3611
|
-
}
|
|
3679
|
+
if (isSandboxUnavailableError(error)) throw error;
|
|
3612
3680
|
}
|
|
3613
3681
|
};
|
|
3614
3682
|
const startKeepAlive = (session) => {
|
|
3615
3683
|
const keepAliveMs = parseKeepAliveMs();
|
|
3616
|
-
if (keepAliveMs === 0 || closed || keepAliveTimer)
|
|
3617
|
-
return;
|
|
3618
|
-
}
|
|
3684
|
+
if (keepAliveMs === 0 || closed || keepAliveTimer) return;
|
|
3619
3685
|
const intervalMs = Math.max(
|
|
3620
3686
|
MIN_KEEPALIVE_INTERVAL_MS,
|
|
3621
3687
|
Math.min(MAX_KEEPALIVE_INTERVAL_MS, Math.floor(keepAliveMs / 2))
|
|
@@ -3623,18 +3689,14 @@ function createSandboxRuntime(options) {
|
|
|
3623
3689
|
const schedule = () => {
|
|
3624
3690
|
keepAliveTimer = setTimeout(async () => {
|
|
3625
3691
|
keepAliveTimer = void 0;
|
|
3626
|
-
if (closed || activeSandbox?.session !== session)
|
|
3627
|
-
return;
|
|
3628
|
-
}
|
|
3692
|
+
if (closed || activeSandbox?.session !== session) return;
|
|
3629
3693
|
try {
|
|
3630
3694
|
await extendKeepAlive(session);
|
|
3631
3695
|
} catch {
|
|
3632
3696
|
invalidateSession(session.sessionId);
|
|
3633
3697
|
return;
|
|
3634
3698
|
}
|
|
3635
|
-
if (closed || activeSandbox?.session !== session)
|
|
3636
|
-
return;
|
|
3637
|
-
}
|
|
3699
|
+
if (closed || activeSandbox?.session !== session) return;
|
|
3638
3700
|
schedule();
|
|
3639
3701
|
}, intervalMs);
|
|
3640
3702
|
keepAliveTimer.unref?.();
|
|
@@ -3714,18 +3776,57 @@ function createSandboxRuntime(options) {
|
|
|
3714
3776
|
};
|
|
3715
3777
|
};
|
|
3716
3778
|
const ensureReadySandbox = async (signal) => {
|
|
3717
|
-
const
|
|
3779
|
+
const session = await getOrAcquireSandbox(signal);
|
|
3718
3780
|
signal?.throwIfAborted();
|
|
3719
|
-
await probeSession(
|
|
3781
|
+
await probeSession(session);
|
|
3720
3782
|
signal?.throwIfAborted();
|
|
3721
|
-
await extendKeepAlive(
|
|
3722
|
-
startKeepAlive(
|
|
3723
|
-
return
|
|
3783
|
+
await extendKeepAlive(session);
|
|
3784
|
+
startKeepAlive(session);
|
|
3785
|
+
return session;
|
|
3724
3786
|
};
|
|
3725
3787
|
return {
|
|
3726
3788
|
sandboxRef() {
|
|
3727
3789
|
return sandboxRef ? { ...sandboxRef } : void 0;
|
|
3728
3790
|
},
|
|
3791
|
+
async switchWorkspace(workspace, signal) {
|
|
3792
|
+
signal?.throwIfAborted();
|
|
3793
|
+
const nextProfileHash = hash(SANDBOX_RUNTIME, workspace);
|
|
3794
|
+
if (activeWorkspace?.id === workspace.id && dependencyProfileHash === nextProfileHash) {
|
|
3795
|
+
return;
|
|
3796
|
+
}
|
|
3797
|
+
if (acquiringSandbox) {
|
|
3798
|
+
await getOrAcquireSandbox(signal);
|
|
3799
|
+
}
|
|
3800
|
+
const previous = activeSandbox;
|
|
3801
|
+
let candidate;
|
|
3802
|
+
try {
|
|
3803
|
+
candidate = await createSandboxCandidate(
|
|
3804
|
+
workspace,
|
|
3805
|
+
nextProfileHash,
|
|
3806
|
+
signal
|
|
3807
|
+
);
|
|
3808
|
+
await probeSession(candidate.session);
|
|
3809
|
+
signal?.throwIfAborted();
|
|
3810
|
+
await extendKeepAlive(candidate.session);
|
|
3811
|
+
signal?.throwIfAborted();
|
|
3812
|
+
await persistSandboxRef(candidate.ref);
|
|
3813
|
+
} catch (error) {
|
|
3814
|
+
await stopSession(candidate?.session);
|
|
3815
|
+
throw error;
|
|
3816
|
+
}
|
|
3817
|
+
if (keepAliveTimer) {
|
|
3818
|
+
clearTimeout(keepAliveTimer);
|
|
3819
|
+
keepAliveTimer = void 0;
|
|
3820
|
+
}
|
|
3821
|
+
activeWorkspace = candidate.workspace;
|
|
3822
|
+
dependencyProfileHash = candidate.profileHash;
|
|
3823
|
+
activeSandbox = {
|
|
3824
|
+
session: candidate.session,
|
|
3825
|
+
networkPolicyKey: candidate.networkPolicyKey
|
|
3826
|
+
};
|
|
3827
|
+
startKeepAlive(candidate.session);
|
|
3828
|
+
await stopSession(previous?.session);
|
|
3829
|
+
},
|
|
3729
3830
|
async acquire(signal) {
|
|
3730
3831
|
return await getOrAcquireSandbox(signal);
|
|
3731
3832
|
},
|
|
@@ -4965,8 +5066,10 @@ function createSandbox(options) {
|
|
|
4965
5066
|
...permissionDenied ? { permissionDenied } : {}
|
|
4966
5067
|
};
|
|
4967
5068
|
};
|
|
5069
|
+
let activeWorkspace = options.workspace;
|
|
4968
5070
|
const runtime = createSandboxRuntime({
|
|
4969
5071
|
sandboxRef: options.sandboxRef,
|
|
5072
|
+
workspace: options.workspace,
|
|
4970
5073
|
skills: options.skills,
|
|
4971
5074
|
referenceFiles: options.referenceFiles,
|
|
4972
5075
|
timeoutMs: options.timeoutMs,
|
|
@@ -4980,6 +5083,7 @@ function createSandbox(options) {
|
|
|
4980
5083
|
traceHeaders
|
|
4981
5084
|
}) : void 0,
|
|
4982
5085
|
onSandboxPrepare: options.prepare,
|
|
5086
|
+
onWorkspacePrepare: options.prepareWorkspace,
|
|
4983
5087
|
onSandboxRefChanged: options.onSandboxRefChanged
|
|
4984
5088
|
});
|
|
4985
5089
|
const createToolCallContext = (signal, setToolCallSpanAttributes) => {
|
|
@@ -5422,7 +5526,9 @@ function createSandbox(options) {
|
|
|
5422
5526
|
return void 0;
|
|
5423
5527
|
}
|
|
5424
5528
|
const { fs: fs5 } = await runtime.tools();
|
|
5425
|
-
const
|
|
5529
|
+
const primary = activeWorkspace?.repos.find((repo) => repo.isPrimary);
|
|
5530
|
+
const primaryPath = primary ? tryWorkspaceRepoCheckoutPath(primary.repo) : void 0;
|
|
5531
|
+
const selected = primaryPath ? `${SANDBOX_WORKSPACE_ROOT}/${primaryPath}` : await findSingleRepositoryDirectory(fs5);
|
|
5426
5532
|
if (!selected) return void 0;
|
|
5427
5533
|
return await resolveRepositoryInstructions({
|
|
5428
5534
|
cwd: selected,
|
|
@@ -5430,6 +5536,10 @@ function createSandbox(options) {
|
|
|
5430
5536
|
});
|
|
5431
5537
|
},
|
|
5432
5538
|
workspace,
|
|
5539
|
+
async switchWorkspace(recipe, signal) {
|
|
5540
|
+
await runtime.switchWorkspace(recipe, signal);
|
|
5541
|
+
activeWorkspace = recipe;
|
|
5542
|
+
},
|
|
5433
5543
|
tools: {
|
|
5434
5544
|
supports(toolName) {
|
|
5435
5545
|
return SANDBOX_TOOL_NAMES.has(toolName);
|
|
@@ -5851,6 +5961,7 @@ function bashCommand(input) {
|
|
|
5851
5961
|
function createAgentSandbox(options) {
|
|
5852
5962
|
const sandbox = createSandbox({
|
|
5853
5963
|
sandboxRef: options.sandboxRef,
|
|
5964
|
+
workspace: options.workspace,
|
|
5854
5965
|
skills: options.skills,
|
|
5855
5966
|
referenceFiles: listReferenceFiles(),
|
|
5856
5967
|
traceContext: options.traceContext,
|
|
@@ -5858,6 +5969,7 @@ function createAgentSandbox(options) {
|
|
|
5858
5969
|
egressSignals: options.egressSignals,
|
|
5859
5970
|
credentialEgress: options.credentialEgress,
|
|
5860
5971
|
prepare: options.prepareSandbox,
|
|
5972
|
+
prepareWorkspace: options.prepareWorkspace,
|
|
5861
5973
|
onSandboxRefChanged: async (sandboxRef) => {
|
|
5862
5974
|
options.onSandboxRefChanged(sandboxRef);
|
|
5863
5975
|
await options.persistSandboxRef?.(sandboxRef);
|
|
@@ -5867,6 +5979,7 @@ function createAgentSandbox(options) {
|
|
|
5867
5979
|
captureRepositoryInstructions: sandbox.captureRepositoryInstructions,
|
|
5868
5980
|
workspace: sandbox.workspace,
|
|
5869
5981
|
sandboxRef: sandbox.sandboxRef,
|
|
5982
|
+
switchWorkspace: sandbox.switchWorkspace,
|
|
5870
5983
|
close: sandbox.close,
|
|
5871
5984
|
tools: {
|
|
5872
5985
|
supports: sandbox.tools.supports,
|
|
@@ -10008,8 +10121,12 @@ var CONVERSATIONS_TOOL_SOURCE = {
|
|
|
10008
10121
|
};
|
|
10009
10122
|
|
|
10010
10123
|
// src/chat/slack/tools/conversation-message-search.ts
|
|
10011
|
-
var DEFAULT_LIMIT =
|
|
10124
|
+
var DEFAULT_LIMIT = 20;
|
|
10125
|
+
var MAX_LIMIT = 50;
|
|
10012
10126
|
var conversationMessageSearchOutputSchema = juniorToolOutputSchema.extend({
|
|
10127
|
+
after: z39.string().datetime().optional(),
|
|
10128
|
+
annotation: z39.string().min(1).optional(),
|
|
10129
|
+
before: z39.string().datetime().optional(),
|
|
10013
10130
|
channel_id: z39.string().min(1).optional(),
|
|
10014
10131
|
count: z39.number().int().nonnegative(),
|
|
10015
10132
|
query: z39.string().optional(),
|
|
@@ -10027,8 +10144,21 @@ var conversationMessageSearchOutputSchema = juniorToolOutputSchema.extend({
|
|
|
10027
10144
|
}).strict()
|
|
10028
10145
|
)
|
|
10029
10146
|
});
|
|
10147
|
+
function parseTimestamp(field, value) {
|
|
10148
|
+
if (value == null || value.trim() === "") {
|
|
10149
|
+
return void 0;
|
|
10150
|
+
}
|
|
10151
|
+
const parsed = Date.parse(value);
|
|
10152
|
+
if (!Number.isFinite(parsed)) {
|
|
10153
|
+
throw new ToolInputError(`${field} must be a valid ISO-8601 timestamp`);
|
|
10154
|
+
}
|
|
10155
|
+
return parsed;
|
|
10156
|
+
}
|
|
10030
10157
|
async function resolveSearchFilters(input) {
|
|
10031
10158
|
const query = input.query?.trim() || void 0;
|
|
10159
|
+
const annotation = input.annotation?.trim() || void 0;
|
|
10160
|
+
const afterMs = parseTimestamp("after", input.after);
|
|
10161
|
+
const beforeMs = parseTimestamp("before", input.before);
|
|
10032
10162
|
let channelId;
|
|
10033
10163
|
if (input.channel_id != null && input.channel_id.trim() !== "") {
|
|
10034
10164
|
const target = await resolveSlackChannelRef({
|
|
@@ -10037,19 +10167,25 @@ async function resolveSearchFilters(input) {
|
|
|
10037
10167
|
});
|
|
10038
10168
|
channelId = target.channelId;
|
|
10039
10169
|
}
|
|
10040
|
-
if (
|
|
10170
|
+
if (afterMs !== void 0 && beforeMs !== void 0 && afterMs >= beforeMs) {
|
|
10171
|
+
throw new ToolInputError("`after` must be earlier than `before`");
|
|
10172
|
+
}
|
|
10173
|
+
if (!query && !channelId && !annotation) {
|
|
10041
10174
|
throw new ToolInputError(
|
|
10042
|
-
"Provide at least one of `query` or `
|
|
10175
|
+
"Provide at least one of `query`, `channel_id`, or `annotation`."
|
|
10043
10176
|
);
|
|
10044
10177
|
}
|
|
10045
10178
|
return {
|
|
10179
|
+
...afterMs !== void 0 ? { afterMs } : {},
|
|
10180
|
+
...annotation ? { annotation } : {},
|
|
10181
|
+
...beforeMs !== void 0 ? { beforeMs } : {},
|
|
10046
10182
|
...channelId ? { channelId } : {},
|
|
10047
10183
|
...query ? { query } : {}
|
|
10048
10184
|
};
|
|
10049
10185
|
}
|
|
10050
10186
|
function createSlackConversationMessageSearchTool(scope, currentConversationId) {
|
|
10051
10187
|
return zodTool({
|
|
10052
|
-
description: "Search retained user and assistant messages from public conversations in this Slack workspace. Excludes the current conversation. Not live Slack workspace search.",
|
|
10188
|
+
description: "Search retained user and assistant messages from public conversations in this Slack workspace. Filter by message text, channel, time range, or linked annotation such as a resource key. Excludes the current conversation. Not live Slack workspace search.",
|
|
10053
10189
|
exposure: "deferred",
|
|
10054
10190
|
source: CONVERSATIONS_TOOL_SOURCE,
|
|
10055
10191
|
annotations: {
|
|
@@ -10059,9 +10195,16 @@ function createSlackConversationMessageSearchTool(scope, currentConversationId)
|
|
|
10059
10195
|
readOnlyHint: true
|
|
10060
10196
|
},
|
|
10061
10197
|
inputSchema: z39.object({
|
|
10198
|
+
after: z39.string().datetime().nullable().describe("Include conversations active at or after this timestamp.").optional(),
|
|
10199
|
+
annotation: z39.string().trim().min(1).max(256).nullable().describe(
|
|
10200
|
+
"Linked resource key. Matches that key, or nested children that continue with #."
|
|
10201
|
+
).optional(),
|
|
10202
|
+
before: z39.string().datetime().nullable().describe("Include conversations active before this timestamp.").optional(),
|
|
10062
10203
|
channel_id: slackChannelRefParam.nullable().optional(),
|
|
10063
10204
|
query: z39.string().trim().min(1).max(200).nullable().describe("Words or phrase to match in message text.").optional(),
|
|
10064
|
-
limit: z39.number().int().min(1).max(
|
|
10205
|
+
limit: z39.number().int().min(1).max(MAX_LIMIT).describe(
|
|
10206
|
+
`Maximum conversations. Default ${DEFAULT_LIMIT}; max ${MAX_LIMIT}.`
|
|
10207
|
+
).nullable().optional()
|
|
10065
10208
|
}).strict(),
|
|
10066
10209
|
outputSchema: conversationMessageSearchOutputSchema,
|
|
10067
10210
|
execute: async (input) => {
|
|
@@ -10099,6 +10242,9 @@ function createSlackConversationMessageSearchTool(scope, currentConversationId)
|
|
|
10099
10242
|
})
|
|
10100
10243
|
);
|
|
10101
10244
|
return {
|
|
10245
|
+
...filters.afterMs !== void 0 ? { after: new Date(filters.afterMs).toISOString() } : {},
|
|
10246
|
+
...filters.annotation ? { annotation: filters.annotation } : {},
|
|
10247
|
+
...filters.beforeMs !== void 0 ? { before: new Date(filters.beforeMs).toISOString() } : {},
|
|
10102
10248
|
...filters.query ? { query: filters.query } : {},
|
|
10103
10249
|
...filters.channelId ? { channel_id: filters.channelId } : {},
|
|
10104
10250
|
count: matchesOutput.length,
|
|
@@ -12597,7 +12743,7 @@ function createUnpublishImageTool(args) {
|
|
|
12597
12743
|
// src/chat/tools/search-conversation-events.ts
|
|
12598
12744
|
import { z as z58 } from "zod";
|
|
12599
12745
|
var DEFAULT_LIMIT3 = 25;
|
|
12600
|
-
var
|
|
12746
|
+
var MAX_LIMIT2 = 100;
|
|
12601
12747
|
var MAX_EVENT_DATA_BYTES = 4e3;
|
|
12602
12748
|
var MAX_EVENTS_JSON_BYTES = 2e4;
|
|
12603
12749
|
var MAX_IDENTITY_CHARS = 256;
|
|
@@ -12634,8 +12780,8 @@ function createSearchConversationEventsTool(context) {
|
|
|
12634
12780
|
).optional(),
|
|
12635
12781
|
after_seq: z58.number().int().nonnegative().nullable().describe("Exclusive event sequence lower bound; returns ascending.").optional(),
|
|
12636
12782
|
before_seq: z58.number().int().nonnegative().nullable().describe("Exclusive event sequence upper bound.").optional(),
|
|
12637
|
-
limit: z58.number().int().min(1).max(
|
|
12638
|
-
`Maximum events. Default ${DEFAULT_LIMIT3}; max ${
|
|
12783
|
+
limit: z58.number().int().min(1).max(MAX_LIMIT2).nullable().describe(
|
|
12784
|
+
`Maximum events. Default ${DEFAULT_LIMIT3}; max ${MAX_LIMIT2}.`
|
|
12639
12785
|
).optional(),
|
|
12640
12786
|
types: z58.array(knownEventTypeSchema).min(1).nullable().describe("Event types to include; omit for all types.").optional()
|
|
12641
12787
|
}).strict(),
|
|
@@ -13521,6 +13667,133 @@ function createWriteFileTool() {
|
|
|
13521
13667
|
});
|
|
13522
13668
|
}
|
|
13523
13669
|
|
|
13670
|
+
// src/chat/workspaces/tools.ts
|
|
13671
|
+
import { z as z63 } from "zod";
|
|
13672
|
+
|
|
13673
|
+
// src/chat/workspaces/store.ts
|
|
13674
|
+
import { asc, eq as eq3 } from "drizzle-orm";
|
|
13675
|
+
function workspaceFromRows(row, repos) {
|
|
13676
|
+
return {
|
|
13677
|
+
id: row.id,
|
|
13678
|
+
name: row.name,
|
|
13679
|
+
setupScript: row.setupScript,
|
|
13680
|
+
repos: repos.map((repo) => ({
|
|
13681
|
+
provider: repo.provider,
|
|
13682
|
+
repo: repo.repo,
|
|
13683
|
+
isPrimary: repo.isPrimary
|
|
13684
|
+
}))
|
|
13685
|
+
};
|
|
13686
|
+
}
|
|
13687
|
+
async function listWorkspaces(db) {
|
|
13688
|
+
const [workspaces, repos] = await Promise.all([
|
|
13689
|
+
db.select().from(juniorWorkspaces).orderBy(asc(juniorWorkspaces.name)),
|
|
13690
|
+
db.select().from(juniorWorkspaceRepos).orderBy(
|
|
13691
|
+
asc(juniorWorkspaceRepos.workspaceId),
|
|
13692
|
+
asc(juniorWorkspaceRepos.provider),
|
|
13693
|
+
asc(juniorWorkspaceRepos.repo)
|
|
13694
|
+
)
|
|
13695
|
+
]);
|
|
13696
|
+
return workspaces.map(
|
|
13697
|
+
(workspace) => workspaceFromRows(
|
|
13698
|
+
workspace,
|
|
13699
|
+
repos.filter((repo) => repo.workspaceId === workspace.id)
|
|
13700
|
+
)
|
|
13701
|
+
);
|
|
13702
|
+
}
|
|
13703
|
+
async function getWorkspaceByName(db, name) {
|
|
13704
|
+
const rows = await db.select().from(juniorWorkspaces).where(eq3(juniorWorkspaces.name, name)).limit(1);
|
|
13705
|
+
const workspace = rows[0];
|
|
13706
|
+
if (!workspace) return void 0;
|
|
13707
|
+
const repos = await db.select().from(juniorWorkspaceRepos).where(eq3(juniorWorkspaceRepos.workspaceId, workspace.id)).orderBy(
|
|
13708
|
+
asc(juniorWorkspaceRepos.provider),
|
|
13709
|
+
asc(juniorWorkspaceRepos.repo)
|
|
13710
|
+
);
|
|
13711
|
+
return workspaceFromRows(workspace, repos);
|
|
13712
|
+
}
|
|
13713
|
+
async function getWorkspace(db, id) {
|
|
13714
|
+
const rows = await db.select().from(juniorWorkspaces).where(eq3(juniorWorkspaces.id, id)).limit(1);
|
|
13715
|
+
const workspace = rows[0];
|
|
13716
|
+
if (!workspace) return void 0;
|
|
13717
|
+
const repos = await db.select().from(juniorWorkspaceRepos).where(eq3(juniorWorkspaceRepos.workspaceId, workspace.id)).orderBy(
|
|
13718
|
+
asc(juniorWorkspaceRepos.provider),
|
|
13719
|
+
asc(juniorWorkspaceRepos.repo)
|
|
13720
|
+
);
|
|
13721
|
+
return workspaceFromRows(workspace, repos);
|
|
13722
|
+
}
|
|
13723
|
+
|
|
13724
|
+
// src/chat/workspaces/tools.ts
|
|
13725
|
+
var repoSchema = z63.object({
|
|
13726
|
+
provider: z63.string(),
|
|
13727
|
+
repo: z63.string(),
|
|
13728
|
+
checkout_path: z63.string(),
|
|
13729
|
+
is_primary: z63.boolean()
|
|
13730
|
+
});
|
|
13731
|
+
var workspaceSchema = z63.object({
|
|
13732
|
+
id: z63.string(),
|
|
13733
|
+
name: z63.string(),
|
|
13734
|
+
repos: z63.array(repoSchema)
|
|
13735
|
+
});
|
|
13736
|
+
function view(workspace) {
|
|
13737
|
+
return {
|
|
13738
|
+
id: workspace.id,
|
|
13739
|
+
name: workspace.name,
|
|
13740
|
+
repos: workspace.repos.map((repo) => ({
|
|
13741
|
+
provider: repo.provider,
|
|
13742
|
+
repo: repo.repo,
|
|
13743
|
+
checkout_path: workspaceRepoCheckoutPath(repo.repo),
|
|
13744
|
+
is_primary: repo.isPrimary
|
|
13745
|
+
}))
|
|
13746
|
+
};
|
|
13747
|
+
}
|
|
13748
|
+
function createWorkspaceTools(context) {
|
|
13749
|
+
if (!context.workspaces) return {};
|
|
13750
|
+
return {
|
|
13751
|
+
listWorkspaces: zodTool({
|
|
13752
|
+
annotations: {
|
|
13753
|
+
destructiveHint: false,
|
|
13754
|
+
idempotentHint: true,
|
|
13755
|
+
openWorldHint: false,
|
|
13756
|
+
readOnlyHint: true
|
|
13757
|
+
},
|
|
13758
|
+
description: "List named repository workspaces that can replace the current sandbox.",
|
|
13759
|
+
inputSchema: z63.object({}).strict(),
|
|
13760
|
+
outputSchema: juniorToolOutputSchema.extend({
|
|
13761
|
+
active_workspace_id: z63.string().nullable(),
|
|
13762
|
+
workspaces: z63.array(workspaceSchema)
|
|
13763
|
+
}),
|
|
13764
|
+
async execute() {
|
|
13765
|
+
return {
|
|
13766
|
+
active_workspace_id: context.workspaces.activeWorkspaceId() ?? null,
|
|
13767
|
+
workspaces: (await listWorkspaces(getDb())).map(view)
|
|
13768
|
+
};
|
|
13769
|
+
}
|
|
13770
|
+
}),
|
|
13771
|
+
switchWorkspace: zodTool({
|
|
13772
|
+
executionMode: "sequential",
|
|
13773
|
+
annotations: {
|
|
13774
|
+
destructiveHint: true,
|
|
13775
|
+
idempotentHint: true,
|
|
13776
|
+
openWorldHint: true,
|
|
13777
|
+
readOnlyHint: false
|
|
13778
|
+
},
|
|
13779
|
+
description: "Replace the current sandbox with a named preconfigured repository workspace. Files in the prior sandbox do not carry over.",
|
|
13780
|
+
inputSchema: z63.object({
|
|
13781
|
+
name: z63.string().trim().min(1).describe("Exact workspace name.")
|
|
13782
|
+
}).strict(),
|
|
13783
|
+
outputSchema: juniorToolOutputSchema.extend({
|
|
13784
|
+
workspace: workspaceSchema
|
|
13785
|
+
}),
|
|
13786
|
+
async execute({ name }, options) {
|
|
13787
|
+
const workspace = await getWorkspaceByName(getDb(), name);
|
|
13788
|
+
if (!workspace)
|
|
13789
|
+
throw new ToolInputError(`Workspace not found: ${name}`);
|
|
13790
|
+
await context.workspaces.switch(workspace, options.signal);
|
|
13791
|
+
return { workspace: view(workspace) };
|
|
13792
|
+
}
|
|
13793
|
+
})
|
|
13794
|
+
};
|
|
13795
|
+
}
|
|
13796
|
+
|
|
13524
13797
|
// src/chat/tools/index.ts
|
|
13525
13798
|
function createToolState() {
|
|
13526
13799
|
const operationResultCache = /* @__PURE__ */ new Map();
|
|
@@ -13563,7 +13836,8 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
|
|
|
13563
13836
|
}),
|
|
13564
13837
|
...createResourceEventTools(context, resourceEventCatalog),
|
|
13565
13838
|
...createEventTaskTools(context, resourceEventCatalog),
|
|
13566
|
-
...createScheduledTaskTools(context)
|
|
13839
|
+
...createScheduledTaskTools(context),
|
|
13840
|
+
...createWorkspaceTools(context)
|
|
13567
13841
|
};
|
|
13568
13842
|
if (context.conversationId) {
|
|
13569
13843
|
tools.searchConversationEvents = createSearchConversationEventsTool(context);
|
|
@@ -14245,7 +14519,7 @@ function handleToolExecutionError(error, toolName, toolCallId, shouldTrace, conv
|
|
|
14245
14519
|
}
|
|
14246
14520
|
|
|
14247
14521
|
// src/chat/tools/execute-tool.ts
|
|
14248
|
-
import { z as
|
|
14522
|
+
import { z as z64 } from "zod";
|
|
14249
14523
|
var EXECUTE_TOOL_NAME = "executeTool";
|
|
14250
14524
|
function createExecuteToolTool() {
|
|
14251
14525
|
return zodTool({
|
|
@@ -14257,11 +14531,11 @@ function createExecuteToolTool() {
|
|
|
14257
14531
|
},
|
|
14258
14532
|
description: "Execute any catalog tool by exact tool_name from searchTools or a tool-result execution hint. Put tool-specific parameters inside arguments.",
|
|
14259
14533
|
executionMode: "sequential",
|
|
14260
|
-
inputSchema:
|
|
14261
|
-
tool_name:
|
|
14534
|
+
inputSchema: z64.object({
|
|
14535
|
+
tool_name: z64.string().min(1).describe(
|
|
14262
14536
|
"Exact catalog tool_name returned by searchTools or a tool-result execution hint."
|
|
14263
14537
|
),
|
|
14264
|
-
arguments:
|
|
14538
|
+
arguments: z64.record(z64.string(), z64.unknown()).describe(
|
|
14265
14539
|
'Arguments matching the selected catalog tool schema, for example { "query": "..." }.'
|
|
14266
14540
|
).optional()
|
|
14267
14541
|
}).strict(),
|
|
@@ -14301,7 +14575,7 @@ function planToolExposure(tools) {
|
|
|
14301
14575
|
}
|
|
14302
14576
|
|
|
14303
14577
|
// src/chat/tools/search-tools.ts
|
|
14304
|
-
import { z as
|
|
14578
|
+
import { z as z65 } from "zod";
|
|
14305
14579
|
var SEARCH_TOOLS_NAME = "searchTools";
|
|
14306
14580
|
var DEFAULT_MAX_RESULTS2 = 5;
|
|
14307
14581
|
var MAX_RESULTS3 = 20;
|
|
@@ -14346,29 +14620,29 @@ var SEARCH_STOP_WORDS = /* @__PURE__ */ new Set([
|
|
|
14346
14620
|
"you",
|
|
14347
14621
|
"your"
|
|
14348
14622
|
]);
|
|
14349
|
-
var searchToolsSourceSchema =
|
|
14350
|
-
id:
|
|
14351
|
-
description:
|
|
14623
|
+
var searchToolsSourceSchema = z65.object({
|
|
14624
|
+
id: z65.string(),
|
|
14625
|
+
description: z65.string()
|
|
14352
14626
|
}).strict();
|
|
14353
|
-
var searchToolsToolSchema =
|
|
14354
|
-
tool_name:
|
|
14355
|
-
description:
|
|
14356
|
-
exposure:
|
|
14357
|
-
source:
|
|
14358
|
-
input_schema:
|
|
14359
|
-
call_notes:
|
|
14360
|
-
annotations:
|
|
14627
|
+
var searchToolsToolSchema = z65.object({
|
|
14628
|
+
tool_name: z65.string(),
|
|
14629
|
+
description: z65.string(),
|
|
14630
|
+
exposure: z65.enum(["direct", "deferred", "modelOnly", "hidden"]),
|
|
14631
|
+
source: z65.string().optional(),
|
|
14632
|
+
input_schema: z65.unknown(),
|
|
14633
|
+
call_notes: z65.array(z65.string()),
|
|
14634
|
+
annotations: z65.record(z65.string(), z65.unknown())
|
|
14361
14635
|
}).strict();
|
|
14362
14636
|
var searchToolsOutputSchema = juniorToolOutputSchema.extend({
|
|
14363
|
-
query:
|
|
14364
|
-
source:
|
|
14365
|
-
sources:
|
|
14366
|
-
total_catalog_tools:
|
|
14367
|
-
total_eligible_tools:
|
|
14368
|
-
total_matches:
|
|
14369
|
-
returned_tools:
|
|
14370
|
-
execution_tool:
|
|
14371
|
-
tools:
|
|
14637
|
+
query: z65.string().nullable(),
|
|
14638
|
+
source: z65.string().nullable(),
|
|
14639
|
+
sources: z65.array(searchToolsSourceSchema),
|
|
14640
|
+
total_catalog_tools: z65.number().int().nonnegative(),
|
|
14641
|
+
total_eligible_tools: z65.number().int().nonnegative(),
|
|
14642
|
+
total_matches: z65.number().int().nonnegative(),
|
|
14643
|
+
returned_tools: z65.number().int().nonnegative(),
|
|
14644
|
+
execution_tool: z65.literal("executeTool"),
|
|
14645
|
+
tools: z65.array(searchToolsToolSchema)
|
|
14372
14646
|
}).strict();
|
|
14373
14647
|
function terms(value) {
|
|
14374
14648
|
const chunks = value.match(/[\p{L}\p{N}]+/gu) ?? [];
|
|
@@ -14579,14 +14853,14 @@ function createSearchToolsTool(catalogTools) {
|
|
|
14579
14853
|
openWorldHint: false,
|
|
14580
14854
|
readOnlyHint: true
|
|
14581
14855
|
},
|
|
14582
|
-
inputSchema:
|
|
14583
|
-
query:
|
|
14856
|
+
inputSchema: z65.object({
|
|
14857
|
+
query: z65.string().nullable().describe(
|
|
14584
14858
|
"Optional search terms describing the tool, owner, action, or arguments needed. Empty string lists catalog tools."
|
|
14585
14859
|
).optional(),
|
|
14586
|
-
source:
|
|
14860
|
+
source: z65.string().nullable().describe(
|
|
14587
14861
|
"Optional source id to search within, such as a plugin source returned in sources."
|
|
14588
14862
|
).optional(),
|
|
14589
|
-
max_results:
|
|
14863
|
+
max_results: z65.number().int().min(1).max(MAX_RESULTS3).nullable().describe("Maximum matching catalog tool descriptors to return.").optional()
|
|
14590
14864
|
}).strict(),
|
|
14591
14865
|
outputSchema: searchToolsOutputSchema,
|
|
14592
14866
|
privateTraceResult: (result) => ({
|
|
@@ -15845,7 +16119,7 @@ function createPluginEgress(deps) {
|
|
|
15845
16119
|
}
|
|
15846
16120
|
|
|
15847
16121
|
// src/chat/services/guardian-action-review.ts
|
|
15848
|
-
import { z as
|
|
16122
|
+
import { z as z66 } from "zod";
|
|
15849
16123
|
|
|
15850
16124
|
// src/chat/services/guardian-action-policy.ts
|
|
15851
16125
|
var GUARDIAN_ACTION_POLICY = `You are judging one planned Junior agent action.
|
|
@@ -15913,17 +16187,17 @@ Assess the exact action's intrinsic risk and whether the user's intent authorize
|
|
|
15913
16187
|
- 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.`;
|
|
15914
16188
|
|
|
15915
16189
|
// src/chat/services/guardian-action-review.ts
|
|
15916
|
-
var guardianDecisionSchema =
|
|
15917
|
-
decision:
|
|
15918
|
-
reason:
|
|
15919
|
-
riskLevel:
|
|
15920
|
-
userAuthorization:
|
|
16190
|
+
var guardianDecisionSchema = z66.object({
|
|
16191
|
+
decision: z66.enum(["allow", "ask", "deny"]),
|
|
16192
|
+
reason: z66.string().trim().min(1).max(500),
|
|
16193
|
+
riskLevel: z66.enum(["low", "medium", "high", "critical"]),
|
|
16194
|
+
userAuthorization: z66.enum(["high", "medium", "low", "unknown"])
|
|
15921
16195
|
}).strict();
|
|
15922
16196
|
var GUARDIAN_REVIEW_TIMEOUT_MS = 6e4;
|
|
15923
16197
|
var GUARDIAN_REVIEW_MAX_TOKENS = 2e3;
|
|
15924
16198
|
var MAX_PROPOSAL_CHARS = 192e3;
|
|
15925
16199
|
function guardianPrompt(proposal) {
|
|
15926
|
-
const proposalJson = JSON.stringify(
|
|
16200
|
+
const proposalJson = JSON.stringify(z66.json().parse(proposal), null, 2);
|
|
15927
16201
|
if (proposalJson.length > MAX_PROPOSAL_CHARS) {
|
|
15928
16202
|
throw new Error(
|
|
15929
16203
|
`Guardian action proposal exceeds ${MAX_PROPOSAL_CHARS} characters.`
|
|
@@ -16208,8 +16482,10 @@ async function wireAgentTools(args) {
|
|
|
16208
16482
|
actor: args.currentActor,
|
|
16209
16483
|
actors: args.currentActors
|
|
16210
16484
|
});
|
|
16485
|
+
const workspace = args.state.sandboxRef?.workspaceId ? await getWorkspace(getDb(), args.state.sandboxRef.workspaceId) : void 0;
|
|
16211
16486
|
const agentSandbox = createAgentSandbox({
|
|
16212
16487
|
sandboxRef: args.state.sandboxRef,
|
|
16488
|
+
workspace,
|
|
16213
16489
|
skills: args.availableSkills,
|
|
16214
16490
|
traceContext: args.spanContext,
|
|
16215
16491
|
tracePropagation: args.run.environment?.sandboxTracePropagation,
|
|
@@ -16220,6 +16496,7 @@ async function wireAgentTools(args) {
|
|
|
16220
16496
|
configurationValues: args.configurationValues,
|
|
16221
16497
|
getActiveSkill: () => args.skillSandbox.getActiveSkill(),
|
|
16222
16498
|
prepareSandbox: pluginHooks.prepareSandbox,
|
|
16499
|
+
prepareWorkspace: async (sandbox, recipe, signal) => await pluginHooks.prepareWorkspace(sandbox, recipe.repos, signal),
|
|
16223
16500
|
onSandboxRefChanged: args.onSandboxRefChanged,
|
|
16224
16501
|
persistSandboxRef: args.durability.onSandboxRefChanged
|
|
16225
16502
|
});
|
|
@@ -16323,7 +16600,11 @@ async function wireAgentTools(args) {
|
|
|
16323
16600
|
const toolRuntimeContext = {
|
|
16324
16601
|
...commonToolRuntimeContext,
|
|
16325
16602
|
...toolRoute,
|
|
16326
|
-
attachmentStorage: args.run.environment?.attachmentStorage
|
|
16603
|
+
attachmentStorage: args.run.environment?.attachmentStorage,
|
|
16604
|
+
workspaces: {
|
|
16605
|
+
activeWorkspaceId: () => agentSandbox.sandboxRef()?.workspaceId,
|
|
16606
|
+
switch: agentSandbox.switchWorkspace
|
|
16607
|
+
}
|
|
16327
16608
|
};
|
|
16328
16609
|
const actionReview = createToolActionReview({
|
|
16329
16610
|
context: {
|