@modeloslab/modelcode 0.1.2 → 0.1.4
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 +38 -10
- package/dist/{main-k6vk3448.mjs → main-wr686fnv.mjs} +78 -17
- package/dist/{tui-2wxjcqb2.mjs → tui-sekv1hga.mjs} +409 -96
- 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
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
searchFacts,
|
|
57
57
|
searchSessions,
|
|
58
58
|
shellInvocation,
|
|
59
|
+
shellName,
|
|
59
60
|
snapshot,
|
|
60
61
|
spawnProc,
|
|
61
62
|
toolSchemas,
|
|
@@ -63,7 +64,7 @@ import {
|
|
|
63
64
|
validateMnemonic,
|
|
64
65
|
walletFromMnemonic,
|
|
65
66
|
which
|
|
66
|
-
} from "./main-
|
|
67
|
+
} from "./main-wr686fnv.mjs";
|
|
67
68
|
import"./main-p2xnn95s.mjs";
|
|
68
69
|
import {
|
|
69
70
|
__require
|
|
@@ -141,7 +142,7 @@ function inside(cwd, p) {
|
|
|
141
142
|
}
|
|
142
143
|
var bash = {
|
|
143
144
|
name: "bash",
|
|
144
|
-
description:
|
|
145
|
+
description: `Run a shell command in the working directory (shell: ${shellName()}); returns combined stdout+stderr. Use for builds, tests, git, file ops.${shellName() === "powershell" || shellName() === "pwsh" ? " NOTE: this is Windows PowerShell — use PowerShell syntax (Get-ChildItem/ls, Get-Content/cat, 2>$null, Select-Object -First N)." : shellName() === "cmd" ? " NOTE: this is Windows cmd.exe — use cmd syntax." : ""}`,
|
|
145
146
|
permission: "ask",
|
|
146
147
|
parameters: {
|
|
147
148
|
type: "object",
|
|
@@ -331,7 +332,9 @@ function registerAgentTool(cfg, onProgress) {
|
|
|
331
332
|
if (!agent)
|
|
332
333
|
return `error: unknown subagent '${args.subagent_type}'. available: ${names.join(", ")}`;
|
|
333
334
|
const { text, feeGrains } = await runSubagent(cfg, agent, String(args.prompt ?? ""), ctx, onProgress);
|
|
334
|
-
|
|
335
|
+
ctx.onCost?.(feeGrains);
|
|
336
|
+
onProgress?.(` ↳ ${agent.name} done · ${(feeGrains / 1e8).toFixed(4)} MDL`);
|
|
337
|
+
return `[${agent.name} · ${(feeGrains / 1e8).toFixed(6)} MDL]
|
|
335
338
|
${text}`;
|
|
336
339
|
}
|
|
337
340
|
};
|
|
@@ -352,7 +355,8 @@ ${text}`;
|
|
|
352
355
|
async run(args, ctx) {
|
|
353
356
|
const members = Array.isArray(args.members) ? args.members.map(String) : [];
|
|
354
357
|
const { transcript, feeGrains } = await runTeam(cfg, members, String(args.prompt ?? ""), ctx, Number(args.rounds) || 2, onProgress);
|
|
355
|
-
|
|
358
|
+
ctx.onCost?.(feeGrains);
|
|
359
|
+
return `[team · ${(feeGrains / 1e8).toFixed(6)} MDL]
|
|
356
360
|
${transcript}`;
|
|
357
361
|
}
|
|
358
362
|
};
|
|
@@ -407,6 +411,16 @@ class Agent {
|
|
|
407
411
|
note(text) {
|
|
408
412
|
this.history.push({ role: "system", content: `User steering note (apply going forward): ${text}` });
|
|
409
413
|
}
|
|
414
|
+
async sideQuestion(question, onDelta) {
|
|
415
|
+
const forked = [
|
|
416
|
+
...this.history,
|
|
417
|
+
{ role: "system", content: "The user has a quick side question. Answer it concisely using the conversation so far. This does NOT change the current task." },
|
|
418
|
+
{ role: "user", content: question }
|
|
419
|
+
];
|
|
420
|
+
const res = await chat(this.cfg, forked, [], onDelta ?? (() => {}), this.modelFor(question));
|
|
421
|
+
this.h.onCost(res.feeGrains);
|
|
422
|
+
return res.content || "(no answer)";
|
|
423
|
+
}
|
|
410
424
|
get messages() {
|
|
411
425
|
return [...this.history];
|
|
412
426
|
}
|
|
@@ -592,7 +606,7 @@ ${tail}`;
|
|
|
592
606
|
} else {
|
|
593
607
|
if (MUTATING_TOOLS.has(tool.name) && typeof args.path === "string")
|
|
594
608
|
snapshot(this.ctx.cwd, args.path);
|
|
595
|
-
const runCtx = { ...this.ctx, onStream: (c) => this.h.onToolStream?.(c) };
|
|
609
|
+
const runCtx = { ...this.ctx, onStream: (c) => this.h.onToolStream?.(c), onCost: (g) => this.h.onCost(g) };
|
|
596
610
|
try {
|
|
597
611
|
result = await tool.run(args, runCtx);
|
|
598
612
|
} catch (e) {
|
|
@@ -1356,10 +1370,15 @@ async function interactiveLogin(rl, cfg) {
|
|
|
1356
1370
|
` + ` ${C.cyan}3${C.reset}) skip for now
|
|
1357
1371
|
`);
|
|
1358
1372
|
const choice = (await rl.question(`${C.green}choose 1-3\u203A${C.reset} `)).trim();
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1373
|
+
const extractKey = (s) => s.match(/mdlk_[A-Za-z0-9]+/)?.[0] ?? "";
|
|
1374
|
+
if (choice === "1" || /mdlk_/.test(choice)) {
|
|
1375
|
+
let key = extractKey(choice);
|
|
1376
|
+
if (!key)
|
|
1377
|
+
key = extractKey(await rl.question("paste your API key (mdlk_\u2026): "));
|
|
1378
|
+
if (!key)
|
|
1379
|
+
key = extractKey(await rl.question("API key (mdlk_\u2026): "));
|
|
1380
|
+
if (!key) {
|
|
1381
|
+
stdout.write(`${C.amber}that doesn't look like an mdlk_ key \u2014 it should start with "mdlk_"${C.reset}
|
|
1363
1382
|
`);
|
|
1364
1383
|
return false;
|
|
1365
1384
|
}
|
|
@@ -1580,8 +1599,17 @@ async function main() {
|
|
|
1580
1599
|
const rl = createInterface({ input: stdin, output: stdout });
|
|
1581
1600
|
await interactiveLogin(rl, cfg);
|
|
1582
1601
|
rl.close();
|
|
1602
|
+
const s = stdin;
|
|
1603
|
+
s.removeAllListeners("data");
|
|
1604
|
+
s.removeAllListeners("keypress");
|
|
1605
|
+
try {
|
|
1606
|
+
if (s.isTTY)
|
|
1607
|
+
s.setRawMode(false);
|
|
1608
|
+
} catch {}
|
|
1609
|
+
s.resume();
|
|
1610
|
+
await new Promise((r) => setImmediate(r));
|
|
1583
1611
|
}
|
|
1584
|
-
const { runTui } = await import("./tui-
|
|
1612
|
+
const { runTui } = await import("./tui-sekv1hga.mjs");
|
|
1585
1613
|
return runTui(cfg, resume);
|
|
1586
1614
|
}
|
|
1587
1615
|
if (cmd === "tui")
|
|
@@ -7966,7 +7966,19 @@ var isWin = process.platform === "win32";
|
|
|
7966
7966
|
function shellInvocation(cmd) {
|
|
7967
7967
|
if (!isWin)
|
|
7968
7968
|
return ["bash", "-lc", cmd];
|
|
7969
|
-
|
|
7969
|
+
if (hasBash())
|
|
7970
|
+
return ["bash", "-c", cmd];
|
|
7971
|
+
const ps = powershellBin();
|
|
7972
|
+
if (ps)
|
|
7973
|
+
return [ps, "-NoProfile", "-NonInteractive", "-Command", cmd];
|
|
7974
|
+
return ["cmd", "/c", cmd];
|
|
7975
|
+
}
|
|
7976
|
+
function shellName() {
|
|
7977
|
+
if (!isWin)
|
|
7978
|
+
return "bash";
|
|
7979
|
+
if (hasBash())
|
|
7980
|
+
return "bash";
|
|
7981
|
+
return powershellBin() ?? "cmd";
|
|
7970
7982
|
}
|
|
7971
7983
|
var _bash = null;
|
|
7972
7984
|
function hasBash() {
|
|
@@ -7979,6 +7991,19 @@ function hasBash() {
|
|
|
7979
7991
|
}
|
|
7980
7992
|
return _bash;
|
|
7981
7993
|
}
|
|
7994
|
+
var _ps;
|
|
7995
|
+
function powershellBin() {
|
|
7996
|
+
if (_ps !== undefined)
|
|
7997
|
+
return _ps;
|
|
7998
|
+
for (const bin of ["pwsh", "powershell"]) {
|
|
7999
|
+
try {
|
|
8000
|
+
if (spawnSync(bin, ["-NoProfile", "-Command", "exit 0"], { stdio: "ignore" }).status === 0) {
|
|
8001
|
+
return _ps = bin;
|
|
8002
|
+
}
|
|
8003
|
+
} catch {}
|
|
8004
|
+
}
|
|
8005
|
+
return _ps = null;
|
|
8006
|
+
}
|
|
7982
8007
|
function packageRoot(startDir) {
|
|
7983
8008
|
let dir = startDir;
|
|
7984
8009
|
for (let i = 0;i < 12; i++) {
|
|
@@ -21025,6 +21050,7 @@ async function chat2(cfg, messages, tools, onDelta, modelOverride, timeoutMs = 1
|
|
|
21025
21050
|
messages,
|
|
21026
21051
|
max_tokens: cfg.maxTokens,
|
|
21027
21052
|
stream: true,
|
|
21053
|
+
stream_options: { include_usage: true },
|
|
21028
21054
|
...tools.length ? { tools, tool_choice: "auto" } : {}
|
|
21029
21055
|
};
|
|
21030
21056
|
const attempt = async (live) => {
|
|
@@ -21032,7 +21058,13 @@ async function chat2(cfg, messages, tools, onDelta, modelOverride, timeoutMs = 1
|
|
|
21032
21058
|
let content = "";
|
|
21033
21059
|
let finishReason = null;
|
|
21034
21060
|
let feeGrains = 0;
|
|
21061
|
+
let promptTokens = 0, completionTokens = 0;
|
|
21035
21062
|
const calls = {};
|
|
21063
|
+
const readFee = (o) => {
|
|
21064
|
+
const x = o;
|
|
21065
|
+
const v = x?.x_modelos?.fee_grains ?? x?.fee_grains ?? x?.cost_grains;
|
|
21066
|
+
return v != null ? Number(v) || 0 : 0;
|
|
21067
|
+
};
|
|
21036
21068
|
for await (const chunk of stream) {
|
|
21037
21069
|
const choice = chunk.choices?.[0];
|
|
21038
21070
|
const delta = choice?.delta;
|
|
@@ -21053,22 +21085,33 @@ async function chat2(cfg, messages, tools, onDelta, modelOverride, timeoutMs = 1
|
|
|
21053
21085
|
}
|
|
21054
21086
|
if (choice?.finish_reason)
|
|
21055
21087
|
finishReason = choice.finish_reason;
|
|
21056
|
-
|
|
21057
|
-
|
|
21058
|
-
|
|
21088
|
+
feeGrains = readFee(chunk) || readFee(chunk.usage) || feeGrains;
|
|
21089
|
+
const usage = chunk.usage;
|
|
21090
|
+
if (usage) {
|
|
21091
|
+
promptTokens = usage.prompt_tokens ?? promptTokens;
|
|
21092
|
+
completionTokens = usage.completion_tokens ?? completionTokens;
|
|
21093
|
+
}
|
|
21059
21094
|
}
|
|
21060
|
-
return { content, toolCalls: Object.values(calls), finishReason, feeGrains };
|
|
21095
|
+
return { content, toolCalls: Object.values(calls), finishReason, feeGrains, promptTokens, completionTokens };
|
|
21061
21096
|
};
|
|
21062
|
-
|
|
21063
|
-
|
|
21064
|
-
} catch (e) {
|
|
21065
|
-
await new Promise((r) => setTimeout(r, 1500));
|
|
21097
|
+
let lastErr;
|
|
21098
|
+
for (let i = 0;i < 3; i++) {
|
|
21066
21099
|
try {
|
|
21067
21100
|
return await attempt(true);
|
|
21068
|
-
} catch {
|
|
21069
|
-
|
|
21101
|
+
} catch (e) {
|
|
21102
|
+
lastErr = e;
|
|
21103
|
+
const status = e.status;
|
|
21104
|
+
if (status && status >= 400 && status < 500)
|
|
21105
|
+
break;
|
|
21106
|
+
if (i < 2)
|
|
21107
|
+
await new Promise((r) => setTimeout(r, 1000 * (i + 1)));
|
|
21070
21108
|
}
|
|
21071
21109
|
}
|
|
21110
|
+
const err = lastErr;
|
|
21111
|
+
const reachable = err?.status !== undefined;
|
|
21112
|
+
if (!reachable)
|
|
21113
|
+
throw new Error(`inference API not reachable (${cfg.baseUrl}) — check your connection. ${err?.message ?? err?.code ?? ""}`.trim());
|
|
21114
|
+
throw new Error(`inference API error${err.status ? ` (HTTP ${err.status})` : ""}: ${err.message ?? "request rejected"}`);
|
|
21072
21115
|
}
|
|
21073
21116
|
|
|
21074
21117
|
// src/router/router.ts
|
|
@@ -21387,21 +21430,39 @@ async function runSubagent(cfg2, agent, task, ctx, onProgress, extraTools = [])
|
|
|
21387
21430
|
const granted = base ? [...base, ...extraTools] : extraTools.length ? [...allTools(), ...extraTools] : null;
|
|
21388
21431
|
const tools = granted ? granted.map((t) => ({ type: "function", function: { name: t.name, description: t.description, parameters: t.parameters } })) : toolSchemas();
|
|
21389
21432
|
const lookup = (name) => granted ? granted.find((t) => t.name === name) : getTool(name);
|
|
21390
|
-
const
|
|
21433
|
+
const env = `Working directory: ${ctx.cwd}
|
|
21434
|
+
Platform: ${process.platform}
|
|
21435
|
+
Today: ${new Date().toISOString().slice(0, 10)}`;
|
|
21436
|
+
const projSlice = loadProjectContext(ctx.cwd).slice(0, 4000);
|
|
21437
|
+
const turnCtx = (buildTurnContext(task, ctx.cwd, {}) || "").slice(0, 4000);
|
|
21438
|
+
const sys = [agent.systemPrompt, env, projSlice, turnCtx].filter(Boolean).join(`
|
|
21439
|
+
|
|
21440
|
+
`);
|
|
21391
21441
|
const history = [
|
|
21392
|
-
{ role: "system", content:
|
|
21393
|
-
...turnCtx ? [{ role: "system", content: turnCtx }] : [],
|
|
21442
|
+
{ role: "system", content: sys },
|
|
21394
21443
|
{ role: "user", content: task }
|
|
21395
21444
|
];
|
|
21396
21445
|
let feeGrains = 0;
|
|
21397
21446
|
const routed = cfg2.autoRoute ? route(task)?.model : undefined;
|
|
21398
21447
|
const subModel = cfg2.subagentModel || routed || agent.model || cfg2.model;
|
|
21448
|
+
onProgress?.(` ↳ ${agent.name} on ${subModel}`);
|
|
21449
|
+
const RESULT_CAP = Number(process.env.MODELCODE_MAX_TOOL_RESULT || "40000");
|
|
21450
|
+
const capResult = (s) => s.length <= RESULT_CAP ? s : `${s.slice(0, Math.floor(RESULT_CAP * 0.7))}
|
|
21451
|
+
|
|
21452
|
+
…[truncated ${s.length - RESULT_CAP} chars]…
|
|
21453
|
+
|
|
21454
|
+
${s.slice(-Math.floor(RESULT_CAP * 0.2))}`;
|
|
21399
21455
|
const finish = (text) => {
|
|
21400
21456
|
fireEvent("subagentStop", ctx.cwd, { AGENT: agent.name, RESULT: text.slice(0, 4000) }).catch(() => {});
|
|
21401
21457
|
return { text, feeGrains };
|
|
21402
21458
|
};
|
|
21403
21459
|
for (let step = 0;step < MAX_STEPS; step++) {
|
|
21404
|
-
|
|
21460
|
+
let res;
|
|
21461
|
+
try {
|
|
21462
|
+
res = await chat2(cfg2, history, tools, () => {}, subModel, 120000);
|
|
21463
|
+
} catch (e) {
|
|
21464
|
+
return finish(`error: ${agent.name} (${subModel}) — ${e.message}`);
|
|
21465
|
+
}
|
|
21405
21466
|
feeGrains += res.feeGrains;
|
|
21406
21467
|
history.push({ role: "assistant", content: res.content || null, ...res.toolCalls.length ? { tool_calls: res.toolCalls } : {} });
|
|
21407
21468
|
if (!res.toolCalls.length)
|
|
@@ -21423,7 +21484,7 @@ async function runSubagent(cfg2, agent, task, ctx, onProgress, extraTools = [])
|
|
|
21423
21484
|
result = `error: ${e.message}`;
|
|
21424
21485
|
}
|
|
21425
21486
|
}
|
|
21426
|
-
history.push({ role: "tool", tool_call_id: call.id, name: call.function.name, content: result });
|
|
21487
|
+
history.push({ role: "tool", tool_call_id: call.id, name: call.function.name, content: capResult(result) });
|
|
21427
21488
|
}
|
|
21428
21489
|
}
|
|
21429
21490
|
return finish("(subagent hit the step limit without finishing)");
|
|
@@ -24254,4 +24315,4 @@ async function decryptWallet(enc, password, network = MAINNET) {
|
|
|
24254
24315
|
}
|
|
24255
24316
|
return w;
|
|
24256
24317
|
}
|
|
24257
|
-
export { exports_external, register, getTool, toolSchemas, renderDiff, shellInvocation, globMatch, runProc, which, spawnProc, globalDir, loadConfig, saveConfig, rememberFact, allFacts, searchFacts, deleteFact, recordTurn, searchSessions, parseFrontmatter, loadSubagents, chat2 as chat, route, loadProjectContext, addEntity, addRelation, query, indexFile, indexCodebaseIncremental, indexCodebase, loadSkills, buildTurnContext, preToolUse, postToolUse, userPromptSubmit, fireEvent, runSubagent, runTeam, isImagePath, imageToDataUrl, estimateTokens, contextStatus, compactionThreshold, findCompactionCut, newTurn, snapshot, undo, depth, MUTATING_TOOLS, isProtectedBuiltin, recordUse, recordPatch, recordCreate, getUsage, allUsage, activityCount, analyzeImpact, impactSummary, lspFor, closeAllLsp, COLUMNS, addCard, moveCard, removeCard, renderBoard, addJob, listJobs, removeJob, startScheduler, MAINNET, generateMnemonic2 as generateMnemonic, validateMnemonic2 as validateMnemonic, walletFromMnemonic, importWalletHex, encryptWallet, decryptWallet, createTransfer };
|
|
24318
|
+
export { exports_external, register, getTool, toolSchemas, renderDiff, shellInvocation, shellName, globMatch, runProc, which, spawnProc, globalDir, loadConfig, saveConfig, rememberFact, allFacts, searchFacts, deleteFact, recordTurn, searchSessions, parseFrontmatter, loadSubagents, chat2 as chat, route, loadProjectContext, addEntity, addRelation, query, indexFile, indexCodebaseIncremental, indexCodebase, loadSkills, buildTurnContext, preToolUse, postToolUse, userPromptSubmit, fireEvent, runSubagent, runTeam, isImagePath, imageToDataUrl, estimateTokens, contextStatus, compactionThreshold, findCompactionCut, newTurn, snapshot, undo, depth, MUTATING_TOOLS, isProtectedBuiltin, recordUse, recordPatch, recordCreate, getUsage, allUsage, activityCount, analyzeImpact, impactSummary, lspFor, closeAllLsp, COLUMNS, addCard, moveCard, removeCard, renderBoard, addJob, listJobs, removeJob, startScheduler, MAINNET, generateMnemonic2 as generateMnemonic, validateMnemonic2 as validateMnemonic, walletFromMnemonic, importWalletHex, encryptWallet, decryptWallet, createTransfer };
|