@elyracode/coding-agent 0.9.8 → 0.9.9
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/CHANGELOG.md +16 -0
- package/dist/cli/doctor-cli.d.ts +8 -0
- package/dist/cli/doctor-cli.d.ts.map +1 -0
- package/dist/cli/doctor-cli.js +81 -0
- package/dist/cli/doctor-cli.js.map +1 -0
- package/dist/core/agent-session.d.ts +35 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +85 -24
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/settings-manager.d.ts +11 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +3 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/smart-router.d.ts +37 -5
- package/dist/core/smart-router.d.ts.map +1 -1
- package/dist/core/smart-router.js +98 -19
- package/dist/core/smart-router.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +4 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +58 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +5 -5
|
@@ -2246,6 +2246,11 @@ export class InteractiveMode {
|
|
|
2246
2246
|
await this.handleReplayCommand(text.slice(7).trim());
|
|
2247
2247
|
return;
|
|
2248
2248
|
}
|
|
2249
|
+
if (text === "/route") {
|
|
2250
|
+
this.editor.setText("");
|
|
2251
|
+
await this.handleRouteCommand();
|
|
2252
|
+
return;
|
|
2253
|
+
}
|
|
2249
2254
|
// Handle bash command (! for normal, !! for excluded from context)
|
|
2250
2255
|
if (text.startsWith("!")) {
|
|
2251
2256
|
const isExcluded = text.startsWith("!!");
|
|
@@ -2298,6 +2303,15 @@ export class InteractiveMode {
|
|
|
2298
2303
|
this.unsubscribe = this.session.subscribe(async (event) => {
|
|
2299
2304
|
await this.handleEvent(event);
|
|
2300
2305
|
});
|
|
2306
|
+
// Feed the active goal budget into smart routing so it can cap tiers
|
|
2307
|
+
// as the budget depletes.
|
|
2308
|
+
this.session.setRoutingBudgetProvider(() => {
|
|
2309
|
+
const goal = this._activeGoal;
|
|
2310
|
+
if (!goal || goal.budgetUsd === undefined)
|
|
2311
|
+
return undefined;
|
|
2312
|
+
const spent = this.session.getSessionStats().cost - (goal.startCostUsd ?? 0);
|
|
2313
|
+
return spent / goal.budgetUsd;
|
|
2314
|
+
});
|
|
2301
2315
|
}
|
|
2302
2316
|
async handleEvent(event) {
|
|
2303
2317
|
if (!this.isInitialized) {
|
|
@@ -2344,6 +2358,11 @@ export class InteractiveMode {
|
|
|
2344
2358
|
this.footer.invalidate();
|
|
2345
2359
|
this.updateEditorBorderColor();
|
|
2346
2360
|
break;
|
|
2361
|
+
case "smart_routing":
|
|
2362
|
+
this.chatContainer.addChild(new Text(theme.fg("dim", `smart routing: ${event.tier} \u2014 ${event.reason} \u2192 ${event.toModel} (was ${event.fromModel})`), 1, 0));
|
|
2363
|
+
this.footer.invalidate();
|
|
2364
|
+
this.ui.requestRender();
|
|
2365
|
+
break;
|
|
2347
2366
|
case "message_start":
|
|
2348
2367
|
if (event.message.role === "custom") {
|
|
2349
2368
|
this.addMessageToChat(event.message);
|
|
@@ -3716,6 +3735,35 @@ export class InteractiveMode {
|
|
|
3716
3735
|
this.chatContainer.addChild(new Text(`${theme.bold(theme.fg("accent", "Goal set:"))} ${goalDisplay}\n${theme.fg("muted", `The agent will keep working until this command exits with code 0.${budgetNote} Type /goal to clear.`)}`, 1, 0));
|
|
3717
3736
|
this.ui.requestRender();
|
|
3718
3737
|
}
|
|
3738
|
+
async handleRouteCommand() {
|
|
3739
|
+
if (!this.settingsManager.getSmartRouting()) {
|
|
3740
|
+
this.showStatus("Smart routing is disabled. Enable it in /settings.");
|
|
3741
|
+
return;
|
|
3742
|
+
}
|
|
3743
|
+
const preview = await this.session.getRoutingPreview();
|
|
3744
|
+
if (!preview) {
|
|
3745
|
+
this.showStatus("Smart routing is inactive (fewer than two available models).");
|
|
3746
|
+
return;
|
|
3747
|
+
}
|
|
3748
|
+
const lines = [theme.bold("Smart Routing"), ""];
|
|
3749
|
+
lines.push(`${theme.fg("dim", "Next turn tier:")} ${theme.fg("accent", preview.tier)} ${theme.fg("muted", `\u2014 ${preview.reason}`)}`);
|
|
3750
|
+
if (preview.budgetUsedFraction !== undefined) {
|
|
3751
|
+
const pct = Math.round(preview.budgetUsedFraction * 100);
|
|
3752
|
+
lines.push(`${theme.fg("dim", "Goal budget:")} ${pct}% spent${pct >= 75 ? theme.fg("warning", " (tier capping active)") : ""}`);
|
|
3753
|
+
}
|
|
3754
|
+
if (preview.requiresImageInput) {
|
|
3755
|
+
lines.push(theme.fg("dim", "Conversation contains images \u2014 only vision-capable models are eligible."));
|
|
3756
|
+
}
|
|
3757
|
+
lines.push("");
|
|
3758
|
+
for (const pick of preview.picks) {
|
|
3759
|
+
const marker = pick.tier === preview.tier ? theme.fg("accent", "\u25b6") : " ";
|
|
3760
|
+
const pinNote = pick.pinned ? theme.fg("muted", " (pinned)") : "";
|
|
3761
|
+
lines.push(`${marker} ${theme.fg("dim", `${pick.tier}:`.padEnd(10))}${pick.model.name || pick.model.id}${pinNote}`);
|
|
3762
|
+
}
|
|
3763
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
3764
|
+
this.chatContainer.addChild(new Text(lines.join("\n"), 1, 0));
|
|
3765
|
+
this.ui.requestRender();
|
|
3766
|
+
}
|
|
3719
3767
|
getLastUserMessageText() {
|
|
3720
3768
|
const messages = this.session.state.messages;
|
|
3721
3769
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
@@ -4034,6 +4082,16 @@ export class InteractiveMode {
|
|
|
4034
4082
|
info += `${theme.fg("dim", "Cache write:")} ${fmt(stats.tokens.cacheWrite)} tokens\n`;
|
|
4035
4083
|
info += `${theme.fg("dim", "Total:")} ${fmt(stats.tokens.total)} tokens\n\n`;
|
|
4036
4084
|
info += `${theme.fg("dim", "Estimated cost:")} ${theme.fg("accent", cost)}\n`;
|
|
4085
|
+
// Burn rate: cost per hour since the first message, once there is
|
|
4086
|
+
// enough elapsed time and spend for the projection to mean anything.
|
|
4087
|
+
const firstMessage = this.session.state.messages.find((m) => "timestamp" in m && typeof m.timestamp === "number");
|
|
4088
|
+
if (firstMessage && stats.cost > 0) {
|
|
4089
|
+
const elapsedMs = Date.now() - firstMessage.timestamp;
|
|
4090
|
+
if (elapsedMs > 60_000) {
|
|
4091
|
+
const perHour = stats.cost / (elapsedMs / 3_600_000);
|
|
4092
|
+
info += `${theme.fg("dim", "Burn rate:")} ${theme.fg("accent", `$${perHour.toFixed(2)}/hour`)} ${theme.fg("muted", "at the current pace")}\n`;
|
|
4093
|
+
}
|
|
4094
|
+
}
|
|
4037
4095
|
if (stats.contextUsage) {
|
|
4038
4096
|
const ctxTokens = stats.contextUsage.tokens ?? 0;
|
|
4039
4097
|
const pct = stats.contextUsage.contextWindow > 0 ? Math.round((ctxTokens / stats.contextUsage.contextWindow) * 100) : 0;
|