@koda-sl/baker-bridge 0.168.0-dev.d78500250 → 0.172.0-dev.b570aa3f2
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 +35 -19
- package/dist/hono/agent.d.ts.map +1 -1
- package/dist/hono/agent.js +3 -1
- package/dist/hono/agent.js.map +1 -1
- package/dist/hono/agent.test.js +2 -0
- package/dist/hono/agent.test.js.map +1 -1
- package/dist/hono/bridge-job.d.ts +19 -11
- package/dist/hono/bridge-job.d.ts.map +1 -1
- package/dist/hono/bridge-job.js +125 -50
- package/dist/hono/bridge-job.js.map +1 -1
- package/dist/hono/bridge-job.test.js +139 -7
- package/dist/hono/bridge-job.test.js.map +1 -1
- package/dist/hono/model-capabilities.d.ts +1 -0
- package/dist/hono/model-capabilities.d.ts.map +1 -1
- package/dist/hono/model-capabilities.js +4 -0
- package/dist/hono/model-capabilities.js.map +1 -1
- package/dist/hono/openrouter-session.d.ts +3 -0
- package/dist/hono/openrouter-session.d.ts.map +1 -1
- package/dist/hono/openrouter-session.js +3 -0
- package/dist/hono/openrouter-session.js.map +1 -1
- package/dist/hono/relay.d.ts +4 -4
- package/dist/hono/relay.d.ts.map +1 -1
- package/dist/hono/relay.js +1 -1
- package/dist/hono/relay.js.map +1 -1
- package/dist/hono/relay.test.js +10 -4
- package/dist/hono/relay.test.js.map +1 -1
- package/dist/hono/served-model.d.ts +8 -0
- package/dist/hono/served-model.d.ts.map +1 -1
- package/dist/hono/served-model.js +41 -0
- package/dist/hono/served-model.js.map +1 -1
- package/dist/hono/served-model.test.js +19 -1
- package/dist/hono/served-model.test.js.map +1 -1
- package/dist/hono/session-continuity.integration.test.js +2 -0
- package/dist/hono/session-continuity.integration.test.js.map +1 -1
- package/dist/hono/subagent-route.d.ts +64 -0
- package/dist/hono/subagent-route.d.ts.map +1 -0
- package/dist/hono/subagent-route.js +147 -0
- package/dist/hono/subagent-route.js.map +1 -0
- package/dist/hono/subagent-route.test.d.ts +2 -0
- package/dist/hono/subagent-route.test.d.ts.map +1 -0
- package/dist/hono/subagent-route.test.js +68 -0
- package/dist/hono/subagent-route.test.js.map +1 -0
- package/dist/hono/tool-result-ledger.d.ts +2 -0
- package/dist/hono/tool-result-ledger.d.ts.map +1 -1
- package/dist/hono/tool-result-ledger.js +12 -8
- package/dist/hono/tool-result-ledger.js.map +1 -1
- package/dist/hono/turn-route.d.ts +84 -0
- package/dist/hono/turn-route.d.ts.map +1 -0
- package/dist/hono/turn-route.js +121 -0
- package/dist/hono/turn-route.js.map +1 -0
- package/dist/hono/turn-route.test.d.ts +2 -0
- package/dist/hono/turn-route.test.d.ts.map +1 -0
- package/dist/hono/turn-route.test.js +134 -0
- package/dist/hono/turn-route.test.js.map +1 -0
- package/package.json +2 -1
- package/dist/hono/effort-route.d.ts +0 -43
- package/dist/hono/effort-route.d.ts.map +0 -1
- package/dist/hono/effort-route.js +0 -36
- package/dist/hono/effort-route.js.map +0 -1
- package/dist/hono/effort-route.test.d.ts +0 -2
- package/dist/hono/effort-route.test.d.ts.map +0 -1
- package/dist/hono/effort-route.test.js +0 -54
- package/dist/hono/effort-route.test.js.map +0 -1
package/dist/hono/bridge-job.js
CHANGED
|
@@ -15,7 +15,6 @@ import { CONNECTION_INPUT_TOOL_NAME, CONNECTION_PLATFORMS, connectedButNotLoaded
|
|
|
15
15
|
import { messageContextTokens, pickContextWindow, streamEventContextUsage, turnContextUsage, } from "./context-usage.js";
|
|
16
16
|
import { CREDENTIAL_INPUT_TOOL_NAME, normalizeCredentialInputToolInput, } from "./credential-input.js";
|
|
17
17
|
import { credentialScrubHooks } from "./credential-scrub.js";
|
|
18
|
-
import { DEFAULT_TURN_EFFORT, decideTurnEffort } from "./effort-route.js";
|
|
19
18
|
import { agentStatedFlowMessage, FLOW_INPUT_TOOL_NAME, nodeTargetRefusals, normalizeFlowInputToolInput, readRawFlowTree, sanitizeFlowRequests, unknownFlowPrefillMessage, } from "./flow-input.js";
|
|
20
19
|
import { writesInventedLogo } from "./invented-logo.js";
|
|
21
20
|
import { jevJudge } from "./jev.js";
|
|
@@ -28,17 +27,19 @@ import { buildAgentExtraBody, EXTRA_BODY_ENV, MODEL_CAPABILITIES_ENV, PER_TURN_E
|
|
|
28
27
|
import { credentialReminder, currentReferenceReminder, kickoffBriefReminder } from "./prompt-context.js";
|
|
29
28
|
import { publishLanguageReminder, publishRunReminder, publishStandingReminder } from "./publish-handoff.js";
|
|
30
29
|
import { bridgeRuntimeFiles } from "./runtime-files.js";
|
|
31
|
-
import { alignServedModels } from "./served-model.js";
|
|
30
|
+
import { alignServedModels, readConversationModel } from "./served-model.js";
|
|
32
31
|
import { applyCurrentSenderAttribution, buildCancelBoundary, buildCleanBoundary, buildRehydratedPrompt, compactionRetryAttempt, emptyInProgressSession, interruptedResumeAttempt, isCliResumeRefusal, isContextOverflowError, isResumeSessionError, observeInProgressSession, prepareSessionAttempt, stallContinuationAttempt, } from "./session-continuity.js";
|
|
33
32
|
import { readSessionSkills } from "./session-skills.js";
|
|
34
33
|
import { ownQueryUsage, readUsageBaseline } from "./session-usage-baseline.js";
|
|
35
34
|
import { skillLanguageHooks } from "./skill-language.js";
|
|
36
35
|
import { BridgeSlashCommands, leadingSkillCommand, verbatimSlashCommand } from "./slash-commands.js";
|
|
36
|
+
import { readAgentDefinitions, subagentHooks } from "./subagent-route.js";
|
|
37
37
|
import { createBakerUiServer, normalizeTagInputToolInput, sanitizeTagChanges, TAG_INPUT_TOOL_NAME, unknownPrefillMessage, } from "./tag-input.js";
|
|
38
38
|
import { blockingToolDelegated, toolRunAsCommand } from "./tool-in-shell.js";
|
|
39
39
|
import { ToolResultLedger } from "./tool-result-ledger.js";
|
|
40
40
|
import { recordTurnEvent } from "./turn-events.js";
|
|
41
41
|
import { addQueryModelUsage, queryModelUsage, turnModelUsageList } from "./turn-model-usage.js";
|
|
42
|
+
import { askTurnSignals, needsSignals, routeTurn, } from "./turn-route.js";
|
|
42
43
|
import { prepareSharedInstructions } from "./workspace-instructions.js";
|
|
43
44
|
import { settleWorkspaceAfterTasks } from "./workspace-settle.js";
|
|
44
45
|
export function parsePlanDecision(value) {
|
|
@@ -451,9 +452,9 @@ function turnUsage(state) {
|
|
|
451
452
|
return {
|
|
452
453
|
modelUsage: turnModelUsageList(state.modelUsageTotals),
|
|
453
454
|
...(toolResults.length > 0 ? { toolResults } : {}),
|
|
454
|
-
//
|
|
455
|
-
...(state.
|
|
456
|
-
? {
|
|
455
|
+
// Left off when nothing was decided: Jev never answered and the model is the Runtime's.
|
|
456
|
+
...(state.turnRoute && !(state.turnRoute.reason === "unjudged" && state.turnRoute.modelReason === "fixed")
|
|
457
|
+
? { turnRoute: state.turnRoute }
|
|
457
458
|
: {}),
|
|
458
459
|
};
|
|
459
460
|
}
|
|
@@ -540,6 +541,64 @@ function hookSettingsForJob(job) {
|
|
|
540
541
|
* the workspace's `CLAUDE.md` itself only when it could not be split into the
|
|
541
542
|
* shared system prompt (`prepareSharedInstructions`).
|
|
542
543
|
*/
|
|
544
|
+
/** A Session review reads no CLAUDE.md, so it has nothing to share. */
|
|
545
|
+
async function sharedInstructionsFor(job) {
|
|
546
|
+
if (job.review) {
|
|
547
|
+
return null;
|
|
548
|
+
}
|
|
549
|
+
return await prepareSharedInstructions({
|
|
550
|
+
projectRoot: bridgeRuntimeFiles.projectRoot(),
|
|
551
|
+
contextDir: bridgeRuntimeFiles.instructionsDir(),
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
function sharedInstructionOptions(sharedInstructions) {
|
|
555
|
+
if (!sharedInstructions) {
|
|
556
|
+
return {};
|
|
557
|
+
}
|
|
558
|
+
return {
|
|
559
|
+
systemPrompt: {
|
|
560
|
+
type: "preset",
|
|
561
|
+
preset: "claude_code",
|
|
562
|
+
append: sharedInstructions.shared,
|
|
563
|
+
// Recorded once per conversation, so a scaffold sync mid-chat cannot
|
|
564
|
+
// move the cached prefix under it; it lands at the next compaction.
|
|
565
|
+
snapshot: true,
|
|
566
|
+
},
|
|
567
|
+
additionalDirectories: [bridgeRuntimeFiles.instructionsDir()],
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
function bridgeJudge(feature) {
|
|
571
|
+
return jevJudge(process.env.OPENROUTER_API_KEY, runtimeOpenRouterTags(process.env, { service: "bridge", feature }));
|
|
572
|
+
}
|
|
573
|
+
function judgesOf(dependencies) {
|
|
574
|
+
return {
|
|
575
|
+
judge: dependencies.judge ?? bridgeJudge("bridge.toolCallGuard"),
|
|
576
|
+
routeJudge: dependencies.routeJudge ?? bridgeJudge("bridge.turnRoute"),
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
function sharedInstructionEnv(sharedInstructions) {
|
|
580
|
+
return sharedInstructions ? { CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD: "1" } : {};
|
|
581
|
+
}
|
|
582
|
+
/** Appends `extra`'s hook matchers after the ones `options` already carries. */
|
|
583
|
+
function withSubagentHooks(options, extra) {
|
|
584
|
+
const hooks = { ...(options.hooks ?? {}) };
|
|
585
|
+
for (const [event, matchers] of Object.entries(extra)) {
|
|
586
|
+
hooks[event] = [...(hooks[event] ?? []), ...matchers];
|
|
587
|
+
}
|
|
588
|
+
return { ...options, hooks };
|
|
589
|
+
}
|
|
590
|
+
function recordSubagentRoute(state, agentType, route) {
|
|
591
|
+
if (state.turnRoute) {
|
|
592
|
+
state.turnRoute.subagents = [...(state.turnRoute.subagents ?? []), { agentType, ...route }];
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
function turnEffortOf(state) {
|
|
596
|
+
return state.turnRoute?.effort ?? "medium";
|
|
597
|
+
}
|
|
598
|
+
/** The agent's last message in the chat, empty on its first turn. */
|
|
599
|
+
function previousReplyOf(job) {
|
|
600
|
+
return (job.history?.entries ?? []).filter((entry) => entry.role === "assistant").at(-1)?.text ?? "";
|
|
601
|
+
}
|
|
543
602
|
function instructionSettingsForJob(job, sharedInstructions) {
|
|
544
603
|
if (job.review) {
|
|
545
604
|
return { claudeMdExcludes: ["**/CLAUDE.md"] };
|
|
@@ -1207,7 +1266,8 @@ export class BridgeJobExecutor {
|
|
|
1207
1266
|
holdsNoWork;
|
|
1208
1267
|
keepCliInStep;
|
|
1209
1268
|
judge;
|
|
1210
|
-
|
|
1269
|
+
routeJudge;
|
|
1270
|
+
routeModels;
|
|
1211
1271
|
constructor(dependencies) {
|
|
1212
1272
|
this.sdk = dependencies.sdk;
|
|
1213
1273
|
this.relay = dependencies.relay;
|
|
@@ -1233,12 +1293,8 @@ export class BridgeJobExecutor {
|
|
|
1233
1293
|
this.keepCliInStep = dependencies.keepCliInStep;
|
|
1234
1294
|
this.readFlowTree =
|
|
1235
1295
|
dependencies.readFlowTree ?? ((flowSlug) => readRawFlowTree(bridgeRuntimeFiles.flowsDir(), flowSlug));
|
|
1236
|
-
this.judge =
|
|
1237
|
-
|
|
1238
|
-
jevJudge(process.env.OPENROUTER_API_KEY, runtimeOpenRouterTags(process.env, { service: "bridge", feature: "bridge.toolCallGuard" }));
|
|
1239
|
-
this.effortJudge =
|
|
1240
|
-
dependencies.effortJudge ??
|
|
1241
|
-
jevJudge(process.env.OPENROUTER_API_KEY, runtimeOpenRouterTags(process.env, { service: "bridge", feature: "bridge.effortRoute" }));
|
|
1296
|
+
({ judge: this.judge, routeJudge: this.routeJudge } = judgesOf(dependencies));
|
|
1297
|
+
this.routeModels = dependencies.routeModels === true;
|
|
1242
1298
|
}
|
|
1243
1299
|
async execute(job, controls) {
|
|
1244
1300
|
try {
|
|
@@ -1251,24 +1307,56 @@ export class BridgeJobExecutor {
|
|
|
1251
1307
|
}
|
|
1252
1308
|
}
|
|
1253
1309
|
/**
|
|
1254
|
-
*
|
|
1255
|
-
* Session review, which keeps
|
|
1256
|
-
*
|
|
1310
|
+
* What Jev reads in this turn, asked while the boundary loads (~0.3 s). Null
|
|
1311
|
+
* for a Session review, which keeps its own model and effort, and for a turn
|
|
1312
|
+
* that decides without it. Never throws: an unanswered judge is no signal.
|
|
1257
1313
|
*/
|
|
1258
|
-
async
|
|
1259
|
-
if (job.review) {
|
|
1314
|
+
async askSignals(job, request) {
|
|
1315
|
+
if (job.review || !needsSignals(this.turnFacts(job, request))) {
|
|
1260
1316
|
return null;
|
|
1261
1317
|
}
|
|
1262
|
-
|
|
1263
|
-
return await decideTurnEffort({
|
|
1318
|
+
return await askTurnSignals({
|
|
1264
1319
|
message: job.prompt,
|
|
1265
|
-
previousReply:
|
|
1266
|
-
judge: this.
|
|
1320
|
+
previousReply: previousReplyOf(job),
|
|
1321
|
+
judge: this.routeJudge,
|
|
1322
|
+
}).catch(() => null);
|
|
1323
|
+
}
|
|
1324
|
+
/** This turn's model and effort (see `turn-route.ts`); undefined for a Session review. */
|
|
1325
|
+
async routeFor(job, request, attempt, signals) {
|
|
1326
|
+
if (job.review) {
|
|
1327
|
+
return undefined;
|
|
1328
|
+
}
|
|
1329
|
+
const resumed = attempt.resumeOptions.resume;
|
|
1330
|
+
const sessionModel = resumed ? await readConversationModel(resumed, claudeConfigDir()) : undefined;
|
|
1331
|
+
return routeTurn({
|
|
1332
|
+
...this.turnFacts(job, request),
|
|
1333
|
+
signals: await signals,
|
|
1334
|
+
defaultModel: this.model,
|
|
1335
|
+
routeModels: this.routeModels,
|
|
1336
|
+
...(sessionModel ? { sessionModel } : {}),
|
|
1337
|
+
startedChat: previousReplyOf(job) === "",
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1340
|
+
/** What this turn's subagents are given (see `subagent-route.ts`); nothing for a Session review. */
|
|
1341
|
+
async subagentHooksFor(job, state, sharedInstructions, model) {
|
|
1342
|
+
if (job.review) {
|
|
1343
|
+
return {};
|
|
1344
|
+
}
|
|
1345
|
+
return subagentHooks({
|
|
1346
|
+
instructions: sharedInstructions?.shared ?? null,
|
|
1347
|
+
definitions: await readAgentDefinitions(bridgeRuntimeFiles.projectRoot()),
|
|
1348
|
+
judge: this.routeModels ? this.routeJudge : null,
|
|
1349
|
+
parentModel: model,
|
|
1350
|
+
onRoute: (agentType, route) => recordSubagentRoute(state, agentType, route),
|
|
1351
|
+
});
|
|
1352
|
+
}
|
|
1353
|
+
turnFacts(job, request) {
|
|
1354
|
+
return {
|
|
1267
1355
|
planMode: job.planMode === true,
|
|
1268
1356
|
leadingCommand: request.leadingCommand,
|
|
1269
1357
|
unattended: job.unattended === true,
|
|
1270
1358
|
hasAttachments: (job.attachments?.length ?? 0) > 0,
|
|
1271
|
-
}
|
|
1359
|
+
};
|
|
1272
1360
|
}
|
|
1273
1361
|
async executeTurn(job, controls) {
|
|
1274
1362
|
const state = createBridgeJobState();
|
|
@@ -1282,7 +1370,7 @@ export class BridgeJobExecutor {
|
|
|
1282
1370
|
return { kind: "cancelled", costUsd: 0, model: state.model };
|
|
1283
1371
|
}
|
|
1284
1372
|
// Asked while the boundary loads, so the answer (~0.3 s) costs the turn no time.
|
|
1285
|
-
const
|
|
1373
|
+
const signals = this.askSignals(job, request);
|
|
1286
1374
|
const loaded = await this.loadTrustedBoundary(job, controls);
|
|
1287
1375
|
if (loaded?.kind !== "clean") {
|
|
1288
1376
|
request = await this.withContinuedAttachments(job, request);
|
|
@@ -1301,7 +1389,7 @@ export class BridgeJobExecutor {
|
|
|
1301
1389
|
state.detachedSession = attempt.detachedSession === true;
|
|
1302
1390
|
result.attemptedRehydration = attempt.attemptedRehydration;
|
|
1303
1391
|
this.recordAttemptContextSource(job, attempt);
|
|
1304
|
-
state.
|
|
1392
|
+
state.turnRoute = await this.routeFor(job, request, attempt, signals);
|
|
1305
1393
|
result = await this.runAttempt(job, controls, state, attempt);
|
|
1306
1394
|
return await this.finishSuccessfulAttempt(job, controls, state, result.costUsd);
|
|
1307
1395
|
}
|
|
@@ -1310,8 +1398,8 @@ export class BridgeJobExecutor {
|
|
|
1310
1398
|
if (repaired && controls.isActive()) {
|
|
1311
1399
|
const repairState = createBridgeJobState();
|
|
1312
1400
|
repairState.detachedSession = repaired.detachedSession === true;
|
|
1313
|
-
// The same turn, so the same level: a
|
|
1314
|
-
repairState.
|
|
1401
|
+
// The same turn, so the same model and level: a change would re-write the cache.
|
|
1402
|
+
repairState.turnRoute = state.turnRoute;
|
|
1315
1403
|
let repairResult = { costUsd: 0, attemptedRehydration: repaired.attemptedRehydration };
|
|
1316
1404
|
try {
|
|
1317
1405
|
repairResult = await this.runAttempt(job, controls, repairState, repaired);
|
|
@@ -1461,7 +1549,7 @@ export class BridgeJobExecutor {
|
|
|
1461
1549
|
return `${block}\n\n${job.prompt}`;
|
|
1462
1550
|
}
|
|
1463
1551
|
async runAttempt(job, controls, state, attempt) {
|
|
1464
|
-
state.model = this.model;
|
|
1552
|
+
state.model = state.turnRoute?.model ?? this.model;
|
|
1465
1553
|
// A stalled stream closes the wedged query and resumes the CLI session in
|
|
1466
1554
|
// place — the turn survives a hung upstream request instead of dying at the
|
|
1467
1555
|
// 30-minute session watchdog with all mid-turn work stranded.
|
|
@@ -1469,7 +1557,7 @@ export class BridgeJobExecutor {
|
|
|
1469
1557
|
let current = attempt;
|
|
1470
1558
|
for (let stallRetries = 0;;) {
|
|
1471
1559
|
try {
|
|
1472
|
-
costUsd += await this.runQueryOnce(job, controls, state, current,
|
|
1560
|
+
costUsd += await this.runQueryOnce(job, controls, state, current, state.model);
|
|
1473
1561
|
break;
|
|
1474
1562
|
}
|
|
1475
1563
|
catch (error) {
|
|
@@ -1849,12 +1937,7 @@ export class BridgeJobExecutor {
|
|
|
1849
1937
|
await this.alignResumedTranscript(attempt);
|
|
1850
1938
|
const mcpServers = await this.resolveMcpServers(job);
|
|
1851
1939
|
const skills = await readSessionSkills(bridgeRuntimeFiles.projectRoot());
|
|
1852
|
-
const sharedInstructions = job
|
|
1853
|
-
? null
|
|
1854
|
-
: await prepareSharedInstructions({
|
|
1855
|
-
projectRoot: bridgeRuntimeFiles.projectRoot(),
|
|
1856
|
-
contextDir: bridgeRuntimeFiles.instructionsDir(),
|
|
1857
|
-
});
|
|
1940
|
+
const sharedInstructions = await sharedInstructionsFor(job);
|
|
1858
1941
|
const autoCompactWindow = autoCompactWindowForModel(model);
|
|
1859
1942
|
const betas = betasForModel(model);
|
|
1860
1943
|
// No `outputStyle`: the built-in `Concise` style was pinned here against Opus 5's
|
|
@@ -1914,25 +1997,13 @@ export class BridgeJobExecutor {
|
|
|
1914
1997
|
// its first tool exchange onward. It may differ between turns only because
|
|
1915
1998
|
// the CLI also restates it per message (`PER_TURN_EFFORT_CAPABILITIES`),
|
|
1916
1999
|
// which keeps the cache; prose is no substitute.
|
|
1917
|
-
effort: state
|
|
2000
|
+
effort: turnEffortOf(state),
|
|
1918
2001
|
cwd: process.cwd(),
|
|
1919
2002
|
settingSources: ["project"],
|
|
1920
2003
|
// The scaffold's CLAUDE.md, minus its `@COMPANY.md` import, as the system
|
|
1921
2004
|
// prompt, so every chat reads one cached copy instead of writing its own;
|
|
1922
2005
|
// the import loads from `instructionsDir` (see workspace-instructions.ts).
|
|
1923
|
-
...(sharedInstructions
|
|
1924
|
-
? {
|
|
1925
|
-
systemPrompt: {
|
|
1926
|
-
type: "preset",
|
|
1927
|
-
preset: "claude_code",
|
|
1928
|
-
append: sharedInstructions.shared,
|
|
1929
|
-
// Recorded once per conversation, so a scaffold sync mid-chat cannot
|
|
1930
|
-
// move the cached prefix under it; it lands at the next compaction.
|
|
1931
|
-
snapshot: true,
|
|
1932
|
-
},
|
|
1933
|
-
additionalDirectories: [bridgeRuntimeFiles.instructionsDir()],
|
|
1934
|
-
}
|
|
1935
|
-
: {}),
|
|
2006
|
+
...sharedInstructionOptions(sharedInstructions),
|
|
1936
2007
|
// `baker_ui` hosts in-process interactive dashboard tools (secure tag
|
|
1937
2008
|
// form). Always present; HTTP (Composio) servers merge alongside it.
|
|
1938
2009
|
mcpServers: { ...(mcpServers ?? {}), baker_ui: createBakerUiServer({ credentials: credentialsEnabled() }) },
|
|
@@ -1945,7 +2016,7 @@ export class BridgeJobExecutor {
|
|
|
1945
2016
|
// the workspace could not be read; omit rather than allowlist nothing.
|
|
1946
2017
|
...(skills ? { skills } : {}),
|
|
1947
2018
|
disallowedTools: disallowedToolsFor(job),
|
|
1948
|
-
...withCredentialScrub(reviewQueryOptions(job), job),
|
|
2019
|
+
...withSubagentHooks(withCredentialScrub(reviewQueryOptions(job), job), await this.subagentHooksFor(job, state, sharedInstructions, model)),
|
|
1949
2020
|
// Never omitted: since SDK 0.3.286 an omitted mode starts a third-party-provider
|
|
1950
2021
|
// session (OpenRouter) in auto mode, where a classifier rather than `canUseTool`
|
|
1951
2022
|
// decides tool calls.
|
|
@@ -1985,7 +2056,7 @@ export class BridgeJobExecutor {
|
|
|
1985
2056
|
// the sandbox pays ~5-10% of its tokens on colour codes it can't see.
|
|
1986
2057
|
NO_COLOR: "1",
|
|
1987
2058
|
// Loads the `CLAUDE.md` in `instructionsDir`, which imports COMPANY.md.
|
|
1988
|
-
...(sharedInstructions
|
|
2059
|
+
...sharedInstructionEnv(sharedInstructions),
|
|
1989
2060
|
// Pin the conversation to one OpenRouter provider instance so the
|
|
1990
2061
|
// instance-scoped prompt cache is actually re-read across the turn's
|
|
1991
2062
|
// many tool-call requests. Merged into every model request body by the
|
|
@@ -1999,6 +2070,10 @@ export class BridgeJobExecutor {
|
|
|
1999
2070
|
.join("\n"),
|
|
2000
2071
|
// Lets a turn change effort without losing the prompt cache; see openrouter-session.ts.
|
|
2001
2072
|
[MODEL_CAPABILITIES_ENV]: PER_TURN_EFFORT_CAPABILITIES,
|
|
2073
|
+
// The CLI names each session with a second, structured-output request on the
|
|
2074
|
+
// turn's model. OpenRouter's Bedrock cannot serve that, so it was billed to
|
|
2075
|
+
// OpenRouter credits on Azure or Vertex, and nothing in Baker reads the name.
|
|
2076
|
+
CLAUDE_CODE_DISABLE_TERMINAL_TITLE: "1",
|
|
2002
2077
|
// The turn's message sender, so in-sandbox `baker` calls can scope to the acting user.
|
|
2003
2078
|
...(job.currentSender?.userId ? { BAKER_ACTING_USER_ID: job.currentSender.userId } : {}),
|
|
2004
2079
|
...subagentModelEnv(),
|