@modeloslab/modelcode 0.1.2 → 0.1.3
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/cli.mjs +10 -5
- package/dist/{tui-2wxjcqb2.mjs → tui-gh76vcf8.mjs} +227 -43
- package/package.json +1 -1
- package/dist/main-2aqyq9g6.mjs +0 -24239
- package/dist/tui-0r2q70wm.mjs +0 -23768
- package/dist/tui-5an9t3j5.mjs +0 -23806
package/dist/cli.mjs
CHANGED
|
@@ -1356,10 +1356,15 @@ async function interactiveLogin(rl, cfg) {
|
|
|
1356
1356
|
` + ` ${C.cyan}3${C.reset}) skip for now
|
|
1357
1357
|
`);
|
|
1358
1358
|
const choice = (await rl.question(`${C.green}choose 1-3\u203A${C.reset} `)).trim();
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1359
|
+
const extractKey = (s) => s.match(/mdlk_[A-Za-z0-9]+/)?.[0] ?? "";
|
|
1360
|
+
if (choice === "1" || /mdlk_/.test(choice)) {
|
|
1361
|
+
let key = extractKey(choice);
|
|
1362
|
+
if (!key)
|
|
1363
|
+
key = extractKey(await rl.question("paste your API key (mdlk_\u2026): "));
|
|
1364
|
+
if (!key)
|
|
1365
|
+
key = extractKey(await rl.question("API key (mdlk_\u2026): "));
|
|
1366
|
+
if (!key) {
|
|
1367
|
+
stdout.write(`${C.amber}that doesn't look like an mdlk_ key \u2014 it should start with "mdlk_"${C.reset}
|
|
1363
1368
|
`);
|
|
1364
1369
|
return false;
|
|
1365
1370
|
}
|
|
@@ -1581,7 +1586,7 @@ async function main() {
|
|
|
1581
1586
|
await interactiveLogin(rl, cfg);
|
|
1582
1587
|
rl.close();
|
|
1583
1588
|
}
|
|
1584
|
-
const { runTui } = await import("./tui-
|
|
1589
|
+
const { runTui } = await import("./tui-gh76vcf8.mjs");
|
|
1585
1590
|
return runTui(cfg, resume);
|
|
1586
1591
|
}
|
|
1587
1592
|
if (cmd === "tui")
|
|
@@ -21480,6 +21480,92 @@ ${c.dim}Tips show on startup (one at a time). Toggle off with MODELCODE_TIPS=0.$
|
|
|
21480
21480
|
`);
|
|
21481
21481
|
}
|
|
21482
21482
|
|
|
21483
|
+
// src/ui/spinnerVerbs.ts
|
|
21484
|
+
var SPINNER_VERBS = [
|
|
21485
|
+
"Accomplishing",
|
|
21486
|
+
"Architecting",
|
|
21487
|
+
"Baking",
|
|
21488
|
+
"Brewing",
|
|
21489
|
+
"Calculating",
|
|
21490
|
+
"Cerebrating",
|
|
21491
|
+
"Channeling",
|
|
21492
|
+
"Churning",
|
|
21493
|
+
"Cogitating",
|
|
21494
|
+
"Composing",
|
|
21495
|
+
"Computing",
|
|
21496
|
+
"Concocting",
|
|
21497
|
+
"Considering",
|
|
21498
|
+
"Contemplating",
|
|
21499
|
+
"Cooking",
|
|
21500
|
+
"Crafting",
|
|
21501
|
+
"Creating",
|
|
21502
|
+
"Crunching",
|
|
21503
|
+
"Crystallizing",
|
|
21504
|
+
"Deciphering",
|
|
21505
|
+
"Deliberating",
|
|
21506
|
+
"Determining",
|
|
21507
|
+
"Digging",
|
|
21508
|
+
"Distilling",
|
|
21509
|
+
"Doing",
|
|
21510
|
+
"Effecting",
|
|
21511
|
+
"Elaborating",
|
|
21512
|
+
"Engineering",
|
|
21513
|
+
"Envisioning",
|
|
21514
|
+
"Excavating",
|
|
21515
|
+
"Exploring",
|
|
21516
|
+
"Fabricating",
|
|
21517
|
+
"Fashioning",
|
|
21518
|
+
"Finagling",
|
|
21519
|
+
"Forging",
|
|
21520
|
+
"Formulating",
|
|
21521
|
+
"Generating",
|
|
21522
|
+
"Germinating",
|
|
21523
|
+
"Hatching",
|
|
21524
|
+
"Herding",
|
|
21525
|
+
"Honing",
|
|
21526
|
+
"Hustling",
|
|
21527
|
+
"Ideating",
|
|
21528
|
+
"Imagining",
|
|
21529
|
+
"Incubating",
|
|
21530
|
+
"Inferring",
|
|
21531
|
+
"Manifesting",
|
|
21532
|
+
"Marinating",
|
|
21533
|
+
"Mulling",
|
|
21534
|
+
"Musing",
|
|
21535
|
+
"Noodling",
|
|
21536
|
+
"Orchestrating",
|
|
21537
|
+
"Percolating",
|
|
21538
|
+
"Philosophizing",
|
|
21539
|
+
"Plotting",
|
|
21540
|
+
"Pondering",
|
|
21541
|
+
"Processing",
|
|
21542
|
+
"Puttering",
|
|
21543
|
+
"Puzzling",
|
|
21544
|
+
"Reticulating",
|
|
21545
|
+
"Ruminating",
|
|
21546
|
+
"Scheming",
|
|
21547
|
+
"Sculpting",
|
|
21548
|
+
"Shimmying",
|
|
21549
|
+
"Simmering",
|
|
21550
|
+
"Smooshing",
|
|
21551
|
+
"Spinning",
|
|
21552
|
+
"Stewing",
|
|
21553
|
+
"Summoning",
|
|
21554
|
+
"Synthesizing",
|
|
21555
|
+
"Thinking",
|
|
21556
|
+
"Tinkering",
|
|
21557
|
+
"Transmuting",
|
|
21558
|
+
"Unfurling",
|
|
21559
|
+
"Vibing",
|
|
21560
|
+
"Weaving",
|
|
21561
|
+
"Whirring",
|
|
21562
|
+
"Working",
|
|
21563
|
+
"Wrangling"
|
|
21564
|
+
];
|
|
21565
|
+
function randomVerb() {
|
|
21566
|
+
return SPINNER_VERBS[Math.floor(Math.random() * SPINNER_VERBS.length)];
|
|
21567
|
+
}
|
|
21568
|
+
|
|
21483
21569
|
// src/ui/themes.ts
|
|
21484
21570
|
var THEMES = {
|
|
21485
21571
|
amber: { accent: "yellow", user: "green", tool: "cyan", dim: "gray", ok: "green", warn: "yellow" },
|
|
@@ -21492,11 +21578,11 @@ function getTheme(name) {
|
|
|
21492
21578
|
|
|
21493
21579
|
// src/ui/App.tsx
|
|
21494
21580
|
var jsx_dev_runtime = __toESM(require_jsx_dev_runtime(), 1);
|
|
21495
|
-
var SPINNER = ["
|
|
21581
|
+
var SPINNER = ["✶", "✸", "✹", "✺", "✹", "✷"];
|
|
21496
21582
|
function Spinner({ color }) {
|
|
21497
21583
|
const [i, setI] = import_react34.useState(0);
|
|
21498
21584
|
import_react34.useEffect(() => {
|
|
21499
|
-
const t = setInterval(() => setI((n) => (n + 1) % SPINNER.length),
|
|
21585
|
+
const t = setInterval(() => setI((n) => (n + 1) % SPINNER.length), 120);
|
|
21500
21586
|
return () => clearInterval(t);
|
|
21501
21587
|
}, []);
|
|
21502
21588
|
return /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
@@ -21504,6 +21590,46 @@ function Spinner({ color }) {
|
|
|
21504
21590
|
children: SPINNER[i]
|
|
21505
21591
|
}, undefined, false, undefined, this);
|
|
21506
21592
|
}
|
|
21593
|
+
function WorkingRow({ start, tokens, color, dim }) {
|
|
21594
|
+
const [, tick] = import_react34.useState(0);
|
|
21595
|
+
const [verb, setVerb] = import_react34.useState(() => randomVerb());
|
|
21596
|
+
import_react34.useEffect(() => {
|
|
21597
|
+
const t = setInterval(() => tick((n) => n + 1), 1000);
|
|
21598
|
+
const v = setInterval(() => setVerb(randomVerb()), 4000);
|
|
21599
|
+
return () => {
|
|
21600
|
+
clearInterval(t);
|
|
21601
|
+
clearInterval(v);
|
|
21602
|
+
};
|
|
21603
|
+
}, []);
|
|
21604
|
+
const secs = Math.max(0, Math.floor((Date.now() - start) / 1000));
|
|
21605
|
+
const tok = tokens > 0 ? ` · ↓ ${tokens.toLocaleString()} tok` : "";
|
|
21606
|
+
return /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
21607
|
+
children: [
|
|
21608
|
+
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Spinner, {
|
|
21609
|
+
color
|
|
21610
|
+
}, undefined, false, undefined, this),
|
|
21611
|
+
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
21612
|
+
color,
|
|
21613
|
+
bold: true,
|
|
21614
|
+
children: [
|
|
21615
|
+
" ",
|
|
21616
|
+
verb,
|
|
21617
|
+
"…"
|
|
21618
|
+
]
|
|
21619
|
+
}, undefined, true, undefined, this),
|
|
21620
|
+
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
21621
|
+
color: dim,
|
|
21622
|
+
children: [
|
|
21623
|
+
" (",
|
|
21624
|
+
secs,
|
|
21625
|
+
"s",
|
|
21626
|
+
tok,
|
|
21627
|
+
" · esc to interrupt)"
|
|
21628
|
+
]
|
|
21629
|
+
}, undefined, true, undefined, this)
|
|
21630
|
+
]
|
|
21631
|
+
}, undefined, true, undefined, this);
|
|
21632
|
+
}
|
|
21507
21633
|
function Chip({ label, color }) {
|
|
21508
21634
|
return /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
21509
21635
|
backgroundColor: color,
|
|
@@ -21527,15 +21653,38 @@ function C_KEY(color, k) {
|
|
|
21527
21653
|
]
|
|
21528
21654
|
}, undefined, true, undefined, this);
|
|
21529
21655
|
}
|
|
21530
|
-
function App2({ theme, model, mdlUsd, lines, streaming, sessionMdl, contextPct, walletMdl, mode, busy, confirmReq, history, onConfirm, onSubmit, onInterrupt, onExit }) {
|
|
21656
|
+
function App2({ theme, model, mdlUsd, lines, streaming, sessionMdl, contextPct, walletMdl, mode, busy, toolStream, turnStart, turnTokens, confirmReq, history, onConfirm, onSubmit, onInterrupt, onExit }) {
|
|
21531
21657
|
const t = getTheme(theme);
|
|
21532
21658
|
const [input, setInput] = import_react34.useState("");
|
|
21533
21659
|
const [histIdx, setHistIdx] = import_react34.useState(-1);
|
|
21660
|
+
const [exitHint, setExitHint] = import_react34.useState(false);
|
|
21661
|
+
const exitTimer = import_react34.useRef(null);
|
|
21534
21662
|
const { exit } = use_app_default();
|
|
21663
|
+
const armExit = () => {
|
|
21664
|
+
setExitHint(true);
|
|
21665
|
+
if (exitTimer.current)
|
|
21666
|
+
clearTimeout(exitTimer.current);
|
|
21667
|
+
exitTimer.current = setTimeout(() => setExitHint(false), 800);
|
|
21668
|
+
};
|
|
21669
|
+
const doExit = () => {
|
|
21670
|
+
if (exitTimer.current)
|
|
21671
|
+
clearTimeout(exitTimer.current);
|
|
21672
|
+
onExit();
|
|
21673
|
+
exit();
|
|
21674
|
+
};
|
|
21535
21675
|
use_input_default((ch, key) => {
|
|
21676
|
+
if (key.ctrl && ch === "d") {
|
|
21677
|
+
doExit();
|
|
21678
|
+
return;
|
|
21679
|
+
}
|
|
21536
21680
|
if (key.ctrl && ch === "c") {
|
|
21537
|
-
|
|
21538
|
-
|
|
21681
|
+
if (exitHint) {
|
|
21682
|
+
doExit();
|
|
21683
|
+
return;
|
|
21684
|
+
}
|
|
21685
|
+
if (busy)
|
|
21686
|
+
onInterrupt();
|
|
21687
|
+
armExit();
|
|
21539
21688
|
return;
|
|
21540
21689
|
}
|
|
21541
21690
|
if (confirmReq) {
|
|
@@ -21711,22 +21860,21 @@ function App2({ theme, model, mdlUsd, lines, streaming, sessionMdl, contextPct,
|
|
|
21711
21860
|
}, undefined, true, undefined, this)
|
|
21712
21861
|
]
|
|
21713
21862
|
}, undefined, true, undefined, this) : null,
|
|
21714
|
-
|
|
21715
|
-
|
|
21716
|
-
children:
|
|
21717
|
-
|
|
21718
|
-
|
|
21719
|
-
|
|
21720
|
-
|
|
21721
|
-
|
|
21722
|
-
|
|
21723
|
-
|
|
21724
|
-
|
|
21725
|
-
|
|
21726
|
-
|
|
21727
|
-
|
|
21728
|
-
|
|
21729
|
-
}, undefined, true, undefined, this) : null
|
|
21863
|
+
toolStream ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
21864
|
+
color: t.dim,
|
|
21865
|
+
children: toolStream.split(`
|
|
21866
|
+
`).slice(-6).join(`
|
|
21867
|
+
`)
|
|
21868
|
+
}, undefined, false, undefined, this) : null,
|
|
21869
|
+
busy ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
21870
|
+
marginTop: streaming || toolStream ? 0 : 1,
|
|
21871
|
+
children: /* @__PURE__ */ jsx_dev_runtime.jsxDEV(WorkingRow, {
|
|
21872
|
+
start: turnStart,
|
|
21873
|
+
tokens: turnTokens,
|
|
21874
|
+
color: t.accent,
|
|
21875
|
+
dim: t.dim
|
|
21876
|
+
}, undefined, false, undefined, this)
|
|
21877
|
+
}, undefined, false, undefined, this) : null
|
|
21730
21878
|
]
|
|
21731
21879
|
}, undefined, true, undefined, this),
|
|
21732
21880
|
suggestions.length ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
@@ -21795,7 +21943,7 @@ function App2({ theme, model, mdlUsd, lines, streaming, sessionMdl, contextPct,
|
|
|
21795
21943
|
]
|
|
21796
21944
|
}, undefined, true, undefined, this),
|
|
21797
21945
|
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
21798
|
-
children: input
|
|
21946
|
+
children: input || (busy ? "" : "")
|
|
21799
21947
|
}, undefined, false, undefined, this),
|
|
21800
21948
|
!busy ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
21801
21949
|
color: t.accent,
|
|
@@ -21831,16 +21979,22 @@ function App2({ theme, model, mdlUsd, lines, streaming, sessionMdl, contextPct,
|
|
|
21831
21979
|
ctxBar,
|
|
21832
21980
|
" ",
|
|
21833
21981
|
contextPct,
|
|
21834
|
-
"%"
|
|
21982
|
+
"%",
|
|
21983
|
+
turnTokens > 0 ? ` · ↓${turnTokens.toLocaleString()} tok` : ""
|
|
21835
21984
|
]
|
|
21836
21985
|
}, undefined, true, undefined, this),
|
|
21837
|
-
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
21986
|
+
exitHint ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
21987
|
+
color: t.warn,
|
|
21988
|
+
children: "press Ctrl-C again to exit"
|
|
21989
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
21838
21990
|
color: t.dim,
|
|
21839
21991
|
children: [
|
|
21840
|
-
sessionMdl.toFixed(
|
|
21992
|
+
sessionMdl.toFixed(4),
|
|
21841
21993
|
" MDL",
|
|
21842
21994
|
usd,
|
|
21843
|
-
" ·
|
|
21995
|
+
" · ",
|
|
21996
|
+
busy ? "esc=stop · " : "",
|
|
21997
|
+
"^C ^C=exit"
|
|
21844
21998
|
]
|
|
21845
21999
|
}, undefined, true, undefined, this)
|
|
21846
22000
|
]
|
|
@@ -22584,13 +22738,15 @@ async function handleSlash(line, ctx) {
|
|
|
22584
22738
|
}
|
|
22585
22739
|
case "/model": {
|
|
22586
22740
|
if (!arg)
|
|
22587
|
-
return { output: `build model: ${cfg.model}${cfg.autoRoute ? " (auto-route
|
|
22741
|
+
return { output: `build model: ${cfg.model}${cfg.autoRoute ? " (auto-route ON — /route to turn off)" : ""}` };
|
|
22588
22742
|
const id = resolveModelName(arg);
|
|
22589
22743
|
if (!id)
|
|
22590
22744
|
return { output: `unknown model '${arg}' — /models to list` };
|
|
22745
|
+
const wasRouting = cfg.autoRoute;
|
|
22591
22746
|
cfg.model = id;
|
|
22592
|
-
|
|
22593
|
-
|
|
22747
|
+
cfg.autoRoute = false;
|
|
22748
|
+
saveConfig({ model: id, autoRoute: false });
|
|
22749
|
+
return { output: `✓ build model → ${id}${wasRouting ? " (auto-route turned OFF — your model is used for every turn)" : ""}`, modeChanged: true };
|
|
22594
22750
|
}
|
|
22595
22751
|
case "/submodel": {
|
|
22596
22752
|
if (!arg) {
|
|
@@ -23606,7 +23762,10 @@ function imageMentions(line, cwd2) {
|
|
|
23606
23762
|
// src/ui/tui.tsx
|
|
23607
23763
|
var jsx_dev_runtime2 = __toESM(require_jsx_dev_runtime(), 1);
|
|
23608
23764
|
function Root({ cfg, resume, mcpCount }) {
|
|
23609
|
-
const [lines, setLines] = import_react35.useState([
|
|
23765
|
+
const [lines, setLines] = import_react35.useState([
|
|
23766
|
+
{ kind: "system", text: `ready · model ${cfg.model} — ask me anything, or /help` },
|
|
23767
|
+
...cfg.autoRoute ? [{ kind: "system", text: `⚠ auto-route is ON — turns may use a different model than ${cfg.model}. Run /route to turn it off (or /model ${cfg.model} to lock it in).` }] : []
|
|
23768
|
+
]);
|
|
23610
23769
|
const [streaming, setStreaming] = import_react35.useState("");
|
|
23611
23770
|
const [busy, setBusy] = import_react35.useState(false);
|
|
23612
23771
|
const [sessionMdl, setSessionMdl] = import_react35.useState(0);
|
|
@@ -23615,14 +23774,25 @@ function Root({ cfg, resume, mcpCount }) {
|
|
|
23615
23774
|
const [mode, setMode] = import_react35.useState("default");
|
|
23616
23775
|
const [confirmReq, setConfirmReq] = import_react35.useState(null);
|
|
23617
23776
|
const [history, setHistory] = import_react35.useState([]);
|
|
23777
|
+
const [toolStream, setToolStream] = import_react35.useState("");
|
|
23778
|
+
const [turnStart, setTurnStart] = import_react35.useState(0);
|
|
23779
|
+
const [turnTokens, setTurnTokens] = import_react35.useState(0);
|
|
23618
23780
|
const mdlUsd = import_react35.useRef(null);
|
|
23619
23781
|
const streamBuf = import_react35.useRef("");
|
|
23782
|
+
const tokensRef = import_react35.useRef(0);
|
|
23620
23783
|
const confirmResolve = import_react35.useRef(null);
|
|
23621
23784
|
const sessionIdRef = import_react35.useRef(newSessionId());
|
|
23622
23785
|
const sessionMdlRef = import_react35.useRef(0);
|
|
23623
23786
|
const mcpCountRef = import_react35.useRef(mcpCount);
|
|
23624
23787
|
const cwd2 = process.cwd();
|
|
23625
23788
|
const add2 = import_react35.useCallback((l) => setLines((prev) => [...prev, l]), []);
|
|
23789
|
+
const flushAssistant = import_react35.useCallback(() => {
|
|
23790
|
+
const txt = streamBuf.current.trim();
|
|
23791
|
+
streamBuf.current = "";
|
|
23792
|
+
setStreaming("");
|
|
23793
|
+
if (txt)
|
|
23794
|
+
setLines((prev) => [...prev, { kind: "assistant", text: txt }]);
|
|
23795
|
+
}, []);
|
|
23626
23796
|
const confirm = import_react35.useCallback((name, args) => {
|
|
23627
23797
|
if (isAllowed(name, cwd2))
|
|
23628
23798
|
return Promise.resolve(true);
|
|
@@ -23643,13 +23813,19 @@ function Root({ cfg, resume, mcpCount }) {
|
|
|
23643
23813
|
onAssistantDelta: (txt) => {
|
|
23644
23814
|
streamBuf.current += txt;
|
|
23645
23815
|
setStreaming(streamBuf.current);
|
|
23816
|
+
tokensRef.current += Math.max(1, Math.round(txt.length / 4));
|
|
23817
|
+
setTurnTokens(tokensRef.current);
|
|
23646
23818
|
},
|
|
23647
|
-
onToolStart: (name, args) =>
|
|
23648
|
-
|
|
23649
|
-
|
|
23650
|
-
|
|
23651
|
-
setStreaming(streamBuf.current);
|
|
23819
|
+
onToolStart: (name, args) => {
|
|
23820
|
+
flushAssistant();
|
|
23821
|
+
setToolStream("");
|
|
23822
|
+
add2({ kind: "tool", text: `${name} ${JSON.stringify(args).slice(0, 80)}` });
|
|
23652
23823
|
},
|
|
23824
|
+
onToolResult: (_n, r) => {
|
|
23825
|
+
setToolStream("");
|
|
23826
|
+
add2({ kind: "system", text: r.slice(0, 300) });
|
|
23827
|
+
},
|
|
23828
|
+
onToolStream: (chunk2) => setToolStream((s) => (s + chunk2).slice(-2000)),
|
|
23653
23829
|
onCost: (g) => setSessionMdl((s) => {
|
|
23654
23830
|
const v = s + g / 1e8;
|
|
23655
23831
|
sessionMdlRef.current = v;
|
|
@@ -23695,33 +23871,38 @@ function Root({ cfg, resume, mcpCount }) {
|
|
|
23695
23871
|
add2({ kind: "system", text: "not logged in — run `modelcode login` (or option 1/2 at startup) to set an API key. /help works without one." });
|
|
23696
23872
|
return;
|
|
23697
23873
|
}
|
|
23698
|
-
setBusy(true);
|
|
23699
23874
|
streamBuf.current = "";
|
|
23700
23875
|
setStreaming("");
|
|
23876
|
+
setToolStream("");
|
|
23877
|
+
tokensRef.current = 0;
|
|
23878
|
+
setTurnTokens(0);
|
|
23879
|
+
setTurnStart(Date.now());
|
|
23880
|
+
setBusy(true);
|
|
23701
23881
|
try {
|
|
23702
23882
|
await agent.send(expandFileMentions(prompt, cwd2), imageMentions(prompt, cwd2));
|
|
23703
|
-
|
|
23704
|
-
add2({ kind: "assistant", text: streamBuf.current });
|
|
23883
|
+
flushAssistant();
|
|
23705
23884
|
saveSession(sessionIdRef.current, cwd2, agent.messages);
|
|
23706
23885
|
const heavyMin = Number(process.env.MODELCODE_AUTOSUMMARY_MIN || "8");
|
|
23707
23886
|
if (cfg.autoSummary && agent.lastTurnToolCount >= heavyMin) {
|
|
23708
|
-
|
|
23887
|
+
tokensRef.current = 0;
|
|
23888
|
+
setTurnTokens(0);
|
|
23889
|
+
setTurnStart(Date.now());
|
|
23709
23890
|
await agent.send("Recap concisely (bullets): what we worked on, key changes/decisions (files touched), current state, and any open/next steps.");
|
|
23710
|
-
|
|
23711
|
-
add2({ kind: "system", text: `— recap —
|
|
23712
|
-
` + streamBuf.current });
|
|
23891
|
+
flushAssistant();
|
|
23713
23892
|
}
|
|
23714
23893
|
} catch (e) {
|
|
23894
|
+
flushAssistant();
|
|
23715
23895
|
add2({ kind: "error", text: e.message });
|
|
23716
23896
|
} finally {
|
|
23717
23897
|
setStreaming("");
|
|
23898
|
+
setToolStream("");
|
|
23718
23899
|
streamBuf.current = "";
|
|
23719
23900
|
setBusy(false);
|
|
23720
23901
|
setContextPct(agent.contextStatus().pct);
|
|
23721
23902
|
setMode(agent.mode);
|
|
23722
23903
|
refreshWallet();
|
|
23723
23904
|
}
|
|
23724
|
-
}, [agent, add2, refreshWallet, cfg, cwd2]);
|
|
23905
|
+
}, [agent, add2, refreshWallet, cfg, cwd2, flushAssistant]);
|
|
23725
23906
|
const onInterrupt = import_react35.useCallback(() => {
|
|
23726
23907
|
agent.abort();
|
|
23727
23908
|
}, [agent]);
|
|
@@ -23770,6 +23951,9 @@ function Root({ cfg, resume, mcpCount }) {
|
|
|
23770
23951
|
walletMdl,
|
|
23771
23952
|
mode,
|
|
23772
23953
|
busy,
|
|
23954
|
+
toolStream,
|
|
23955
|
+
turnStart,
|
|
23956
|
+
turnTokens,
|
|
23773
23957
|
confirmReq,
|
|
23774
23958
|
history,
|
|
23775
23959
|
onConfirm,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modeloslab/modelcode",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "modelOS-native AI coding agent CLI — remembers like Hermes, codes like Claude Code, runs on modelOS (pay-per-use in MDL, no rate limits). Knowledge-graph memory, subagents, MCP, vision, spend caps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|