@sentry/junior 0.162.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-TL2SGC5W.js → agent-hooks-6IX5CV7G.js} +10 -10
- package/dist/api/acp/route.d.ts +13 -0
- package/dist/api.js +204 -403
- package/dist/app.d.ts +2 -2
- package/dist/app.js +480 -38
- package/dist/{catalog-runtime-IGSMIADJ.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/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/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-BPZQWAZJ.js → chunk-2FBPN2Y4.js} +4 -1
- package/dist/{chunk-H2KW7AZC.js → chunk-2HBJQEBE.js} +1 -1
- package/dist/{chunk-O6P7DZ6O.js → chunk-3OZNFCPR.js} +6 -6
- package/dist/{chunk-7DTPFFQX.js → chunk-3T7RJVDJ.js} +1 -1
- package/dist/{chunk-FEWT5KPP.js → chunk-4P2XNVTO.js} +2 -2
- package/dist/{chunk-CZ6EHOU5.js → chunk-ATWHPSMF.js} +40 -2
- package/dist/{chunk-MMBMDSRK.js → chunk-BLZUFHM7.js} +1 -1
- package/dist/chunk-BVREIWBD.js +131 -0
- package/dist/{chunk-OPNJRQDP.js → chunk-EKGJVUVS.js} +9 -6
- package/dist/{chunk-4WYGQ47U.js → chunk-FEIHINKR.js} +5 -5
- package/dist/{chunk-JJ3VXFDI.js → chunk-GCLHNRMU.js} +1 -1
- package/dist/{chunk-WHAJ3QVY.js → chunk-ICJ3KCA2.js} +1 -1
- package/dist/{chunk-5NEBOHRG.js → chunk-IIT23D3M.js} +4 -4
- package/dist/{chunk-EHQLTK3X.js → chunk-IX4XI42N.js} +376 -128
- package/dist/{chunk-DDQ43S5Q.js → chunk-JI5EPI3O.js} +4 -4
- package/dist/{chunk-C3KUKA27.js → chunk-KD3ROG6P.js} +17 -17
- package/dist/{chunk-JRVURR3H.js → chunk-MWVQ35U6.js} +543 -164
- package/dist/{chunk-V7QL4QMW.js → chunk-MXFL7LNZ.js} +12 -7
- package/dist/{chunk-RDV4BQRZ.js → chunk-NL53P7PS.js} +1 -1
- package/dist/{chunk-EBEHJPFF.js → chunk-O4IK4O7C.js} +1 -1
- package/dist/{chunk-KQSO4DJ4.js → chunk-O5ZZL7IR.js} +9 -9
- package/dist/{chunk-FESUWAYU.js → chunk-RK7KPI6G.js} +1 -1
- package/dist/{chunk-OBFRMQBY.js → chunk-RTPJRLOP.js} +9 -9
- package/dist/{chunk-HW4BW3PC.js → chunk-SR6WRBJW.js} +4 -4
- package/dist/{chunk-6BJFIWEV.js → chunk-THS4CKN4.js} +46 -87
- package/dist/{chunk-DZC3F2UI.js → chunk-TPDNZCZU.js} +1 -1
- package/dist/{chunk-Y75ZDQB5.js → chunk-TPT6EF7K.js} +1 -1
- package/dist/{chunk-5IDFPCON.js → chunk-VRS6WDK5.js} +1 -1
- package/dist/{chunk-AJ7J2HWY.js → chunk-WPGYWDJR.js} +6 -6
- package/dist/{chunk-K7IV6UV3.js → chunk-XY2IVIAY.js} +5 -5
- package/dist/{chunk-MNCEGXEH.js → chunk-YAUQXZVT.js} +2 -2
- package/dist/{chunk-THXMSSFZ.js → chunk-ZDKTZG3G.js} +1 -1
- package/dist/{chunk-QHCIZLIX.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-66XZ4HHQ.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-FMLKDUUF.js → oauth-callback-server-5NCCUIM2.js} +24 -24
- package/dist/{runner-YZONUMNY.js → runner-6ONEB6TQ.js} +13 -13
- package/dist/{skills-3UDJJXSO.js → skills-Y5R36UH4.js} +6 -6
- package/dist/spawn-RFMBQ6B3.js +37 -0
- package/dist/{validation-3HTDBONC.js → validation-HLHEQDEK.js} +6 -6
- package/dist/version.js +1 -1
- package/dist/{work-O4YTIS54.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-TBPVA5S2.js +0 -37
- package/dist/worker-WHURUEYX.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,
|
|
@@ -13554,6 +13667,133 @@ function createWriteFileTool() {
|
|
|
13554
13667
|
});
|
|
13555
13668
|
}
|
|
13556
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
|
+
|
|
13557
13797
|
// src/chat/tools/index.ts
|
|
13558
13798
|
function createToolState() {
|
|
13559
13799
|
const operationResultCache = /* @__PURE__ */ new Map();
|
|
@@ -13596,7 +13836,8 @@ function createTools(availableSkills, hooks = {}, context, options = {}) {
|
|
|
13596
13836
|
}),
|
|
13597
13837
|
...createResourceEventTools(context, resourceEventCatalog),
|
|
13598
13838
|
...createEventTaskTools(context, resourceEventCatalog),
|
|
13599
|
-
...createScheduledTaskTools(context)
|
|
13839
|
+
...createScheduledTaskTools(context),
|
|
13840
|
+
...createWorkspaceTools(context)
|
|
13600
13841
|
};
|
|
13601
13842
|
if (context.conversationId) {
|
|
13602
13843
|
tools.searchConversationEvents = createSearchConversationEventsTool(context);
|
|
@@ -14278,7 +14519,7 @@ function handleToolExecutionError(error, toolName, toolCallId, shouldTrace, conv
|
|
|
14278
14519
|
}
|
|
14279
14520
|
|
|
14280
14521
|
// src/chat/tools/execute-tool.ts
|
|
14281
|
-
import { z as
|
|
14522
|
+
import { z as z64 } from "zod";
|
|
14282
14523
|
var EXECUTE_TOOL_NAME = "executeTool";
|
|
14283
14524
|
function createExecuteToolTool() {
|
|
14284
14525
|
return zodTool({
|
|
@@ -14290,11 +14531,11 @@ function createExecuteToolTool() {
|
|
|
14290
14531
|
},
|
|
14291
14532
|
description: "Execute any catalog tool by exact tool_name from searchTools or a tool-result execution hint. Put tool-specific parameters inside arguments.",
|
|
14292
14533
|
executionMode: "sequential",
|
|
14293
|
-
inputSchema:
|
|
14294
|
-
tool_name:
|
|
14534
|
+
inputSchema: z64.object({
|
|
14535
|
+
tool_name: z64.string().min(1).describe(
|
|
14295
14536
|
"Exact catalog tool_name returned by searchTools or a tool-result execution hint."
|
|
14296
14537
|
),
|
|
14297
|
-
arguments:
|
|
14538
|
+
arguments: z64.record(z64.string(), z64.unknown()).describe(
|
|
14298
14539
|
'Arguments matching the selected catalog tool schema, for example { "query": "..." }.'
|
|
14299
14540
|
).optional()
|
|
14300
14541
|
}).strict(),
|
|
@@ -14334,7 +14575,7 @@ function planToolExposure(tools) {
|
|
|
14334
14575
|
}
|
|
14335
14576
|
|
|
14336
14577
|
// src/chat/tools/search-tools.ts
|
|
14337
|
-
import { z as
|
|
14578
|
+
import { z as z65 } from "zod";
|
|
14338
14579
|
var SEARCH_TOOLS_NAME = "searchTools";
|
|
14339
14580
|
var DEFAULT_MAX_RESULTS2 = 5;
|
|
14340
14581
|
var MAX_RESULTS3 = 20;
|
|
@@ -14379,29 +14620,29 @@ var SEARCH_STOP_WORDS = /* @__PURE__ */ new Set([
|
|
|
14379
14620
|
"you",
|
|
14380
14621
|
"your"
|
|
14381
14622
|
]);
|
|
14382
|
-
var searchToolsSourceSchema =
|
|
14383
|
-
id:
|
|
14384
|
-
description:
|
|
14623
|
+
var searchToolsSourceSchema = z65.object({
|
|
14624
|
+
id: z65.string(),
|
|
14625
|
+
description: z65.string()
|
|
14385
14626
|
}).strict();
|
|
14386
|
-
var searchToolsToolSchema =
|
|
14387
|
-
tool_name:
|
|
14388
|
-
description:
|
|
14389
|
-
exposure:
|
|
14390
|
-
source:
|
|
14391
|
-
input_schema:
|
|
14392
|
-
call_notes:
|
|
14393
|
-
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())
|
|
14394
14635
|
}).strict();
|
|
14395
14636
|
var searchToolsOutputSchema = juniorToolOutputSchema.extend({
|
|
14396
|
-
query:
|
|
14397
|
-
source:
|
|
14398
|
-
sources:
|
|
14399
|
-
total_catalog_tools:
|
|
14400
|
-
total_eligible_tools:
|
|
14401
|
-
total_matches:
|
|
14402
|
-
returned_tools:
|
|
14403
|
-
execution_tool:
|
|
14404
|
-
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)
|
|
14405
14646
|
}).strict();
|
|
14406
14647
|
function terms(value) {
|
|
14407
14648
|
const chunks = value.match(/[\p{L}\p{N}]+/gu) ?? [];
|
|
@@ -14612,14 +14853,14 @@ function createSearchToolsTool(catalogTools) {
|
|
|
14612
14853
|
openWorldHint: false,
|
|
14613
14854
|
readOnlyHint: true
|
|
14614
14855
|
},
|
|
14615
|
-
inputSchema:
|
|
14616
|
-
query:
|
|
14856
|
+
inputSchema: z65.object({
|
|
14857
|
+
query: z65.string().nullable().describe(
|
|
14617
14858
|
"Optional search terms describing the tool, owner, action, or arguments needed. Empty string lists catalog tools."
|
|
14618
14859
|
).optional(),
|
|
14619
|
-
source:
|
|
14860
|
+
source: z65.string().nullable().describe(
|
|
14620
14861
|
"Optional source id to search within, such as a plugin source returned in sources."
|
|
14621
14862
|
).optional(),
|
|
14622
|
-
max_results:
|
|
14863
|
+
max_results: z65.number().int().min(1).max(MAX_RESULTS3).nullable().describe("Maximum matching catalog tool descriptors to return.").optional()
|
|
14623
14864
|
}).strict(),
|
|
14624
14865
|
outputSchema: searchToolsOutputSchema,
|
|
14625
14866
|
privateTraceResult: (result) => ({
|
|
@@ -15878,7 +16119,7 @@ function createPluginEgress(deps) {
|
|
|
15878
16119
|
}
|
|
15879
16120
|
|
|
15880
16121
|
// src/chat/services/guardian-action-review.ts
|
|
15881
|
-
import { z as
|
|
16122
|
+
import { z as z66 } from "zod";
|
|
15882
16123
|
|
|
15883
16124
|
// src/chat/services/guardian-action-policy.ts
|
|
15884
16125
|
var GUARDIAN_ACTION_POLICY = `You are judging one planned Junior agent action.
|
|
@@ -15946,17 +16187,17 @@ Assess the exact action's intrinsic risk and whether the user's intent authorize
|
|
|
15946
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.`;
|
|
15947
16188
|
|
|
15948
16189
|
// src/chat/services/guardian-action-review.ts
|
|
15949
|
-
var guardianDecisionSchema =
|
|
15950
|
-
decision:
|
|
15951
|
-
reason:
|
|
15952
|
-
riskLevel:
|
|
15953
|
-
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"])
|
|
15954
16195
|
}).strict();
|
|
15955
16196
|
var GUARDIAN_REVIEW_TIMEOUT_MS = 6e4;
|
|
15956
16197
|
var GUARDIAN_REVIEW_MAX_TOKENS = 2e3;
|
|
15957
16198
|
var MAX_PROPOSAL_CHARS = 192e3;
|
|
15958
16199
|
function guardianPrompt(proposal) {
|
|
15959
|
-
const proposalJson = JSON.stringify(
|
|
16200
|
+
const proposalJson = JSON.stringify(z66.json().parse(proposal), null, 2);
|
|
15960
16201
|
if (proposalJson.length > MAX_PROPOSAL_CHARS) {
|
|
15961
16202
|
throw new Error(
|
|
15962
16203
|
`Guardian action proposal exceeds ${MAX_PROPOSAL_CHARS} characters.`
|
|
@@ -16241,8 +16482,10 @@ async function wireAgentTools(args) {
|
|
|
16241
16482
|
actor: args.currentActor,
|
|
16242
16483
|
actors: args.currentActors
|
|
16243
16484
|
});
|
|
16485
|
+
const workspace = args.state.sandboxRef?.workspaceId ? await getWorkspace(getDb(), args.state.sandboxRef.workspaceId) : void 0;
|
|
16244
16486
|
const agentSandbox = createAgentSandbox({
|
|
16245
16487
|
sandboxRef: args.state.sandboxRef,
|
|
16488
|
+
workspace,
|
|
16246
16489
|
skills: args.availableSkills,
|
|
16247
16490
|
traceContext: args.spanContext,
|
|
16248
16491
|
tracePropagation: args.run.environment?.sandboxTracePropagation,
|
|
@@ -16253,6 +16496,7 @@ async function wireAgentTools(args) {
|
|
|
16253
16496
|
configurationValues: args.configurationValues,
|
|
16254
16497
|
getActiveSkill: () => args.skillSandbox.getActiveSkill(),
|
|
16255
16498
|
prepareSandbox: pluginHooks.prepareSandbox,
|
|
16499
|
+
prepareWorkspace: async (sandbox, recipe, signal) => await pluginHooks.prepareWorkspace(sandbox, recipe.repos, signal),
|
|
16256
16500
|
onSandboxRefChanged: args.onSandboxRefChanged,
|
|
16257
16501
|
persistSandboxRef: args.durability.onSandboxRefChanged
|
|
16258
16502
|
});
|
|
@@ -16356,7 +16600,11 @@ async function wireAgentTools(args) {
|
|
|
16356
16600
|
const toolRuntimeContext = {
|
|
16357
16601
|
...commonToolRuntimeContext,
|
|
16358
16602
|
...toolRoute,
|
|
16359
|
-
attachmentStorage: args.run.environment?.attachmentStorage
|
|
16603
|
+
attachmentStorage: args.run.environment?.attachmentStorage,
|
|
16604
|
+
workspaces: {
|
|
16605
|
+
activeWorkspaceId: () => agentSandbox.sandboxRef()?.workspaceId,
|
|
16606
|
+
switch: agentSandbox.switchWorkspace
|
|
16607
|
+
}
|
|
16360
16608
|
};
|
|
16361
16609
|
const actionReview = createToolActionReview({
|
|
16362
16610
|
context: {
|