@dreb/coding-agent 2.46.0 → 2.48.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 +4 -2
- package/dist/core/agent-session.d.ts +22 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +109 -20
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +7 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +10 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +35 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/k3-context-tier.d.ts +67 -0
- package/dist/core/k3-context-tier.d.ts.map +1 -0
- package/dist/core/k3-context-tier.js +76 -0
- package/dist/core/k3-context-tier.js.map +1 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +6 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +38 -2
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/tools/ask-user.d.ts +45 -0
- package/dist/core/tools/ask-user.d.ts.map +1 -0
- package/dist/core/tools/ask-user.js +210 -0
- package/dist/core/tools/ask-user.js.map +1 -0
- package/dist/core/tools/index.d.ts +11 -0
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +8 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/modes/interactive/components/ask-user.d.ts +59 -0
- package/dist/modes/interactive/components/ask-user.d.ts.map +1 -0
- package/dist/modes/interactive/components/ask-user.js +240 -0
- package/dist/modes/interactive/components/ask-user.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +12 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +99 -5
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +16 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +112 -59
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +24 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/dashboard.md +1 -1
- package/docs/extensions.md +33 -3
- package/docs/providers.md +1 -0
- package/docs/rpc.md +46 -6
- package/docs/session.md +1 -1
- package/package.json +1 -1
|
@@ -35,6 +35,7 @@ import { parseGitUrl } from "../../utils/git.js";
|
|
|
35
35
|
import { extractCopyableText, extractThinkingText, getMessagePreview, getMessageRoleLabel, toSingleLinePreview, } from "../../utils/message-text.js";
|
|
36
36
|
import { ensureTool } from "../../utils/tools-manager.js";
|
|
37
37
|
import { ArminComponent } from "./components/armin.js";
|
|
38
|
+
import { AskUserComponent } from "./components/ask-user.js";
|
|
38
39
|
import { AssistantMessageComponent } from "./components/assistant-message.js";
|
|
39
40
|
import { BashExecutionComponent } from "./components/bash-execution.js";
|
|
40
41
|
import { BorderedLoader } from "./components/bordered-loader.js";
|
|
@@ -136,6 +137,8 @@ export class InteractiveMode {
|
|
|
136
137
|
extensionSelector = undefined;
|
|
137
138
|
extensionInput = undefined;
|
|
138
139
|
extensionEditor = undefined;
|
|
140
|
+
extensionAsk = undefined;
|
|
141
|
+
extensionDialogQueue = Promise.resolve();
|
|
139
142
|
extensionTerminalInputUnsubscribers = new Set();
|
|
140
143
|
// Extension widgets (components rendered above/below the editor)
|
|
141
144
|
extensionWidgetsAbove = new Map();
|
|
@@ -1184,6 +1187,9 @@ export class InteractiveMode {
|
|
|
1184
1187
|
if (this.extensionEditor) {
|
|
1185
1188
|
this.hideExtensionEditor();
|
|
1186
1189
|
}
|
|
1190
|
+
if (this.extensionAsk) {
|
|
1191
|
+
this.hideExtensionAsk();
|
|
1192
|
+
}
|
|
1187
1193
|
this.ui.hideOverlay();
|
|
1188
1194
|
this.clearExtensionTerminalInputListeners();
|
|
1189
1195
|
this.setExtensionFooter(undefined);
|
|
@@ -1406,9 +1412,22 @@ export class InteractiveMode {
|
|
|
1406
1412
|
*/
|
|
1407
1413
|
createExtensionUIContext() {
|
|
1408
1414
|
return {
|
|
1409
|
-
select: (title, options, opts) => this.showExtensionSelector(title, options, opts),
|
|
1410
|
-
|
|
1411
|
-
|
|
1415
|
+
select: (title, options, opts) => this.enqueueExtensionDialog(() => this.showExtensionSelector(title, options, opts), {
|
|
1416
|
+
signal: opts?.signal,
|
|
1417
|
+
abortedValue: undefined,
|
|
1418
|
+
}),
|
|
1419
|
+
confirm: (title, message, opts) => this.enqueueExtensionDialog(() => this.showExtensionConfirm(title, message, opts), {
|
|
1420
|
+
signal: opts?.signal,
|
|
1421
|
+
abortedValue: false,
|
|
1422
|
+
}),
|
|
1423
|
+
input: (title, placeholder, opts) => this.enqueueExtensionDialog(() => this.showExtensionInput(title, placeholder, opts), {
|
|
1424
|
+
signal: opts?.signal,
|
|
1425
|
+
abortedValue: undefined,
|
|
1426
|
+
}),
|
|
1427
|
+
ask: (request, opts) => this.enqueueExtensionDialog(() => this.showExtensionAsk(request, opts), {
|
|
1428
|
+
signal: opts?.signal,
|
|
1429
|
+
abortedValue: undefined,
|
|
1430
|
+
}),
|
|
1412
1431
|
notify: (message, type) => this.showExtensionNotify(message, type),
|
|
1413
1432
|
onTerminalInput: (handler) => this.addExtensionTerminalInputListener(handler),
|
|
1414
1433
|
setStatus: (key, text) => this.setExtensionStatus(key, text),
|
|
@@ -1417,11 +1436,11 @@ export class InteractiveMode {
|
|
|
1417
1436
|
setFooter: (factory) => this.setExtensionFooter(factory),
|
|
1418
1437
|
setHeader: (factory) => this.setExtensionHeader(factory),
|
|
1419
1438
|
setTitle: (title) => this.ui.terminal.setTitle(title),
|
|
1420
|
-
custom: (factory, options) => this.showExtensionCustom(factory, options),
|
|
1439
|
+
custom: (factory, options) => this.enqueueExtensionDialog(() => this.showExtensionCustom(factory, options)),
|
|
1421
1440
|
pasteToEditor: (text) => this.editor.handleInput(`\x1b[200~${text}\x1b[201~`),
|
|
1422
1441
|
setEditorText: (text) => this.editor.setText(text),
|
|
1423
1442
|
getEditorText: () => this.editor.getExpandedText?.() ?? this.editor.getText(),
|
|
1424
|
-
editor: (title, prefill) => this.showExtensionEditor(title, prefill),
|
|
1443
|
+
editor: (title, prefill) => this.enqueueExtensionDialog(() => this.showExtensionEditor(title, prefill)),
|
|
1425
1444
|
setEditorComponent: (factory) => this.setCustomEditorComponent(factory),
|
|
1426
1445
|
get theme() {
|
|
1427
1446
|
return theme;
|
|
@@ -1447,6 +1466,32 @@ export class InteractiveMode {
|
|
|
1447
1466
|
setToolsExpanded: (expanded) => this.setToolsExpanded(expanded),
|
|
1448
1467
|
};
|
|
1449
1468
|
}
|
|
1469
|
+
/** Serialize every blocking extension dialog that can take over keyboard focus. */
|
|
1470
|
+
enqueueExtensionDialog(open, opts) {
|
|
1471
|
+
if (!opts?.signal) {
|
|
1472
|
+
const result = this.extensionDialogQueue.then(open, open);
|
|
1473
|
+
this.extensionDialogQueue = result.then(() => undefined, () => undefined);
|
|
1474
|
+
return result;
|
|
1475
|
+
}
|
|
1476
|
+
const { signal, abortedValue } = opts;
|
|
1477
|
+
if (signal.aborted)
|
|
1478
|
+
return Promise.resolve(abortedValue);
|
|
1479
|
+
// Settle the caller as soon as a queued dialog aborts, even if an earlier
|
|
1480
|
+
// unbounded dialog still owns the UI. Its queue slot remains as a no-op so
|
|
1481
|
+
// later dialogs keep their FIFO order.
|
|
1482
|
+
let onQueuedAbort;
|
|
1483
|
+
const aborted = new Promise((resolve) => {
|
|
1484
|
+
onQueuedAbort = () => resolve(abortedValue);
|
|
1485
|
+
signal.addEventListener("abort", onQueuedAbort, { once: true });
|
|
1486
|
+
});
|
|
1487
|
+
const run = () => {
|
|
1488
|
+
signal.removeEventListener("abort", onQueuedAbort);
|
|
1489
|
+
return signal.aborted ? Promise.resolve(abortedValue) : open();
|
|
1490
|
+
};
|
|
1491
|
+
const queued = this.extensionDialogQueue.then(run, run);
|
|
1492
|
+
this.extensionDialogQueue = queued.then(() => undefined, () => undefined);
|
|
1493
|
+
return Promise.race([queued, aborted]).finally(() => signal.removeEventListener("abort", onQueuedAbort));
|
|
1494
|
+
}
|
|
1450
1495
|
/**
|
|
1451
1496
|
* Show a selector for extensions.
|
|
1452
1497
|
*/
|
|
@@ -1528,6 +1573,48 @@ export class InteractiveMode {
|
|
|
1528
1573
|
this.extensionInput = undefined;
|
|
1529
1574
|
this.restoreEditorComponent();
|
|
1530
1575
|
}
|
|
1576
|
+
/**
|
|
1577
|
+
* Show a rich ask_user question for extensions/built-in tools.
|
|
1578
|
+
*/
|
|
1579
|
+
showExtensionAsk(request, opts) {
|
|
1580
|
+
return new Promise((resolve) => {
|
|
1581
|
+
if (opts?.signal?.aborted) {
|
|
1582
|
+
resolve(undefined);
|
|
1583
|
+
return;
|
|
1584
|
+
}
|
|
1585
|
+
const onAbort = () => {
|
|
1586
|
+
this.hideExtensionAsk();
|
|
1587
|
+
resolve(undefined);
|
|
1588
|
+
};
|
|
1589
|
+
opts?.signal?.addEventListener("abort", onAbort, { once: true });
|
|
1590
|
+
this.extensionAsk = new AskUserComponent(request, (result) => {
|
|
1591
|
+
opts?.signal?.removeEventListener("abort", onAbort);
|
|
1592
|
+
this.hideExtensionAsk();
|
|
1593
|
+
resolve(result);
|
|
1594
|
+
}, () => {
|
|
1595
|
+
opts?.signal?.removeEventListener("abort", onAbort);
|
|
1596
|
+
this.hideExtensionAsk();
|
|
1597
|
+
// The question-level escape action means stop the whole turn, not
|
|
1598
|
+
// continue without an answer. Mirror the default editor's Escape
|
|
1599
|
+
// behavior, including background-agent and queued-message cleanup.
|
|
1600
|
+
this.cancelBackgroundAgents();
|
|
1601
|
+
this.restoreQueuedMessagesToEditor({ abort: true });
|
|
1602
|
+
resolve(undefined);
|
|
1603
|
+
}, { tui: this.ui, timeout: opts?.timeout });
|
|
1604
|
+
this.editorContainer.clear();
|
|
1605
|
+
this.editorContainer.addChild(this.extensionAsk);
|
|
1606
|
+
this.ui.setFocus(this.extensionAsk);
|
|
1607
|
+
this.ui.requestRender();
|
|
1608
|
+
});
|
|
1609
|
+
}
|
|
1610
|
+
/**
|
|
1611
|
+
* Hide the ask_user question.
|
|
1612
|
+
*/
|
|
1613
|
+
hideExtensionAsk() {
|
|
1614
|
+
this.extensionAsk?.dispose();
|
|
1615
|
+
this.extensionAsk = undefined;
|
|
1616
|
+
this.restoreEditorComponent();
|
|
1617
|
+
}
|
|
1531
1618
|
/**
|
|
1532
1619
|
* Show a multi-line editor for extensions (with Ctrl+G support).
|
|
1533
1620
|
*/
|
|
@@ -2330,6 +2417,13 @@ export class InteractiveMode {
|
|
|
2330
2417
|
}
|
|
2331
2418
|
break;
|
|
2332
2419
|
}
|
|
2420
|
+
case "context_window_upgrade": {
|
|
2421
|
+
// Auto context tier upgrade (e.g. Kimi K3 256k → 1M); cache is
|
|
2422
|
+
// preserved server-side and no compaction occurred.
|
|
2423
|
+
this.showStatus(`${event.modelId} context window upgraded: ${Math.round(event.fromContextWindow / 1024)}k → ${Math.round(event.toContextWindow / 1048576)}M (cache preserved)`);
|
|
2424
|
+
this.footer.invalidate();
|
|
2425
|
+
break;
|
|
2426
|
+
}
|
|
2333
2427
|
}
|
|
2334
2428
|
}
|
|
2335
2429
|
/** Update the footer status line with running background agent count. */
|