@sentry/junior 0.195.0 → 0.196.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-hooks-VIBTIP5F.js → agent-hooks-IQLRR4RC.js} +13 -13
- package/dist/api/schema.js +3 -3
- package/dist/api.js +27 -27
- package/dist/app.d.ts +8 -2
- package/dist/app.js +102 -70
- package/dist/{catalog-runtime-6E6SGRZK.js → catalog-runtime-EM7V2F4I.js} +4 -4
- package/dist/chat/agent/handoff.d.ts +73 -0
- package/dist/chat/config.d.ts +2 -2
- package/dist/chat/model-profile.d.ts +12 -0
- package/dist/chat/no-reply.d.ts +4 -3
- package/dist/chat/services/subscribed-decision.d.ts +8 -0
- package/dist/chat/tools/types.d.ts +6 -2
- package/dist/{chunk-LMYRF6HX.js → chunk-5XSEOJPC.js} +85 -14
- package/dist/{chunk-RZ3PBNDV.js → chunk-6LQNW2CJ.js} +7 -7
- package/dist/{chunk-GFBR4S3Q.js → chunk-7NL7T6VU.js} +1 -1
- package/dist/{chunk-6GGDBXXP.js → chunk-7TUDDW3Y.js} +3 -3
- package/dist/{chunk-R5BGW4WR.js → chunk-B5WJBVHY.js} +2 -2
- package/dist/{chunk-X3PBQ4BK.js → chunk-BXIVMNLR.js} +1 -1
- package/dist/{chunk-JBSCMOLR.js → chunk-CNI74T7U.js} +6 -6
- package/dist/{chunk-HUQOXMDG.js → chunk-CTS72G4B.js} +1 -1
- package/dist/{chunk-VYDIA2UL.js → chunk-DFWJJOW3.js} +2 -6
- package/dist/{chunk-7UED4D5T.js → chunk-EEUFKVCD.js} +22 -22
- package/dist/{chunk-PYTRZZ4V.js → chunk-EFNUCRB5.js} +8 -8
- package/dist/{chunk-7MYXH5LA.js → chunk-EQBHN4JK.js} +1 -1
- package/dist/{chunk-KBPWC7NU.js → chunk-ES7KCEND.js} +1 -1
- package/dist/{chunk-RKA22BQP.js → chunk-G6YRPYDC.js} +1 -1
- package/dist/{chunk-DTYOEHUP.js → chunk-GZ336GZ5.js} +4 -4
- package/dist/{chunk-C4NY6L7S.js → chunk-I7GEGEHZ.js} +1 -1
- package/dist/{chunk-KUQRWV53.js → chunk-J357NJQ5.js} +5 -5
- package/dist/{chunk-CE2P6TOV.js → chunk-KJGH3KWA.js} +3 -3
- package/dist/{chunk-L62JVQPL.js → chunk-KZX7LORG.js} +3 -3
- package/dist/{chunk-QPZL2IYT.js → chunk-LBN67OZR.js} +1 -1
- package/dist/{chunk-HE5PZAPS.js → chunk-LCAM2P7H.js} +4 -4
- package/dist/{chunk-5NR7N567.js → chunk-LGXI6PWX.js} +4 -4
- package/dist/{chunk-RQO67SAO.js → chunk-LSPUMNZK.js} +2 -2
- package/dist/{chunk-OQHO62VA.js → chunk-N2MSPOGG.js} +8 -8
- package/dist/{chunk-PFQRZ4IB.js → chunk-NE2UQMC7.js} +7 -7
- package/dist/{chunk-D4YV5TDV.js → chunk-NHJU2ZAL.js} +11 -0
- package/dist/{chunk-FEZIEEOP.js → chunk-OVWAO5KY.js} +260 -182
- package/dist/{chunk-QHJZSYKY.js → chunk-P3LE2CSJ.js} +2 -2
- package/dist/{chunk-3VWIZVK7.js → chunk-PI6VXVBK.js} +1 -1
- package/dist/{chunk-FPQPYJEG.js → chunk-PIZJBSGZ.js} +1 -1
- package/dist/{chunk-FE3Y4KES.js → chunk-QAINJHI4.js} +5 -5
- package/dist/{chunk-5HNXLP4W.js → chunk-RAWYH7TW.js} +1 -1
- package/dist/{chunk-R5OHONYU.js → chunk-RFNMWONZ.js} +6 -6
- package/dist/{chunk-QKHZF2LH.js → chunk-S74KAE77.js} +4 -4
- package/dist/{chunk-LM7UE523.js → chunk-SR5FS2JP.js} +3 -3
- package/dist/{chunk-N67T4VY3.js → chunk-VKLQ2M7V.js} +9 -9
- package/dist/{chunk-I4RH3KLJ.js → chunk-VRHZXY5X.js} +1 -1
- package/dist/{chunk-7PQMTME5.js → chunk-VSOO3Y6M.js} +1 -1
- package/dist/{chunk-BJZML4RT.js → chunk-VVU7GHIZ.js} +9 -9
- package/dist/{chunk-6TRQLG3D.js → chunk-VXAQTJSR.js} +1 -1
- package/dist/{chunk-KQ3GZGBK.js → chunk-XNXKRWWI.js} +4 -4
- package/dist/cli/chat.js +35 -35
- package/dist/cli/check.js +5 -5
- package/dist/cli/plugins.js +14 -14
- package/dist/cli/snapshot-create.js +10 -10
- package/dist/cli/upgrade.js +7 -7
- package/dist/{db-FVCSDROR.js → db-YTM7ZXPK.js} +8 -8
- package/dist/instrumentation.js +3 -3
- package/dist/nitro.js +7 -7
- package/dist/{oauth-callback-server-Z5PXTDOE.js → oauth-callback-server-OXW4KQLQ.js} +31 -31
- package/dist/{runner-RHYU7OGV.js → runner-RJY5RNJO.js} +23 -23
- package/dist/{skills-QTN73DN5.js → skills-WZV6NLFY.js} +5 -5
- package/dist/spawn-J7SQJLYF.js +42 -0
- package/dist/task-runner-SMUQ5464.js +36 -0
- package/dist/{validation-2ZK7GA6N.js → validation-XS5ZHV3W.js} +5 -5
- package/dist/version.js +1 -1
- package/dist/{work-7IBKSZRU.js → work-LJMSDEY3.js} +23 -23
- package/dist/worker-NMFZ7A2N.js +24 -0
- package/package.json +5 -5
- package/dist/spawn-R56OWLUH.js +0 -42
- package/dist/task-runner-LLJZTLRP.js +0 -36
- package/dist/worker-RNVQVCO7.js +0 -24
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
PluginCredentialFailureError,
|
|
8
8
|
agentNameSchema,
|
|
9
9
|
createPluginAuthOrchestration
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-CNI74T7U.js";
|
|
11
11
|
import {
|
|
12
12
|
parseSandboxEgressAuthRequiredSignal,
|
|
13
13
|
parseSandboxEgressPermissionDeniedSignal,
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
searchSlackUsers,
|
|
39
39
|
selectPluginGrant,
|
|
40
40
|
toMcpProviderError
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-N2MSPOGG.js";
|
|
42
42
|
import {
|
|
43
43
|
RetryableDeliveryError,
|
|
44
44
|
actorFromRun,
|
|
@@ -53,20 +53,19 @@ import {
|
|
|
53
53
|
surfaceFromRun,
|
|
54
54
|
toolInvocationDestination,
|
|
55
55
|
uploadFilesToConversation
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-RFNMWONZ.js";
|
|
57
57
|
import {
|
|
58
58
|
CooperativeTurnYieldError,
|
|
59
59
|
NO_REPLY_MARKER,
|
|
60
60
|
TurnInputCommitLostError,
|
|
61
61
|
abandonReplacedPendingAuth,
|
|
62
62
|
canReusePendingAuthLink,
|
|
63
|
-
containsNoReplyMarker,
|
|
64
63
|
decideReply,
|
|
65
64
|
getAssistantReplyText,
|
|
66
65
|
isNoReplyMarker,
|
|
67
66
|
isTurnInputCommitLostError,
|
|
68
67
|
sanitizeAssistantText
|
|
69
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-DFWJJOW3.js";
|
|
70
69
|
import {
|
|
71
70
|
AGENTS_REMOVAL_NOTICE,
|
|
72
71
|
AGENTS_REPLACEMENT_NOTICE,
|
|
@@ -122,7 +121,7 @@ import {
|
|
|
122
121
|
stripRuntimeTurnContext,
|
|
123
122
|
trimTrailingAssistantMessages,
|
|
124
123
|
truncateText
|
|
125
|
-
} from "./chunk-
|
|
124
|
+
} from "./chunk-6LQNW2CJ.js";
|
|
126
125
|
import {
|
|
127
126
|
SCHEDULED_TASK_SYSTEM_ACTOR,
|
|
128
127
|
WORKSPACE_SNAPSHOT_FAILED_EVENT,
|
|
@@ -163,13 +162,13 @@ import {
|
|
|
163
162
|
workspaceSnapshotFinishedEvent,
|
|
164
163
|
workspaceSnapshotWatch,
|
|
165
164
|
writableEventTask
|
|
166
|
-
} from "./chunk-
|
|
165
|
+
} from "./chunk-GZ336GZ5.js";
|
|
167
166
|
import {
|
|
168
167
|
parseSlackThreadId
|
|
169
|
-
} from "./chunk-
|
|
168
|
+
} from "./chunk-VXAQTJSR.js";
|
|
170
169
|
import {
|
|
171
170
|
appendAndEnqueueInboundMessage
|
|
172
|
-
} from "./chunk-
|
|
171
|
+
} from "./chunk-S74KAE77.js";
|
|
173
172
|
import {
|
|
174
173
|
SHORT_TITLE_MAX_LENGTH,
|
|
175
174
|
ToolInputError,
|
|
@@ -177,7 +176,7 @@ import {
|
|
|
177
176
|
generateShortTitle,
|
|
178
177
|
hasAgentTurnUsage,
|
|
179
178
|
resolveTaskTitle
|
|
180
|
-
} from "./chunk-
|
|
179
|
+
} from "./chunk-B5WJBVHY.js";
|
|
181
180
|
import {
|
|
182
181
|
bindSandboxFileSystem,
|
|
183
182
|
createSandboxSession,
|
|
@@ -188,7 +187,7 @@ import {
|
|
|
188
187
|
resolve,
|
|
189
188
|
setSnapshotSpanAttributes,
|
|
190
189
|
stopSession
|
|
191
|
-
} from "./chunk-
|
|
190
|
+
} from "./chunk-KZX7LORG.js";
|
|
192
191
|
import {
|
|
193
192
|
privateTraceResultAttributes
|
|
194
193
|
} from "./chunk-UIE3R5XU.js";
|
|
@@ -198,7 +197,7 @@ import {
|
|
|
198
197
|
} from "./chunk-X6GDDWQH.js";
|
|
199
198
|
import {
|
|
200
199
|
getTurnRequestDeadline
|
|
201
|
-
} from "./chunk-
|
|
200
|
+
} from "./chunk-VRHZXY5X.js";
|
|
202
201
|
import {
|
|
203
202
|
getVercelConversationWorkQueue
|
|
204
203
|
} from "./chunk-DKIJ2RP5.js";
|
|
@@ -245,7 +244,7 @@ import {
|
|
|
245
244
|
updateWorkspace,
|
|
246
245
|
withSlackRetries,
|
|
247
246
|
workspaceRepoCheckoutPath
|
|
248
|
-
} from "./chunk-
|
|
247
|
+
} from "./chunk-NE2UQMC7.js";
|
|
249
248
|
import {
|
|
250
249
|
JUNIOR_THREAD_STATE_TTL_MS
|
|
251
250
|
} from "./chunk-3Y47VMHV.js";
|
|
@@ -256,12 +255,12 @@ import {
|
|
|
256
255
|
getConversationStore,
|
|
257
256
|
getDb,
|
|
258
257
|
getSqlExecutor
|
|
259
|
-
} from "./chunk-
|
|
258
|
+
} from "./chunk-XNXKRWWI.js";
|
|
260
259
|
import {
|
|
261
260
|
juniorArtifacts,
|
|
262
261
|
juniorIdentities,
|
|
263
262
|
juniorSchedulerRuns
|
|
264
|
-
} from "./chunk-
|
|
263
|
+
} from "./chunk-PIZJBSGZ.js";
|
|
265
264
|
import {
|
|
266
265
|
SANDBOX_DATA_ROOT,
|
|
267
266
|
SANDBOX_REPOS_ROOT,
|
|
@@ -292,19 +291,19 @@ import {
|
|
|
292
291
|
throwSandboxOperationError,
|
|
293
292
|
workspaceSnapshotNotReadyUserMessage,
|
|
294
293
|
wrapSandboxSetupError
|
|
295
|
-
} from "./chunk-
|
|
294
|
+
} from "./chunk-SR5FS2JP.js";
|
|
296
295
|
import {
|
|
297
296
|
fenceLock,
|
|
298
297
|
getStateAdapter,
|
|
299
298
|
withLock
|
|
300
|
-
} from "./chunk-
|
|
299
|
+
} from "./chunk-EQBHN4JK.js";
|
|
301
300
|
import {
|
|
302
301
|
KNOWN_CONVERSATION_EVENT_TYPES,
|
|
303
302
|
contextProvenance,
|
|
304
303
|
instructionActors,
|
|
305
304
|
instructionProvenanceFor,
|
|
306
305
|
sameActorIdentity
|
|
307
|
-
} from "./chunk-
|
|
306
|
+
} from "./chunk-7NL7T6VU.js";
|
|
308
307
|
import {
|
|
309
308
|
ACTIVE_TURN_COMPACTION_SUMMARY_PREFIX,
|
|
310
309
|
COMPACTION_SUMMARY_PREFIX,
|
|
@@ -330,14 +329,16 @@ import {
|
|
|
330
329
|
resolveGatewayCredential,
|
|
331
330
|
resolveGatewayModel,
|
|
332
331
|
unwrapCurrentInstruction
|
|
333
|
-
} from "./chunk-
|
|
332
|
+
} from "./chunk-5XSEOJPC.js";
|
|
334
333
|
import {
|
|
335
334
|
ModelProfileNotConfiguredError,
|
|
336
335
|
TURN_REASONING_LEVELS,
|
|
336
|
+
formatModelProfile,
|
|
337
|
+
formatModelProfiles,
|
|
337
338
|
modelIdForProfile,
|
|
338
339
|
modelProfileSchema,
|
|
339
340
|
profileConfig
|
|
340
|
-
} from "./chunk-
|
|
341
|
+
} from "./chunk-NHJU2ZAL.js";
|
|
341
342
|
import {
|
|
342
343
|
canExposeConversationPayload,
|
|
343
344
|
resolveConversationPrivacy,
|
|
@@ -347,16 +348,16 @@ import {
|
|
|
347
348
|
toGenAiMessagesTraceAttributes,
|
|
348
349
|
toGenAiPayloadMetadata,
|
|
349
350
|
toGenAiPayloadTraceAttributes
|
|
350
|
-
} from "./chunk-
|
|
351
|
+
} from "./chunk-ES7KCEND.js";
|
|
351
352
|
import {
|
|
352
353
|
discoverSkills,
|
|
353
354
|
findSkillByName,
|
|
354
355
|
loadSkillsByName,
|
|
355
356
|
parseSkillInvocation
|
|
356
|
-
} from "./chunk-
|
|
357
|
+
} from "./chunk-LSPUMNZK.js";
|
|
357
358
|
import {
|
|
358
359
|
pluginCatalogRuntime
|
|
359
|
-
} from "./chunk-
|
|
360
|
+
} from "./chunk-G6YRPYDC.js";
|
|
360
361
|
import {
|
|
361
362
|
CredentialUnavailableError,
|
|
362
363
|
OAuthProviderError,
|
|
@@ -364,7 +365,7 @@ import {
|
|
|
364
365
|
getOAuthProviderErrorAttributes,
|
|
365
366
|
resolveAuthTokenPlaceholder,
|
|
366
367
|
resolvePluginCommandEnv
|
|
367
|
-
} from "./chunk-
|
|
368
|
+
} from "./chunk-BXIVMNLR.js";
|
|
368
369
|
import {
|
|
369
370
|
credentialContextForActor,
|
|
370
371
|
credentialUserSubjectId
|
|
@@ -400,7 +401,7 @@ import {
|
|
|
400
401
|
summarizeMessageText,
|
|
401
402
|
withLogContext,
|
|
402
403
|
withSpan
|
|
403
|
-
} from "./chunk-
|
|
404
|
+
} from "./chunk-CTS72G4B.js";
|
|
404
405
|
import {
|
|
405
406
|
startInactiveSpan,
|
|
406
407
|
withActiveSpan
|
|
@@ -924,11 +925,6 @@ function buildTurnResult(input) {
|
|
|
924
925
|
if (!isProviderError) {
|
|
925
926
|
logInfo("ai.no_reply_marker.accepted", markerAttributes);
|
|
926
927
|
}
|
|
927
|
-
} else if (containsNoReplyMarker(rawPrimaryText)) {
|
|
928
|
-
logWarn("ai.no_reply_marker.mixed_text", {
|
|
929
|
-
"app.ai.no_reply_marker": true,
|
|
930
|
-
"app.ai.no_reply_marker_mode": "mixed"
|
|
931
|
-
});
|
|
932
928
|
}
|
|
933
929
|
if (!primaryText && !completedWithoutTerminalText && !isProviderError) {
|
|
934
930
|
logWarn("ai.model_response.empty", {
|
|
@@ -1146,11 +1142,11 @@ function trimContextForRouter(text) {
|
|
|
1146
1142
|
originalCharCount: trimmed.length
|
|
1147
1143
|
};
|
|
1148
1144
|
}
|
|
1149
|
-
function buildClassifierSystemPrompt(profileNames, defaultProfile) {
|
|
1145
|
+
function buildClassifierSystemPrompt(profiles, profileNames, defaultProfile) {
|
|
1146
|
+
const profileList = formatModelProfiles(profiles, profileNames);
|
|
1150
1147
|
return [
|
|
1151
1148
|
"You choose the model profile most likely to produce a complete, source-grounded answer.",
|
|
1152
1149
|
"Choose exactly one bucket: none, low, medium, high, or xhigh.",
|
|
1153
|
-
`Choose profile from the configured profiles: ${profileNames.join(", ")}.`,
|
|
1154
1150
|
"Choose profile independently from the reasoning bucket.",
|
|
1155
1151
|
"",
|
|
1156
1152
|
"Use none only for greetings, acknowledgments, and turns that need no substantive assistant work.",
|
|
@@ -1159,9 +1155,11 @@ function buildClassifierSystemPrompt(profileNames, defaultProfile) {
|
|
|
1159
1155
|
"Use high for research-heavy work, non-trivial drafting, or explicit requests to be thorough.",
|
|
1160
1156
|
"Use xhigh for the most complex tasks: code changes, debugging/root-cause analysis, broad refactors, architecture decisions, multi-file implementation, or any task where deep reasoning across multiple systems or files is required.",
|
|
1161
1157
|
"When unsure between two non-none buckets, choose the higher bucket. Do not use low as the default.",
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
"
|
|
1158
|
+
"",
|
|
1159
|
+
`Default profile: "${defaultProfile}". Keep it unless another profile's description is a clearly better fit.`,
|
|
1160
|
+
"Configured profiles (use each description's use and avoid cases; names are labels only; non-default does not mean stronger):",
|
|
1161
|
+
profileList,
|
|
1162
|
+
"Choose a non-default profile only when its description clearly fits the task. If no description clearly fits, keep the default profile.",
|
|
1165
1163
|
"",
|
|
1166
1164
|
"Classify based on the substance of the task, not the length of the current message. When the current instruction is a short affirmation (for example: 'go', 'do it', 'yes please', 'proceed') and prior thread context contains a pending task, classify the pending task \u2014 not the affirmation.",
|
|
1167
1165
|
"",
|
|
@@ -1299,6 +1297,7 @@ async function classifyTurn(args) {
|
|
|
1299
1297
|
prompt: args.prompt,
|
|
1300
1298
|
thinkingLevel: "low",
|
|
1301
1299
|
system: buildClassifierSystemPrompt(
|
|
1300
|
+
args.profiles,
|
|
1302
1301
|
Object.keys(args.profiles),
|
|
1303
1302
|
args.defaultProfile
|
|
1304
1303
|
),
|
|
@@ -1733,7 +1732,7 @@ var TOOL_POLICY_RULES = [
|
|
|
1733
1732
|
"- Event tasks make the task creator's connected credentials available by default when the requested work needs user-bound authorization. Do not ask for separate confirmation merely to use credentials needed for the requested work. On creation, omit credentialMode for the creator default and set system only when the creator explicitly requires it. For later changes, creator always means the task's original createdBy actor, never the current requester. If the requester is not that creator, do not attempt to enable creator credential use or suggest that confirmation could authorize it.",
|
|
1734
1733
|
"- Event tasks list for the current destination, not one thread. Public tasks can also be updated or deleted by task id from another destination in the same workspace. When listing them, use createdBy to explain creator-only credential changes and warn when triggerAvailable is false; an unavailable task remains stored but cannot receive events until its plugin event is enabled again.",
|
|
1735
1734
|
"- Scheduled tasks make the task creator's connected credentials available by default when the requested work needs user-bound authorization. Do not ask for separate confirmation merely to use credentials needed for the requested work. On creation, omit credential_mode for the creator default and set system only when the creator explicitly requires it. For later changes, creator always means the task's original created_by actor, never the current requester. If the requester is not that creator, do not attempt to enable creator credential use or suggest that confirmation could authorize it.",
|
|
1736
|
-
"-
|
|
1735
|
+
"- When another model profile fits the task better, call `handoff` before substantial work. Follow the profile list and selection rules in the tool description.",
|
|
1737
1736
|
"- Run `jr-rpc config get|set|unset|list` for provider defaults and `jr-rpc plugins list` for installed plugin introspection as standalone bash commands; do not chain them with `cd`, `&&`, pipes, or provider commands.",
|
|
1738
1737
|
"- If the first result is empty, stale, ambiguous, or incomplete, try a focused alternate query, path, command, or source before concluding the answer cannot be verified."
|
|
1739
1738
|
];
|
|
@@ -3452,7 +3451,7 @@ async function maybePostAutomatedTurnLimitNotice(args) {
|
|
|
3452
3451
|
function replyContractLines() {
|
|
3453
3452
|
return [
|
|
3454
3453
|
"When you reply, follow any reply format in the instructions.",
|
|
3455
|
-
`If no visible reply is needed,
|
|
3454
|
+
`If no visible reply is needed, your final assistant message must be exactly ${NO_REPLY_MARKER} and nothing else.`,
|
|
3456
3455
|
"Otherwise briefly summarize what you acted on and what you did or need next."
|
|
3457
3456
|
];
|
|
3458
3457
|
}
|
|
@@ -14258,12 +14257,19 @@ function stripReplacementHistoryField(value) {
|
|
|
14258
14257
|
// src/chat/tools/handoff/tool.ts
|
|
14259
14258
|
import { z as z59 } from "zod";
|
|
14260
14259
|
var HANDOFF_TOOL_NAME = "handoff";
|
|
14260
|
+
function formatHandoffProfiles(handoff) {
|
|
14261
|
+
return handoff.profiles.map(
|
|
14262
|
+
(profile) => `- ${formatModelProfile(profile.name, profile.description)}`
|
|
14263
|
+
).join("\n");
|
|
14264
|
+
}
|
|
14261
14265
|
function createHandoffTool(handoff) {
|
|
14262
|
-
const profileSchema = z59.enum(
|
|
14266
|
+
const profileSchema = z59.enum(
|
|
14267
|
+
handoff.profiles.map((profile) => profile.name)
|
|
14268
|
+
);
|
|
14263
14269
|
const handoffResultSchema = juniorToolOutputSchema.extend({
|
|
14264
14270
|
model_profile: modelProfileSchema
|
|
14265
14271
|
});
|
|
14266
|
-
const
|
|
14272
|
+
const profileList = formatHandoffProfiles(handoff);
|
|
14267
14273
|
return zodTool({
|
|
14268
14274
|
annotations: {
|
|
14269
14275
|
destructiveHint: false,
|
|
@@ -14271,10 +14277,21 @@ function createHandoffTool(handoff) {
|
|
|
14271
14277
|
openWorldHint: false,
|
|
14272
14278
|
readOnlyHint: false
|
|
14273
14279
|
},
|
|
14274
|
-
description:
|
|
14280
|
+
description: [
|
|
14281
|
+
"Switch this conversation to another configured model profile and continue the same task.",
|
|
14282
|
+
"Call this as the only tool in the assistant turn, before substantial analysis or implementation, when a listed profile's description fits the task better than the current profile.",
|
|
14283
|
+
"Use each description's use and avoid cases. Do not select by the profile name or assume that a non-default profile is stronger.",
|
|
14284
|
+
"Do not call this for ordinary lookups, short answers, light investigation, or only because the task mentions code.",
|
|
14285
|
+
"Do not call this after you have done the difficult work on the current profile. Do not combine it with other tools in the same assistant message.",
|
|
14286
|
+
"A successful handoff becomes the active profile for later turns. Another handoff can change it again.",
|
|
14287
|
+
`Available profiles:
|
|
14288
|
+
${profileList}`
|
|
14289
|
+
].join(" "),
|
|
14275
14290
|
executionMode: "sequential",
|
|
14276
14291
|
inputSchema: z59.object({
|
|
14277
|
-
profile: profileSchema.describe(
|
|
14292
|
+
profile: profileSchema.describe(
|
|
14293
|
+
"Exact configured profile name. Choose the profile whose description best fits the remaining task. If none clearly fits better, do not call handoff."
|
|
14294
|
+
)
|
|
14278
14295
|
}).strict(),
|
|
14279
14296
|
outputSchema: handoffResultSchema,
|
|
14280
14297
|
execute: async (input, options) => {
|
|
@@ -18987,6 +19004,145 @@ ${summary}`
|
|
|
18987
19004
|
return { compacted: true, piMessages: messages };
|
|
18988
19005
|
}
|
|
18989
19006
|
|
|
19007
|
+
// src/chat/agent/handoff.ts
|
|
19008
|
+
var EXCLUSIVE_TOOL_NAMES = [HANDOFF_TOOL_NAME, "switchWorkspace"];
|
|
19009
|
+
function exclusiveToolName(toolCalls) {
|
|
19010
|
+
for (const name of EXCLUSIVE_TOOL_NAMES) {
|
|
19011
|
+
if (toolCalls.some((call) => call.name === name)) {
|
|
19012
|
+
return name;
|
|
19013
|
+
}
|
|
19014
|
+
}
|
|
19015
|
+
return void 0;
|
|
19016
|
+
}
|
|
19017
|
+
function handoffControl(args) {
|
|
19018
|
+
if (!args.enabled) {
|
|
19019
|
+
return void 0;
|
|
19020
|
+
}
|
|
19021
|
+
const profileNames = [
|
|
19022
|
+
botConfig.defaultProfile,
|
|
19023
|
+
...Object.keys(botConfig.profiles).filter((profile) => profile !== botConfig.defaultProfile).sort()
|
|
19024
|
+
].filter((profile) => profile !== args.activeProfile);
|
|
19025
|
+
const [firstProfileName, ...otherProfileNames] = profileNames;
|
|
19026
|
+
if (!firstProfileName) {
|
|
19027
|
+
return void 0;
|
|
19028
|
+
}
|
|
19029
|
+
const toHandoffProfile = (name) => ({
|
|
19030
|
+
name,
|
|
19031
|
+
description: profileConfig(botConfig, name).description
|
|
19032
|
+
});
|
|
19033
|
+
return {
|
|
19034
|
+
profiles: [
|
|
19035
|
+
toHandoffProfile(firstProfileName),
|
|
19036
|
+
...otherProfileNames.map(toHandoffProfile)
|
|
19037
|
+
],
|
|
19038
|
+
execute: args.execute
|
|
19039
|
+
};
|
|
19040
|
+
}
|
|
19041
|
+
function toolsForHandoffProfile(args) {
|
|
19042
|
+
const control = handoffControl({
|
|
19043
|
+
activeProfile: args.activeProfile,
|
|
19044
|
+
enabled: args.enabled,
|
|
19045
|
+
execute: args.execute
|
|
19046
|
+
});
|
|
19047
|
+
if (!control) {
|
|
19048
|
+
return args.agentTools.filter((tool) => tool.name !== HANDOFF_TOOL_NAME);
|
|
19049
|
+
}
|
|
19050
|
+
const handoffAgentTool = args.agentTools.find(
|
|
19051
|
+
(tool) => tool.name === HANDOFF_TOOL_NAME
|
|
19052
|
+
);
|
|
19053
|
+
if (!handoffAgentTool) {
|
|
19054
|
+
throw new Error("Handoff control is missing its Pi tool");
|
|
19055
|
+
}
|
|
19056
|
+
const definition = createHandoffTool(control);
|
|
19057
|
+
return args.agentTools.map(
|
|
19058
|
+
(tool) => tool.name === HANDOFF_TOOL_NAME ? {
|
|
19059
|
+
...handoffAgentTool,
|
|
19060
|
+
description: definition.description,
|
|
19061
|
+
parameters: definition.inputSchema,
|
|
19062
|
+
prepareArguments: definition.prepareArguments
|
|
19063
|
+
} : tool
|
|
19064
|
+
);
|
|
19065
|
+
}
|
|
19066
|
+
async function commitHandoff(args) {
|
|
19067
|
+
if (args.profile === args.activeModelProfile) {
|
|
19068
|
+
return void 0;
|
|
19069
|
+
}
|
|
19070
|
+
const runtimeContext = retainRuntimeTurnContext(
|
|
19071
|
+
args.runtimeContextSourceMessages ?? args.sourceMessages
|
|
19072
|
+
);
|
|
19073
|
+
const phaseUsageSummary = extractGenAiUsageSummary(
|
|
19074
|
+
...args.sourceMessages.slice(args.beforeMessageCount).filter(isAssistantMessage)
|
|
19075
|
+
);
|
|
19076
|
+
const phaseUsage = hasAgentTurnUsage(phaseUsageSummary) ? phaseUsageSummary : void 0;
|
|
19077
|
+
const selectedProfile = profileConfig(botConfig, args.profile);
|
|
19078
|
+
const handoffReasoningLevel = selectedProfile.reasoningLevel ?? args.turnRoute.reasoningLevel;
|
|
19079
|
+
const target = {
|
|
19080
|
+
modelId: selectedProfile.modelId,
|
|
19081
|
+
modelProfile: args.profile,
|
|
19082
|
+
reasoningLevel: handoffReasoningLevel
|
|
19083
|
+
};
|
|
19084
|
+
void (async () => {
|
|
19085
|
+
await args.onStatus?.({ text: "Switching models" });
|
|
19086
|
+
})().catch((error) => {
|
|
19087
|
+
logWarn("assistant.status.observer.failed", {
|
|
19088
|
+
"exception.message": error instanceof Error ? error.message : String(error)
|
|
19089
|
+
});
|
|
19090
|
+
});
|
|
19091
|
+
const handoffMessages = await compactContextForHandoff(
|
|
19092
|
+
{
|
|
19093
|
+
conversationContext: args.conversationContext,
|
|
19094
|
+
conversationId: args.conversationId,
|
|
19095
|
+
piMessages: args.sourceMessages,
|
|
19096
|
+
runtimeContext,
|
|
19097
|
+
signal: args.signal,
|
|
19098
|
+
triggeringToolCallId: args.triggeringToolCallId,
|
|
19099
|
+
target,
|
|
19100
|
+
metadata: args.metadata
|
|
19101
|
+
},
|
|
19102
|
+
{
|
|
19103
|
+
completeText: (completeArgs) => completeText(completeArgs)
|
|
19104
|
+
}
|
|
19105
|
+
);
|
|
19106
|
+
const turnRoute = handoffReasoningLevel === args.turnRoute.reasoningLevel ? args.turnRoute : {
|
|
19107
|
+
...args.turnRoute,
|
|
19108
|
+
reasoningLevel: handoffReasoningLevel,
|
|
19109
|
+
reason: `profile_reasoning_override:${args.profile}:${args.turnRoute.reason}`
|
|
19110
|
+
};
|
|
19111
|
+
return {
|
|
19112
|
+
messages: handoffMessages,
|
|
19113
|
+
model: resolveGatewayModel(target.modelId),
|
|
19114
|
+
modelId: target.modelId,
|
|
19115
|
+
modelProfile: args.profile,
|
|
19116
|
+
phaseUsage,
|
|
19117
|
+
thinkingLevel: toPiReasoningLevel(handoffReasoningLevel),
|
|
19118
|
+
turnRoute
|
|
19119
|
+
};
|
|
19120
|
+
}
|
|
19121
|
+
function applyHandoff(args) {
|
|
19122
|
+
const replacement = [...args.pending.messages];
|
|
19123
|
+
args.agent.state.messages = replacement;
|
|
19124
|
+
args.agent.state.model = args.pending.model;
|
|
19125
|
+
args.agent.state.thinkingLevel = args.pending.thinkingLevel;
|
|
19126
|
+
args.agent.state.tools = args.tools;
|
|
19127
|
+
args.resume.setBeforeMessageCount(replacement.length);
|
|
19128
|
+
args.resume.setTurnStartMessageIndex(0);
|
|
19129
|
+
args.resume.adoptCommittedBoundary(replacement);
|
|
19130
|
+
setSpanAttributes({
|
|
19131
|
+
"gen_ai.agent.model": args.pending.modelId,
|
|
19132
|
+
"gen_ai.agent.model_profile": args.pending.modelProfile,
|
|
19133
|
+
"gen_ai.agent.reasoning.level": args.pending.turnRoute.reasoningLevel
|
|
19134
|
+
});
|
|
19135
|
+
return {
|
|
19136
|
+
context: {
|
|
19137
|
+
systemPrompt: args.baseInstructions,
|
|
19138
|
+
messages: replacement,
|
|
19139
|
+
tools: args.tools
|
|
19140
|
+
},
|
|
19141
|
+
model: args.pending.model,
|
|
19142
|
+
thinkingLevel: args.pending.thinkingLevel
|
|
19143
|
+
};
|
|
19144
|
+
}
|
|
19145
|
+
|
|
18990
19146
|
// src/chat/agent/index.ts
|
|
18991
19147
|
var AGENT_ABORT_SETTLE_GRACE_MS = 5e3;
|
|
18992
19148
|
async function readRunConversationVisibility(conversationId) {
|
|
@@ -19382,93 +19538,56 @@ async function executeAgentRunInPrivacyContext(run, conversationPrivacy, runLogC
|
|
|
19382
19538
|
activeModelProfile = routedModelProfile;
|
|
19383
19539
|
activeModelId = routedModelId;
|
|
19384
19540
|
let pendingPiHookError;
|
|
19385
|
-
let pendingHandoff;
|
|
19386
19541
|
const currentAgentMessages = () => agent ? [...agent.state.messages] : [];
|
|
19387
|
-
const handoffProfiles = [
|
|
19388
|
-
botConfig.defaultProfile,
|
|
19389
|
-
...Object.keys(botConfig.profiles).filter((profile) => profile !== botConfig.defaultProfile).sort()
|
|
19390
|
-
];
|
|
19391
19542
|
const usageSinceCurrentBoundary = (messages) => {
|
|
19392
19543
|
const usage = extractGenAiUsageSummary(
|
|
19393
19544
|
...messages.slice(runResume.beforeMessageCount).filter(isAssistantMessage)
|
|
19394
19545
|
);
|
|
19395
19546
|
return hasAgentTurnUsage(usage) ? usage : void 0;
|
|
19396
19547
|
};
|
|
19548
|
+
let baseInstructions = "";
|
|
19549
|
+
let pendingHandoff;
|
|
19550
|
+
const handoffMetadata = {
|
|
19551
|
+
threadId: conversationId,
|
|
19552
|
+
channelId: slackChannelId,
|
|
19553
|
+
actorId: slackActor?.userId,
|
|
19554
|
+
runId
|
|
19555
|
+
};
|
|
19397
19556
|
const scheduleHandoff = async (args) => {
|
|
19398
|
-
|
|
19399
|
-
|
|
19400
|
-
|
|
19401
|
-
|
|
19402
|
-
|
|
19403
|
-
|
|
19404
|
-
|
|
19405
|
-
|
|
19406
|
-
|
|
19407
|
-
|
|
19408
|
-
|
|
19409
|
-
|
|
19410
|
-
|
|
19411
|
-
};
|
|
19412
|
-
const handoffModel = resolveGatewayModel(target.modelId);
|
|
19413
|
-
const handoffThinkingLevel = toPiReasoningLevel(handoffReasoningLevel);
|
|
19414
|
-
void (async () => {
|
|
19415
|
-
await observers.onStatus?.({ text: "Switching models" });
|
|
19416
|
-
})().catch((error) => {
|
|
19417
|
-
logWarn("assistant.status.observer.failed", {
|
|
19418
|
-
"exception.message": error instanceof Error ? error.message : String(error)
|
|
19419
|
-
});
|
|
19557
|
+
const pending = await commitHandoff({
|
|
19558
|
+
activeModelProfile,
|
|
19559
|
+
beforeMessageCount: runResume.beforeMessageCount,
|
|
19560
|
+
conversationContext: input.conversationContext,
|
|
19561
|
+
conversationId,
|
|
19562
|
+
metadata: handoffMetadata,
|
|
19563
|
+
onStatus: observers.onStatus,
|
|
19564
|
+
profile: args.profile,
|
|
19565
|
+
runtimeContextSourceMessages: args.runtimeContextSourceMessages,
|
|
19566
|
+
signal: args.signal,
|
|
19567
|
+
sourceMessages: args.sourceMessages,
|
|
19568
|
+
triggeringToolCallId: args.triggeringToolCallId,
|
|
19569
|
+
turnRoute
|
|
19420
19570
|
});
|
|
19421
|
-
|
|
19422
|
-
|
|
19423
|
-
conversationContext: input.conversationContext,
|
|
19424
|
-
conversationId,
|
|
19425
|
-
piMessages: args.sourceMessages,
|
|
19426
|
-
runtimeContext,
|
|
19427
|
-
signal: args.signal,
|
|
19428
|
-
triggeringToolCallId: args.triggeringToolCallId,
|
|
19429
|
-
target,
|
|
19430
|
-
metadata: {
|
|
19431
|
-
threadId: conversationId,
|
|
19432
|
-
channelId: slackChannelId,
|
|
19433
|
-
actorId: slackActor?.userId,
|
|
19434
|
-
runId
|
|
19435
|
-
}
|
|
19436
|
-
},
|
|
19437
|
-
{
|
|
19438
|
-
completeText: (args2) => completeText(args2)
|
|
19439
|
-
}
|
|
19440
|
-
);
|
|
19441
|
-
if (handoffReasoningLevel !== turnRoute.reasoningLevel) {
|
|
19442
|
-
turnRoute = {
|
|
19443
|
-
...turnRoute,
|
|
19444
|
-
reasoningLevel: handoffReasoningLevel,
|
|
19445
|
-
reason: `profile_reasoning_override:${args.profile}:${turnRoute.reason}`
|
|
19446
|
-
};
|
|
19571
|
+
if (!pending) {
|
|
19572
|
+
return;
|
|
19447
19573
|
}
|
|
19448
|
-
priorPhaseUsage = addAgentTurnUsage(priorPhaseUsage, phaseUsage);
|
|
19449
|
-
pendingHandoff =
|
|
19450
|
-
|
|
19451
|
-
|
|
19452
|
-
|
|
19453
|
-
};
|
|
19454
|
-
activeModelProfile = args.profile;
|
|
19455
|
-
activeModelId = target.modelId;
|
|
19574
|
+
priorPhaseUsage = addAgentTurnUsage(priorPhaseUsage, pending.phaseUsage);
|
|
19575
|
+
pendingHandoff = pending;
|
|
19576
|
+
activeModelProfile = pending.modelProfile;
|
|
19577
|
+
activeModelId = pending.modelId;
|
|
19578
|
+
turnRoute = pending.turnRoute;
|
|
19456
19579
|
};
|
|
19457
|
-
const
|
|
19458
|
-
|
|
19459
|
-
|
|
19460
|
-
|
|
19461
|
-
|
|
19462
|
-
|
|
19463
|
-
|
|
19464
|
-
|
|
19465
|
-
|
|
19466
|
-
|
|
19467
|
-
|
|
19468
|
-
})
|
|
19469
|
-
} : void 0;
|
|
19470
|
-
};
|
|
19471
|
-
const requestHandoff = handoffEnabled ? handoffControlFor(activeModelProfile) : void 0;
|
|
19580
|
+
const handoffExecute = async (profile, options) => await scheduleHandoff({
|
|
19581
|
+
profile,
|
|
19582
|
+
signal: options.signal,
|
|
19583
|
+
sourceMessages: [...agent.state.messages],
|
|
19584
|
+
triggeringToolCallId: options.toolCallId
|
|
19585
|
+
});
|
|
19586
|
+
const requestHandoff = handoffControl({
|
|
19587
|
+
activeProfile: activeModelProfile,
|
|
19588
|
+
enabled: handoffEnabled,
|
|
19589
|
+
execute: handoffExecute
|
|
19590
|
+
});
|
|
19472
19591
|
setTags({
|
|
19473
19592
|
...runLogContext,
|
|
19474
19593
|
modelId: activeModelId
|
|
@@ -19529,32 +19648,27 @@ async function executeAgentRunInPrivacyContext(run, conversationPrivacy, runLogC
|
|
|
19529
19648
|
await recordAgentsTransition(initialRepositoryInstructions);
|
|
19530
19649
|
}
|
|
19531
19650
|
const getPendingAuthPause = wiring.getPendingAuthPause;
|
|
19532
|
-
const
|
|
19533
|
-
(
|
|
19534
|
-
|
|
19535
|
-
|
|
19536
|
-
|
|
19537
|
-
|
|
19538
|
-
|
|
19539
|
-
|
|
19540
|
-
|
|
19541
|
-
|
|
19542
|
-
|
|
19543
|
-
|
|
19544
|
-
|
|
19545
|
-
|
|
19546
|
-
|
|
19547
|
-
|
|
19548
|
-
|
|
19549
|
-
|
|
19550
|
-
description: definition.description,
|
|
19551
|
-
parameters: definition.inputSchema,
|
|
19552
|
-
prepareArguments: definition.prepareArguments
|
|
19553
|
-
} : tool
|
|
19554
|
-
);
|
|
19651
|
+
const applyPendingHandoff = () => {
|
|
19652
|
+
if (!pendingHandoff) {
|
|
19653
|
+
return void 0;
|
|
19654
|
+
}
|
|
19655
|
+
const pending = pendingHandoff;
|
|
19656
|
+
pendingHandoff = void 0;
|
|
19657
|
+
return applyHandoff({
|
|
19658
|
+
agent,
|
|
19659
|
+
baseInstructions,
|
|
19660
|
+
pending,
|
|
19661
|
+
resume: runResume,
|
|
19662
|
+
tools: toolsForHandoffProfile({
|
|
19663
|
+
activeProfile: pending.modelProfile,
|
|
19664
|
+
agentTools: wiring.agentTools,
|
|
19665
|
+
enabled: handoffEnabled,
|
|
19666
|
+
execute: handoffExecute
|
|
19667
|
+
})
|
|
19668
|
+
});
|
|
19555
19669
|
};
|
|
19556
19670
|
const {
|
|
19557
|
-
baseInstructions,
|
|
19671
|
+
baseInstructions: assembledBaseInstructions,
|
|
19558
19672
|
contextContentParts: promptContextContentParts,
|
|
19559
19673
|
inputMessages,
|
|
19560
19674
|
inputMessagesAttribute,
|
|
@@ -19590,6 +19704,7 @@ async function executeAgentRunInPrivacyContext(run, conversationPrivacy, runLogC
|
|
|
19590
19704
|
toolRuntimeContext: wiring.toolRuntimeContext,
|
|
19591
19705
|
userContentParts
|
|
19592
19706
|
});
|
|
19707
|
+
baseInstructions = assembledBaseInstructions;
|
|
19593
19708
|
const repositoryInstructionsContext = createRepositoryInstructionsContext({
|
|
19594
19709
|
capture: wiring.captureRepositoryInstructions,
|
|
19595
19710
|
hasSandbox: () => Boolean(wiring.getSandboxRef()),
|
|
@@ -19604,36 +19719,6 @@ async function executeAgentRunInPrivacyContext(run, conversationPrivacy, runLogC
|
|
|
19604
19719
|
shouldPromptAgent
|
|
19605
19720
|
});
|
|
19606
19721
|
runResume.setTurnContexts(turnContexts);
|
|
19607
|
-
const applyPendingHandoff = () => {
|
|
19608
|
-
if (!pendingHandoff) {
|
|
19609
|
-
return void 0;
|
|
19610
|
-
}
|
|
19611
|
-
const { messages, model, thinkingLevel } = pendingHandoff;
|
|
19612
|
-
const replacement = [...messages];
|
|
19613
|
-
pendingHandoff = void 0;
|
|
19614
|
-
agent.state.messages = replacement;
|
|
19615
|
-
agent.state.model = model;
|
|
19616
|
-
agent.state.thinkingLevel = thinkingLevel;
|
|
19617
|
-
const tools = toolsForActiveProfile();
|
|
19618
|
-
agent.state.tools = tools;
|
|
19619
|
-
runResume.setBeforeMessageCount(replacement.length);
|
|
19620
|
-
runResume.setTurnStartMessageIndex(0);
|
|
19621
|
-
runResume.adoptCommittedBoundary(replacement);
|
|
19622
|
-
setSpanAttributes({
|
|
19623
|
-
"gen_ai.agent.model": activeModelId,
|
|
19624
|
-
"gen_ai.agent.model_profile": activeModelProfile,
|
|
19625
|
-
"gen_ai.agent.reasoning.level": turnRoute.reasoningLevel
|
|
19626
|
-
});
|
|
19627
|
-
return {
|
|
19628
|
-
context: {
|
|
19629
|
-
systemPrompt: baseInstructions,
|
|
19630
|
-
messages: replacement,
|
|
19631
|
-
tools
|
|
19632
|
-
},
|
|
19633
|
-
model,
|
|
19634
|
-
thinkingLevel
|
|
19635
|
-
};
|
|
19636
|
-
};
|
|
19637
19722
|
const applyActiveContextCompaction = async (messages, hookSignal, pendingMessages, clearSteeringQueueOnCommit = false, pairPendingRuntimeContext = false) => {
|
|
19638
19723
|
const compaction = await compactActiveContextIfNeeded(
|
|
19639
19724
|
{
|
|
@@ -19764,13 +19849,7 @@ async function executeAgentRunInPrivacyContext(run, conversationPrivacy, runLogC
|
|
|
19764
19849
|
const toolCalls2 = assistantMessage.content.filter(
|
|
19765
19850
|
(part) => part.type === "toolCall"
|
|
19766
19851
|
);
|
|
19767
|
-
const
|
|
19768
|
-
(call) => call.name === HANDOFF_TOOL_NAME
|
|
19769
|
-
);
|
|
19770
|
-
const containsWorkspaceSwitch = toolCalls2.some(
|
|
19771
|
-
(call) => call.name === "switchWorkspace"
|
|
19772
|
-
);
|
|
19773
|
-
const exclusiveTool = containsHandoff ? HANDOFF_TOOL_NAME : containsWorkspaceSwitch ? "switchWorkspace" : void 0;
|
|
19852
|
+
const exclusiveTool = exclusiveToolName(toolCalls2);
|
|
19774
19853
|
if (exclusiveTool && toolCalls2.length !== 1) {
|
|
19775
19854
|
return {
|
|
19776
19855
|
block: true,
|
|
@@ -19847,10 +19926,9 @@ async function executeAgentRunInPrivacyContext(run, conversationPrivacy, runLogC
|
|
|
19847
19926
|
if (event.message.stopReason === "error" || event.message.stopReason === "aborted") {
|
|
19848
19927
|
return;
|
|
19849
19928
|
}
|
|
19850
|
-
|
|
19929
|
+
if (event.message.content.some(
|
|
19851
19930
|
(part) => part.type === "toolCall" && part.name === HANDOFF_TOOL_NAME
|
|
19852
|
-
)
|
|
19853
|
-
if (containsHandoff) {
|
|
19931
|
+
)) {
|
|
19854
19932
|
return;
|
|
19855
19933
|
}
|
|
19856
19934
|
return deliverAssistantMessage(event.message);
|
|
@@ -20000,9 +20078,9 @@ async function executeAgentRunInPrivacyContext(run, conversationPrivacy, runLogC
|
|
|
20000
20078
|
}
|
|
20001
20079
|
return result2;
|
|
20002
20080
|
};
|
|
20003
|
-
const requestedProfile = activeModelProfile === botConfig.defaultProfile ? turnRoute.profile : void 0;
|
|
20004
20081
|
let run2;
|
|
20005
20082
|
let handoffApplied = false;
|
|
20083
|
+
const requestedProfile = activeModelProfile === botConfig.defaultProfile ? turnRoute.profile : void 0;
|
|
20006
20084
|
if (requestedProfile && requestedProfile !== botConfig.defaultProfile) {
|
|
20007
20085
|
const handoffAbortController = new AbortController();
|
|
20008
20086
|
await runAgentStep(
|