micro-models-agent 0.43.3 → 0.45.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 +312 -312
- package/bin/mma.mjs +41 -41
- package/dist/main.js +333 -66
- package/dist/skills/builtin/git.md +36 -36
- package/dist/skills/builtin/typescript.md +35 -35
- package/package.json +1 -1
- package/dist/cli/commands.js +0 -333
- package/dist/cli/completer.js +0 -168
- package/dist/cli/index.js +0 -2
- package/dist/cli/main.js +0 -140
- package/dist/cli/repl-commands.js +0 -633
- package/dist/cli/repl.js +0 -486
- package/dist/cli/security-commands.js +0 -166
- package/dist/cli/setup.js +0 -249
- package/dist/config/config.js +0 -202
- package/dist/config/defaults.js +0 -100
- package/dist/config/experts.js +0 -15
- package/dist/config/index.js +0 -3
- package/dist/config/security.js +0 -200
- package/dist/config/types.js +0 -1
- package/dist/core/agent-moe.js +0 -110
- package/dist/core/agent.js +0 -695
- package/dist/core/bootstrap.js +0 -337
- package/dist/core/index.js +0 -2
- package/dist/core/prompt-builder.js +0 -55
- package/dist/core/session-logger.js +0 -155
- package/dist/core/types.js +0 -1
- package/dist/core/workspace.js +0 -76
- package/dist/i18n/en.json +0 -525
- package/dist/i18n/index.js +0 -46
- package/dist/i18n/ru.json +0 -525
- package/dist/index.js +0 -22
- package/dist/llm/image-utils.js +0 -144
- package/dist/llm/index.js +0 -4
- package/dist/llm/model-loader.js +0 -78
- package/dist/llm/openai-compat.js +0 -353
- package/dist/llm/orchestrator.js +0 -194
- package/dist/llm/provider.js +0 -10
- package/dist/llm/response.js +0 -39
- package/dist/llm/token-counter.js +0 -39
- package/dist/llm/types.js +0 -1
- package/dist/logger/app-logger.js +0 -143
- package/dist/logger/file-log.js +0 -151
- package/dist/logger/index.js +0 -1
- package/dist/migration/backup.js +0 -45
- package/dist/migration/detect.js +0 -50
- package/dist/migration/index.js +0 -2
- package/dist/modules/browser/actions.js +0 -46
- package/dist/modules/browser/cookie-store.js +0 -24
- package/dist/modules/browser/index.js +0 -5
- package/dist/modules/browser/module.js +0 -28
- package/dist/modules/browser/session.js +0 -335
- package/dist/modules/browser/snapshot.js +0 -114
- package/dist/modules/browser/types.js +0 -9
- package/dist/modules/certification/cli.js +0 -176
- package/dist/modules/certification/fact-checker.js +0 -84
- package/dist/modules/certification/loader.js +0 -111
- package/dist/modules/certification/manifest.js +0 -50
- package/dist/modules/certification/runner.js +0 -162
- package/dist/modules/certification/scenarios.js +0 -124
- package/dist/modules/certification/types.js +0 -1
- package/dist/modules/context/index.js +0 -1
- package/dist/modules/context/manager.js +0 -349
- package/dist/modules/execution/auditor.js +0 -66
- package/dist/modules/execution/index.js +0 -8
- package/dist/modules/execution/module.js +0 -779
- package/dist/modules/execution/moe-executor.js +0 -266
- package/dist/modules/execution/plan-coverage.js +0 -68
- package/dist/modules/execution/plan-persister.js +0 -46
- package/dist/modules/execution/plan-store.js +0 -159
- package/dist/modules/execution/plan-validator.js +0 -153
- package/dist/modules/execution/planner.js +0 -85
- package/dist/modules/execution/stuck-detector.js +0 -347
- package/dist/modules/execution/tracker.js +0 -67
- package/dist/modules/execution/types.js +0 -1
- package/dist/modules/execution/verifier.js +0 -178
- package/dist/modules/hallucination/confidence.js +0 -59
- package/dist/modules/hallucination/consistency.js +0 -26
- package/dist/modules/hallucination/detector.js +0 -46
- package/dist/modules/hallucination/factual.js +0 -190
- package/dist/modules/hallucination/index.js +0 -5
- package/dist/modules/hallucination/js-identifiers.js +0 -72
- package/dist/modules/hallucination/llm-judge.js +0 -103
- package/dist/modules/index.js +0 -5
- package/dist/modules/indexer/cache.js +0 -38
- package/dist/modules/indexer/index.js +0 -3
- package/dist/modules/indexer/module.js +0 -192
- package/dist/modules/indexer/walker.js +0 -101
- package/dist/modules/lsp/client.js +0 -235
- package/dist/modules/lsp/config.js +0 -81
- package/dist/modules/lsp/index.js +0 -3
- package/dist/modules/lsp/module.js +0 -68
- package/dist/modules/lsp/types.js +0 -1
- package/dist/modules/mcp/client.js +0 -399
- package/dist/modules/mcp/index.js +0 -3
- package/dist/modules/mcp/module.js +0 -146
- package/dist/modules/mcp/registry.js +0 -15
- package/dist/modules/memory/index.js +0 -1
- package/dist/modules/memory/module.js +0 -48
- package/dist/modules/memory/search.js +0 -40
- package/dist/modules/memory/store.js +0 -69
- package/dist/modules/pipelines/engine.js +0 -60
- package/dist/modules/pipelines/index.js +0 -3
- package/dist/modules/pipelines/parser.js +0 -53
- package/dist/modules/pipelines/template.js +0 -14
- package/dist/modules/plugins/builtin/lint-on-write.js +0 -226
- package/dist/modules/plugins/builtin/notify.js +0 -8
- package/dist/modules/plugins/index.js +0 -1
- package/dist/modules/plugins/loader.js +0 -28
- package/dist/modules/plugins/manager.js +0 -161
- package/dist/modules/plugins/types.js +0 -1
- package/dist/modules/processes/index.js +0 -2
- package/dist/modules/processes/registry.js +0 -238
- package/dist/modules/processes/runner.js +0 -23
- package/dist/modules/registry.js +0 -45
- package/dist/modules/security/audit-log.js +0 -136
- package/dist/modules/security/audit-notifier.js +0 -292
- package/dist/modules/security/command-validator.js +0 -211
- package/dist/modules/security/content-scanner.js +0 -53
- package/dist/modules/security/data-sanitizer.js +0 -97
- package/dist/modules/security/encryption.js +0 -240
- package/dist/modules/security/index.js +0 -14
- package/dist/modules/security/network-validator.js +0 -79
- package/dist/modules/security/path-validator.js +0 -209
- package/dist/modules/security/rate-limiter.js +0 -119
- package/dist/modules/security/security-policies.js +0 -547
- package/dist/modules/security/session-encryption.js +0 -210
- package/dist/modules/security/session-isolation.js +0 -95
- package/dist/modules/session/index.js +0 -3
- package/dist/modules/session/manager.js +0 -172
- package/dist/modules/session/module.js +0 -24
- package/dist/modules/session/store.js +0 -228
- package/dist/modules/session/types.js +0 -1
- package/dist/modules/skills/index.js +0 -2
- package/dist/modules/skills/loader.js +0 -72
- package/dist/modules/skills/module.js +0 -130
- package/dist/modules/types.js +0 -1
- package/dist/modules/updater/checker.js +0 -32
- package/dist/modules/updater/index.js +0 -1
- package/dist/modules/user-profile/compressor.js +0 -16
- package/dist/modules/user-profile/index.js +0 -1
- package/dist/modules/user-profile/profile.js +0 -68
- package/dist/tools/approve.js +0 -32
- package/dist/tools/attach-image.js +0 -89
- package/dist/tools/bash.js +0 -337
- package/dist/tools/browser.js +0 -97
- package/dist/tools/create-dir.js +0 -55
- package/dist/tools/delete-file.js +0 -62
- package/dist/tools/edit-file.js +0 -79
- package/dist/tools/executor.js +0 -145
- package/dist/tools/file-info.js +0 -45
- package/dist/tools/filter-tools.js +0 -10
- package/dist/tools/glob-tool.js +0 -26
- package/dist/tools/grep-tool.js +0 -86
- package/dist/tools/index.js +0 -67
- package/dist/tools/list-dir.js +0 -47
- package/dist/tools/load-skill.js +0 -44
- package/dist/tools/mcp-call.js +0 -68
- package/dist/tools/move-file.js +0 -85
- package/dist/tools/path-utils.js +0 -51
- package/dist/tools/pipeline-run.js +0 -144
- package/dist/tools/preview.js +0 -2
- package/dist/tools/process-kill.js +0 -29
- package/dist/tools/process-list.js +0 -38
- package/dist/tools/process-log.js +0 -41
- package/dist/tools/question.js +0 -142
- package/dist/tools/read-file.js +0 -83
- package/dist/tools/recall.js +0 -110
- package/dist/tools/registry.js +0 -36
- package/dist/tools/remember.js +0 -67
- package/dist/tools/scope-check.js +0 -30
- package/dist/tools/search-history.js +0 -84
- package/dist/tools/subagent.js +0 -151
- package/dist/tools/types.js +0 -1
- package/dist/tools/user-input.js +0 -123
- package/dist/tools/web-browse.js +0 -86
- package/dist/tools/web-fetch.js +0 -98
- package/dist/tools/web-search.js +0 -78
- package/dist/tools/write-file.js +0 -83
- package/dist/ui/box.js +0 -81
- package/dist/ui/colors.js +0 -4
- package/dist/ui/diff.js +0 -178
- package/dist/ui/index.js +0 -6
- package/dist/ui/md-formatter.js +0 -212
- package/dist/ui/output.js +0 -13
- package/dist/ui/renderer.js +0 -204
- package/dist/ui/spinner.js +0 -70
- package/dist/ui/table.js +0 -144
package/dist/main.js
CHANGED
|
@@ -2298,6 +2298,10 @@ var init_defaults = __esm(() => {
|
|
|
2298
2298
|
maxSearchesPerSession: 3,
|
|
2299
2299
|
requestTimeoutMs: 1e4
|
|
2300
2300
|
},
|
|
2301
|
+
pricing: {
|
|
2302
|
+
enabled: true,
|
|
2303
|
+
overrides: {}
|
|
2304
|
+
},
|
|
2301
2305
|
ui: {
|
|
2302
2306
|
spinner: true,
|
|
2303
2307
|
toolStyle: "inline",
|
|
@@ -2390,6 +2394,7 @@ Use read_file on {path} to see the current content before editing — the target
|
|
|
2390
2394
|
"error.http": "HTTP {status}: {statusText}",
|
|
2391
2395
|
"error.llm_api": "LLM API error {status} ({statusText}): {errorText}",
|
|
2392
2396
|
"error.llm_retries": "LLM request failed after retries",
|
|
2397
|
+
"error.llm_429": "Rate limit exceeded (HTTP 429) for {model} on {baseUrl}. The provider is throttling requests — free models are especially strict. Get an API key or switch to a paid/faster model: {baseUrl}",
|
|
2393
2398
|
"error.no_response_body": "No response body stream",
|
|
2394
2399
|
"session.started": "Session started: {id}",
|
|
2395
2400
|
"session.ended": "Session ended: {id}",
|
|
@@ -2999,7 +3004,10 @@ Apply a matching solution from these results. If none is relevant — do NOT rep
|
|
|
2999
3004
|
"tools.enable_already_active": "Tool tags already active: {tags}.",
|
|
3000
3005
|
"tools.enable_added": "Enabled tool tags: {tags}. Available tools now: {tools}",
|
|
3001
3006
|
"tools.hidden_header": "Additional tools (enable on demand via enable_tools or route to subagent tool_tags):",
|
|
3002
|
-
"tool.friendly.enable_tools": "Enable tools"
|
|
3007
|
+
"tool.friendly.enable_tools": "Enable tools",
|
|
3008
|
+
"cli.provider_base_hint": "Base URL set to: {baseUrl}",
|
|
3009
|
+
"repl.cost": "Total cost: {cost}",
|
|
3010
|
+
"repl.tokens": "Tokens used: {tokens}"
|
|
3003
3011
|
};
|
|
3004
3012
|
});
|
|
3005
3013
|
|
|
@@ -3049,6 +3057,7 @@ var init_ru = __esm(() => {
|
|
|
3049
3057
|
"error.http": "HTTP {status}: {statusText}",
|
|
3050
3058
|
"error.llm_api": "Ошибка LLM API {status} ({statusText}): {errorText}",
|
|
3051
3059
|
"error.llm_retries": "Запрос LLM не удался после повторов",
|
|
3060
|
+
"error.llm_429": "Превышен лимит запросов (HTTP 429) для {model} на {baseUrl}. Провайдер ограничивает трафик — особенно строгие free-модели. Получите API-ключ или переключитесь на платную/быструю модель: {baseUrl}",
|
|
3052
3061
|
"error.no_response_body": "Нет потока тела ответа",
|
|
3053
3062
|
"session.started": "Сессия начата: {id}",
|
|
3054
3063
|
"session.ended": "Сессия завершена: {id}",
|
|
@@ -3659,7 +3668,10 @@ var init_ru = __esm(() => {
|
|
|
3659
3668
|
"tools.enable_already_active": "Теги тулов уже активны: {tags}.",
|
|
3660
3669
|
"tools.enable_added": "Включены теги тулов: {tags}. Теперь доступны тулы: {tools}",
|
|
3661
3670
|
"tools.hidden_header": "Дополнительные тулы (включите по требованию через enable_tools или маршрутизируйте через subagent tool_tags):",
|
|
3662
|
-
"tool.friendly.enable_tools": "Включить тулы"
|
|
3671
|
+
"tool.friendly.enable_tools": "Включить тулы",
|
|
3672
|
+
"cli.provider_base_hint": "Базовый URL установлен: {baseUrl}",
|
|
3673
|
+
"repl.cost": "Итого потрачено: {cost}",
|
|
3674
|
+
"repl.tokens": "Потрачено токенов: {tokens}"
|
|
3663
3675
|
};
|
|
3664
3676
|
});
|
|
3665
3677
|
|
|
@@ -5421,26 +5433,36 @@ class OpenAICompatProvider {
|
|
|
5421
5433
|
}
|
|
5422
5434
|
async fetchWithRetry(url, init) {
|
|
5423
5435
|
const { maxRetries, baseDelay, maxDelay } = this.retryConfig;
|
|
5424
|
-
let
|
|
5436
|
+
let lastStatus = 0;
|
|
5437
|
+
let lastRetryAfter = 0;
|
|
5425
5438
|
for (let attempt = 0;attempt <= maxRetries; attempt++) {
|
|
5426
5439
|
try {
|
|
5427
5440
|
const response = await fetch(url, init);
|
|
5428
5441
|
if (!this.isRetryable(response.status))
|
|
5429
5442
|
return response;
|
|
5430
|
-
|
|
5443
|
+
lastStatus = response.status;
|
|
5444
|
+
const retryAfter = Number(response.headers.get("retry-after") ?? 0);
|
|
5445
|
+
lastRetryAfter = retryAfter > 0 ? retryAfter * 1000 : 0;
|
|
5431
5446
|
} catch (err) {
|
|
5432
5447
|
if (err.name === "AbortError") {
|
|
5433
5448
|
throw err;
|
|
5434
5449
|
}
|
|
5435
|
-
|
|
5450
|
+
if (attempt === maxRetries)
|
|
5451
|
+
throw err;
|
|
5436
5452
|
}
|
|
5437
5453
|
if (attempt < maxRetries) {
|
|
5438
|
-
const delay = Math.min(baseDelay * Math.pow(2, attempt), maxDelay);
|
|
5454
|
+
const delay = lastRetryAfter > 0 ? Math.min(lastRetryAfter, maxDelay) : Math.min(baseDelay * Math.pow(2, attempt), maxDelay);
|
|
5439
5455
|
const jitter = Math.random() * baseDelay * 0.1;
|
|
5440
5456
|
await this.sleep(delay + jitter, init.signal ?? undefined);
|
|
5441
5457
|
}
|
|
5442
5458
|
}
|
|
5443
|
-
|
|
5459
|
+
if (lastStatus === 429) {
|
|
5460
|
+
throw new Error(t("error.llm_429", {
|
|
5461
|
+
model: this.model,
|
|
5462
|
+
baseUrl: this.config.baseUrl
|
|
5463
|
+
}));
|
|
5464
|
+
}
|
|
5465
|
+
throw new Error(t("error.llm_retries"));
|
|
5444
5466
|
}
|
|
5445
5467
|
isRetryable(status) {
|
|
5446
5468
|
return status === 429 || status >= 500;
|
|
@@ -6292,6 +6314,7 @@ var init_read_file = __esm(() => {
|
|
|
6292
6314
|
init_path_utils();
|
|
6293
6315
|
readFileTool = {
|
|
6294
6316
|
name: "read_file",
|
|
6317
|
+
icon: "\uD83D\uDC40",
|
|
6295
6318
|
description: `Read a file from the filesystem. Reads up to ${DEFAULT_LIMIT} lines at a time by default; use offset to page through large files.`,
|
|
6296
6319
|
tags: ["file", "code"],
|
|
6297
6320
|
boundedOutput: true,
|
|
@@ -6661,6 +6684,7 @@ var init_write_file = __esm(() => {
|
|
|
6661
6684
|
init_path_utils();
|
|
6662
6685
|
writeFileTool = {
|
|
6663
6686
|
name: "write_file",
|
|
6687
|
+
icon: "\uD83D\uDCDD",
|
|
6664
6688
|
description: "Create or overwrite a file with given content. Creates intermediate directories if needed.",
|
|
6665
6689
|
tags: ["file", "code"],
|
|
6666
6690
|
parameters: {
|
|
@@ -6736,6 +6760,7 @@ var init_edit_file = __esm(() => {
|
|
|
6736
6760
|
init_path_utils();
|
|
6737
6761
|
editFileTool = {
|
|
6738
6762
|
name: "edit_file",
|
|
6763
|
+
icon: "✏️",
|
|
6739
6764
|
description: "Find and replace text in an existing file. Uses exact string match (not regex).",
|
|
6740
6765
|
tags: ["file", "code"],
|
|
6741
6766
|
parameters: {
|
|
@@ -6809,6 +6834,7 @@ var init_glob_tool = __esm(() => {
|
|
|
6809
6834
|
init_i18n();
|
|
6810
6835
|
globTool = {
|
|
6811
6836
|
name: "glob",
|
|
6837
|
+
icon: "\uD83D\uDD0E",
|
|
6812
6838
|
description: `Search for files matching a glob pattern. Shows up to ${MAX_PREVIEW_LINES} results by default. Uses standard glob syntax (e.g., **/*.ts, src/**/*.test.ts).`,
|
|
6813
6839
|
tags: ["file", "code", "research"],
|
|
6814
6840
|
parameters: {
|
|
@@ -6850,6 +6876,7 @@ var init_grep_tool = __esm(() => {
|
|
|
6850
6876
|
init_audit_log();
|
|
6851
6877
|
grepTool = {
|
|
6852
6878
|
name: "grep",
|
|
6879
|
+
icon: "\uD83D\uDD0D",
|
|
6853
6880
|
description: `Search file contents using a regular expression. Shows up to ${MAX_PREVIEW_LINES} matching lines by default. Uses ripgrep (rg) if available, otherwise falls back to grep -r.`,
|
|
6854
6881
|
tags: ["file", "code", "research"],
|
|
6855
6882
|
parameters: {
|
|
@@ -6925,6 +6952,7 @@ var init_list_dir = __esm(() => {
|
|
|
6925
6952
|
init_path_utils();
|
|
6926
6953
|
listDirTool = {
|
|
6927
6954
|
name: "list_dir",
|
|
6955
|
+
icon: "\uD83D\uDCC2",
|
|
6928
6956
|
description: `List files and directories in a given path. Shows up to ${MAX_PREVIEW_LINES} entries by default.`,
|
|
6929
6957
|
tags: ["file"],
|
|
6930
6958
|
boundedOutput: true,
|
|
@@ -6977,6 +7005,7 @@ var init_create_dir = __esm(() => {
|
|
|
6977
7005
|
init_path_utils();
|
|
6978
7006
|
createDirTool = {
|
|
6979
7007
|
name: "create_dir",
|
|
7008
|
+
icon: "\uD83D\uDCC1",
|
|
6980
7009
|
description: "Create a directory (and any intermediate directories).",
|
|
6981
7010
|
tags: ["file"],
|
|
6982
7011
|
parameters: {
|
|
@@ -7031,6 +7060,7 @@ var init_delete_file = __esm(() => {
|
|
|
7031
7060
|
init_path_utils();
|
|
7032
7061
|
deleteFileTool = {
|
|
7033
7062
|
name: "delete_file",
|
|
7063
|
+
icon: "\uD83D\uDDD1️",
|
|
7034
7064
|
description: "Delete a file from the filesystem.",
|
|
7035
7065
|
tags: ["file"],
|
|
7036
7066
|
parameters: {
|
|
@@ -7092,6 +7122,7 @@ var init_move_file = __esm(() => {
|
|
|
7092
7122
|
init_path_utils();
|
|
7093
7123
|
moveFileTool = {
|
|
7094
7124
|
name: "move_file",
|
|
7125
|
+
icon: "\uD83D\uDCE6",
|
|
7095
7126
|
description: "Move or rename a file or directory.",
|
|
7096
7127
|
tags: ["file"],
|
|
7097
7128
|
parameters: {
|
|
@@ -7170,6 +7201,7 @@ var init_file_info = __esm(() => {
|
|
|
7170
7201
|
init_path_utils();
|
|
7171
7202
|
fileInfoTool = {
|
|
7172
7203
|
name: "file_info",
|
|
7204
|
+
icon: "ℹ️",
|
|
7173
7205
|
description: "Get metadata about a file or directory (size, creation date, modification date).",
|
|
7174
7206
|
tags: ["file"],
|
|
7175
7207
|
boundedOutput: true,
|
|
@@ -7844,6 +7876,7 @@ var init_bash = __esm(() => {
|
|
|
7844
7876
|
NPM_EXEC_RE = /could not determine executable to run/i;
|
|
7845
7877
|
bashTool = {
|
|
7846
7878
|
name: "bash",
|
|
7879
|
+
icon: "\uD83D\uDCBB",
|
|
7847
7880
|
description: `Execute a shell command and return its output. Use for running tests, build, git, and shell operations. Commands that are still running after a few seconds are automatically moved to the background and return a process id — manage them with process_list, process_log, process_kill. Set background=true to return a process id immediately for commands you know are long-running (dev servers, watchers).
|
|
7848
7881
|
|
|
7849
7882
|
Windows notes: the shell is cmd.exe — PowerShell cmdlets (Write-Host, Get-Content, Select-String, Out-File) and bash heredocs (cat << EOF) do NOT work there. Use the read_file/write_file tools instead of cat/echo redirection. Sequential commands: use && (a leading ; is auto-converted to &).`,
|
|
@@ -8012,6 +8045,7 @@ var init_process_list = __esm(() => {
|
|
|
8012
8045
|
init_i18n();
|
|
8013
8046
|
processListTool = {
|
|
8014
8047
|
name: "process_list",
|
|
8048
|
+
icon: "\uD83D\uDCCA",
|
|
8015
8049
|
description: "List background processes started via the bash tool (dev servers, watchers, long-running commands). Shows id, pid, command, status, and recent output. Use with process_log and process_kill to inspect or stop them.",
|
|
8016
8050
|
tags: ["shell"],
|
|
8017
8051
|
parameters: {
|
|
@@ -8056,6 +8090,7 @@ var init_process_log = __esm(() => {
|
|
|
8056
8090
|
DEFAULT_TAIL = MAX_PREVIEW_LINES;
|
|
8057
8091
|
processLogTool = {
|
|
8058
8092
|
name: "process_log",
|
|
8093
|
+
icon: "\uD83D\uDCDC",
|
|
8059
8094
|
description: `Show the buffered output of a background process started via bash. Shows the last ${DEFAULT_TAIL} lines by default. Use after starting a dev server to verify it came up without errors, and while it runs to check its state.`,
|
|
8060
8095
|
tags: ["shell"],
|
|
8061
8096
|
boundedOutput: true,
|
|
@@ -8101,6 +8136,7 @@ var init_process_kill = __esm(() => {
|
|
|
8101
8136
|
init_i18n();
|
|
8102
8137
|
processKillTool = {
|
|
8103
8138
|
name: "process_kill",
|
|
8139
|
+
icon: "⛔",
|
|
8104
8140
|
description: "Stop a background process started via bash (dev server, watcher). Kills the whole process tree (children included). Use the id returned by bash or process_list.",
|
|
8105
8141
|
tags: ["shell"],
|
|
8106
8142
|
parameters: {
|
|
@@ -11279,6 +11315,145 @@ var init_agent_moe = __esm(() => {
|
|
|
11279
11315
|
init_verifier();
|
|
11280
11316
|
});
|
|
11281
11317
|
|
|
11318
|
+
// src/modules/pricing/prices.ts
|
|
11319
|
+
function normalizeModelId(model) {
|
|
11320
|
+
let id = model.trim();
|
|
11321
|
+
for (const prefix of PROVIDER_PREFIXES) {
|
|
11322
|
+
if (id.startsWith(prefix)) {
|
|
11323
|
+
id = id.slice(prefix.length);
|
|
11324
|
+
break;
|
|
11325
|
+
}
|
|
11326
|
+
}
|
|
11327
|
+
const parts = id.split("/");
|
|
11328
|
+
return parts[parts.length - 1];
|
|
11329
|
+
}
|
|
11330
|
+
function resolvePrice(model, config) {
|
|
11331
|
+
if (!config?.enabled)
|
|
11332
|
+
return;
|
|
11333
|
+
const bare = normalizeModelId(model);
|
|
11334
|
+
const overrides = config.overrides ?? {};
|
|
11335
|
+
const direct = overrides[model] ?? overrides[bare];
|
|
11336
|
+
if (direct)
|
|
11337
|
+
return direct;
|
|
11338
|
+
return ZEN_PRICES[bare];
|
|
11339
|
+
}
|
|
11340
|
+
function calculateCost(model, promptTokens, completionTokens, config) {
|
|
11341
|
+
const price = resolvePrice(model, config);
|
|
11342
|
+
if (!price)
|
|
11343
|
+
return;
|
|
11344
|
+
return promptTokens / 1e6 * price.input + completionTokens / 1e6 * price.output;
|
|
11345
|
+
}
|
|
11346
|
+
function formatCost(cost) {
|
|
11347
|
+
if (cost === 0)
|
|
11348
|
+
return "$0.00";
|
|
11349
|
+
if (cost >= 0.01)
|
|
11350
|
+
return `$${cost.toFixed(2)}`;
|
|
11351
|
+
if (cost >= 0.0001)
|
|
11352
|
+
return `$${cost.toFixed(4)}`;
|
|
11353
|
+
return `$${cost.toFixed(6)}`;
|
|
11354
|
+
}
|
|
11355
|
+
var ZEN_PRICES, PROVIDER_PREFIXES;
|
|
11356
|
+
var init_prices = __esm(() => {
|
|
11357
|
+
ZEN_PRICES = {
|
|
11358
|
+
"big-pickle": { input: 0, output: 0 },
|
|
11359
|
+
"mimo-v2.5-free": { input: 0, output: 0 },
|
|
11360
|
+
"hy3-free": { input: 0, output: 0 },
|
|
11361
|
+
"nemotron-3-ultra-free": { input: 0, output: 0 },
|
|
11362
|
+
"nemotron-3.5-lightning-free": { input: 0, output: 0 },
|
|
11363
|
+
"muse-spark-1.2-contributor-free": { input: 0, output: 0 },
|
|
11364
|
+
"minimax-m3": { input: 0.3, output: 1.2 },
|
|
11365
|
+
"minimax-m2.7": { input: 0.3, output: 1.2 },
|
|
11366
|
+
"minimax-m2.5": { input: 0.3, output: 1.2 },
|
|
11367
|
+
"glm-5.2": { input: 1.4, output: 4.4 },
|
|
11368
|
+
"glm-5.1": { input: 1.4, output: 4.4 },
|
|
11369
|
+
"glm-5": { input: 1, output: 3.2 },
|
|
11370
|
+
"glm-5.3": { input: 1.4, output: 4.4 },
|
|
11371
|
+
"kimi-k2.7-code": { input: 0.95, output: 4 },
|
|
11372
|
+
"kimi-k3": { input: 3, output: 15 },
|
|
11373
|
+
"kimi-k2.6": { input: 0.95, output: 4 },
|
|
11374
|
+
"kimi-k2.5": { input: 0.6, output: 3 },
|
|
11375
|
+
"qwen3.7-max": { input: 2.5, output: 7.5 },
|
|
11376
|
+
"qwen3.7-plus": { input: 0.4, output: 1.6 },
|
|
11377
|
+
"qwen3.6-plus": { input: 0.5, output: 3 },
|
|
11378
|
+
"qwen3.5-plus": { input: 0.2, output: 1.2 },
|
|
11379
|
+
"qwen3.8-max": { input: 2.5, output: 7.5 },
|
|
11380
|
+
"deepseek-v4-pro": { input: 0.66, output: 1.98 },
|
|
11381
|
+
"deepseek-v4-flash": { input: 0.22, output: 0.66 },
|
|
11382
|
+
"claude-fable-5": { input: 10, output: 50 },
|
|
11383
|
+
"claude-opus-5": { input: 5, output: 25 },
|
|
11384
|
+
"claude-opus-4-8": { input: 5, output: 25 },
|
|
11385
|
+
"claude-opus-4-7": { input: 5, output: 25 },
|
|
11386
|
+
"claude-opus-4-6": { input: 5, output: 25 },
|
|
11387
|
+
"claude-opus-4-5": { input: 5, output: 25 },
|
|
11388
|
+
"claude-sonnet-5": { input: 2, output: 10 },
|
|
11389
|
+
"claude-sonnet-4-6": { input: 3, output: 15 },
|
|
11390
|
+
"claude-sonnet-4-5": { input: 3, output: 15 },
|
|
11391
|
+
"claude-haiku-4-5": { input: 1, output: 5 },
|
|
11392
|
+
"gemini-3.7-flash": { input: 1.5, output: 7.5 },
|
|
11393
|
+
"gemini-3.6-flash": { input: 1.5, output: 7.5 },
|
|
11394
|
+
"gemini-3.5-flash": { input: 1.5, output: 9 },
|
|
11395
|
+
"gemini-3.5-flash-lite": { input: 0.3, output: 2.5 },
|
|
11396
|
+
"gemini-3.1-pro": { input: 2, output: 12 },
|
|
11397
|
+
"gemini-3-flash": { input: 0.5, output: 3 },
|
|
11398
|
+
"grok-4.6": { input: 2, output: 6 },
|
|
11399
|
+
"grok-4.5": { input: 2, output: 6 },
|
|
11400
|
+
"grok-build-0.1": { input: 1, output: 2 },
|
|
11401
|
+
"muse-spark-1.2": { input: 1.25, output: 4.25 },
|
|
11402
|
+
"gpt-5.6-sol": { input: 5, output: 30 },
|
|
11403
|
+
"gpt-5.6-terra": { input: 2, output: 12 },
|
|
11404
|
+
"gpt-5.6-luna": { input: 0.2, output: 1.2 },
|
|
11405
|
+
"gpt-5.5": { input: 5, output: 30 },
|
|
11406
|
+
"gpt-5.5-pro": { input: 30, output: 180 },
|
|
11407
|
+
"gpt-5.4": { input: 2.5, output: 15 },
|
|
11408
|
+
"gpt-5.4-pro": { input: 30, output: 180 },
|
|
11409
|
+
"gpt-5.4-mini": { input: 0.75, output: 4.5 },
|
|
11410
|
+
"gpt-5.4-nano": { input: 0.2, output: 1.25 },
|
|
11411
|
+
"gpt-5.3-codex": { input: 1.75, output: 14 },
|
|
11412
|
+
"gpt-5.3-codex-spark": { input: 1.75, output: 14 },
|
|
11413
|
+
"gpt-5.2": { input: 1.75, output: 14 },
|
|
11414
|
+
"gpt-5.2-codex": { input: 1.75, output: 14 },
|
|
11415
|
+
"gpt-5.1": { input: 1.07, output: 8.5 },
|
|
11416
|
+
"gpt-5.1-codex": { input: 1.07, output: 8.5 },
|
|
11417
|
+
"gpt-5.1-codex-max": { input: 1.25, output: 10 },
|
|
11418
|
+
"gpt-5.1-codex-mini": { input: 0.25, output: 2 },
|
|
11419
|
+
"gpt-5": { input: 1.07, output: 8.5 },
|
|
11420
|
+
"gpt-5-codex": { input: 1.07, output: 8.5 },
|
|
11421
|
+
"gpt-5-nano": { input: 0.05, output: 0.4 }
|
|
11422
|
+
};
|
|
11423
|
+
PROVIDER_PREFIXES = ["opencode-go/", "opencode/", "openai/", "anthropic/"];
|
|
11424
|
+
});
|
|
11425
|
+
|
|
11426
|
+
// src/modules/pricing/index.ts
|
|
11427
|
+
class CostTracker {
|
|
11428
|
+
config;
|
|
11429
|
+
model;
|
|
11430
|
+
_total = 0;
|
|
11431
|
+
_known = false;
|
|
11432
|
+
constructor(model, config) {
|
|
11433
|
+
this.model = model;
|
|
11434
|
+
this.config = config;
|
|
11435
|
+
}
|
|
11436
|
+
setModel(model) {
|
|
11437
|
+
this.model = model;
|
|
11438
|
+
}
|
|
11439
|
+
record(promptTokens, completionTokens) {
|
|
11440
|
+
const cost = calculateCost(this.model, promptTokens, completionTokens, this.config);
|
|
11441
|
+
if (cost === undefined)
|
|
11442
|
+
return;
|
|
11443
|
+
this._known = true;
|
|
11444
|
+
this._total += cost;
|
|
11445
|
+
}
|
|
11446
|
+
get total() {
|
|
11447
|
+
return this._known ? this._total : undefined;
|
|
11448
|
+
}
|
|
11449
|
+
get formatted() {
|
|
11450
|
+
return this._known ? formatCost(this._total) : undefined;
|
|
11451
|
+
}
|
|
11452
|
+
}
|
|
11453
|
+
var init_pricing = __esm(() => {
|
|
11454
|
+
init_prices();
|
|
11455
|
+
});
|
|
11456
|
+
|
|
11282
11457
|
// src/core/agent.ts
|
|
11283
11458
|
function isToolCallJson(text) {
|
|
11284
11459
|
const trimmed = text.trim();
|
|
@@ -11305,8 +11480,10 @@ class Agent {
|
|
|
11305
11480
|
shutdownRequested = false;
|
|
11306
11481
|
abortController = null;
|
|
11307
11482
|
lastCompactionShown = 0;
|
|
11483
|
+
costTracker;
|
|
11308
11484
|
constructor(deps) {
|
|
11309
11485
|
this.deps = deps;
|
|
11486
|
+
this.costTracker = new CostTracker(deps.config.model, deps.config.pricing);
|
|
11310
11487
|
}
|
|
11311
11488
|
get contextManager() {
|
|
11312
11489
|
return this.deps.contextManager;
|
|
@@ -11536,6 +11713,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
11536
11713
|
if (result) {
|
|
11537
11714
|
logger.debug("Context compacted");
|
|
11538
11715
|
slog.logCompaction({ reason: "interval", iteration, ...result });
|
|
11716
|
+
hallucinationDetector.addKnownFiles(contextManager.getKnownFiles());
|
|
11539
11717
|
}
|
|
11540
11718
|
}
|
|
11541
11719
|
const currentTokens = contextManager.getEstimatedTokens();
|
|
@@ -11551,6 +11729,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
11551
11729
|
iteration,
|
|
11552
11730
|
...result
|
|
11553
11731
|
});
|
|
11732
|
+
hallucinationDetector.addKnownFiles(contextManager.getKnownFiles());
|
|
11554
11733
|
}
|
|
11555
11734
|
}
|
|
11556
11735
|
if (currentTokens > budget2.history) {
|
|
@@ -11562,6 +11741,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
11562
11741
|
iteration,
|
|
11563
11742
|
...result
|
|
11564
11743
|
});
|
|
11744
|
+
hallucinationDetector.addKnownFiles(contextManager.getKnownFiles());
|
|
11565
11745
|
}
|
|
11566
11746
|
}
|
|
11567
11747
|
this.refreshSystemPrompt();
|
|
@@ -11659,6 +11839,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
11659
11839
|
source,
|
|
11660
11840
|
durationMs: Date.now() - llmStart
|
|
11661
11841
|
});
|
|
11842
|
+
this.costTracker.record(prompt, completion);
|
|
11662
11843
|
}
|
|
11663
11844
|
if (this.shutdownRequested) {
|
|
11664
11845
|
break;
|
|
@@ -11713,6 +11894,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
11713
11894
|
});
|
|
11714
11895
|
const summaries = [];
|
|
11715
11896
|
let anyToolFailed = false;
|
|
11897
|
+
const infoTools = new Set(["file_info"]);
|
|
11716
11898
|
for (const call of toolCalls) {
|
|
11717
11899
|
this.setScope();
|
|
11718
11900
|
const startTime = Date.now();
|
|
@@ -11721,14 +11903,15 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
11721
11903
|
args: call.arguments
|
|
11722
11904
|
});
|
|
11723
11905
|
pluginManager.runOnToolStart({ iteration, logger, contextManager }, { id: call.id, name: call.name, arguments: call.arguments });
|
|
11724
|
-
|
|
11906
|
+
const toolIcon = this.deps.toolExecutor.getRegistry().get(call.name)?.icon;
|
|
11907
|
+
onTool?.({ type: "start", tool: call.name, args: call.arguments, icon: toolIcon });
|
|
11725
11908
|
slog.logToolCall(call, iteration);
|
|
11726
11909
|
const tokensBeforeTool = contextManager.getEstimatedTokens();
|
|
11727
11910
|
const result = await toolExecutor.execute(call, this.abortController?.signal);
|
|
11728
11911
|
if (this.shutdownRequested)
|
|
11729
11912
|
break;
|
|
11730
11913
|
const duration = Date.now() - startTime;
|
|
11731
|
-
if (!result.success)
|
|
11914
|
+
if (!result.success && !infoTools.has(call.name))
|
|
11732
11915
|
anyToolFailed = true;
|
|
11733
11916
|
if (result.success && call.arguments.path) {
|
|
11734
11917
|
const filePath = String(call.arguments.path);
|
|
@@ -11772,7 +11955,8 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
11772
11955
|
args: call.arguments,
|
|
11773
11956
|
duration,
|
|
11774
11957
|
error: !result.success,
|
|
11775
|
-
ctxDelta: tokensAfterTool - tokensBeforeTool
|
|
11958
|
+
ctxDelta: tokensAfterTool - tokensBeforeTool,
|
|
11959
|
+
costUsd: this.costTracker.total
|
|
11776
11960
|
});
|
|
11777
11961
|
summaries.push(`[Tool: ${call.name} (${JSON.stringify(call.arguments)}) → ${truncatedOutput.slice(0, 200)}]`);
|
|
11778
11962
|
if (config.session.autoSave) {
|
|
@@ -11787,9 +11971,10 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
11787
11971
|
iteration,
|
|
11788
11972
|
...result2
|
|
11789
11973
|
});
|
|
11974
|
+
hallucinationDetector.addKnownFiles(contextManager.getKnownFiles());
|
|
11790
11975
|
}
|
|
11791
11976
|
}
|
|
11792
|
-
if (!result.success) {
|
|
11977
|
+
if (!result.success && !infoTools.has(call.name)) {
|
|
11793
11978
|
const key = call.name;
|
|
11794
11979
|
const prev = toolFailureCounts.get(key) ?? { count: 0, error: "" };
|
|
11795
11980
|
prev.count++;
|
|
@@ -12006,6 +12191,7 @@ ${warnLine}
|
|
|
12006
12191
|
promptTokens: usageTokens.prompt,
|
|
12007
12192
|
completionTokens: usageTokens.completion,
|
|
12008
12193
|
totalTokens: usageTokens.total,
|
|
12194
|
+
totalCost: this.costTracker.total,
|
|
12009
12195
|
compactionCount: contextManager.getCompactionCount(),
|
|
12010
12196
|
contextQuality: contextManager.getQuality()
|
|
12011
12197
|
};
|
|
@@ -12020,6 +12206,7 @@ ${warnLine}
|
|
|
12020
12206
|
promptTokens: usageTokens.prompt,
|
|
12021
12207
|
completionTokens: usageTokens.completion,
|
|
12022
12208
|
totalTokens: usageTokens.total,
|
|
12209
|
+
totalCost: this.costTracker.total,
|
|
12023
12210
|
compactionCount: contextManager.getCompactionCount(),
|
|
12024
12211
|
contextQuality: contextManager.getQuality()
|
|
12025
12212
|
};
|
|
@@ -12045,6 +12232,7 @@ ${warnLine}
|
|
|
12045
12232
|
const newTokenCounter = new TokenCounter2(config.model);
|
|
12046
12233
|
this.deps.contextManager.resize(config.contextWindow, config.contextBudget, newTokenCounter);
|
|
12047
12234
|
this.deps.config = config;
|
|
12235
|
+
this.costTracker.setModel(config.model);
|
|
12048
12236
|
}
|
|
12049
12237
|
setContext(messages) {
|
|
12050
12238
|
const { contextManager } = this.deps;
|
|
@@ -12088,6 +12276,7 @@ var init_agent = __esm(() => {
|
|
|
12088
12276
|
init_session_logger();
|
|
12089
12277
|
init_agent_moe();
|
|
12090
12278
|
init_verifier();
|
|
12279
|
+
init_pricing();
|
|
12091
12280
|
});
|
|
12092
12281
|
|
|
12093
12282
|
// src/modules/context/fact-extractor.ts
|
|
@@ -12184,6 +12373,10 @@ class FactExtractor {
|
|
|
12184
12373
|
return null;
|
|
12185
12374
|
return `[Files: ${liveFiles.slice(-15).join("; ")}]`;
|
|
12186
12375
|
}
|
|
12376
|
+
getKnownFiles() {
|
|
12377
|
+
const deletedSet = new Set(this.deletedFacts);
|
|
12378
|
+
return this.fileFacts.filter((p) => !deletedSet.has(p));
|
|
12379
|
+
}
|
|
12187
12380
|
deletedLine() {
|
|
12188
12381
|
if (this.deletedFacts.length === 0)
|
|
12189
12382
|
return null;
|
|
@@ -12308,6 +12501,9 @@ class ContextManager {
|
|
|
12308
12501
|
getIterationsSinceCompaction() {
|
|
12309
12502
|
return this.iterationsSinceCompaction;
|
|
12310
12503
|
}
|
|
12504
|
+
getKnownFiles() {
|
|
12505
|
+
return this.facts.getKnownFiles();
|
|
12506
|
+
}
|
|
12311
12507
|
noteIteration() {
|
|
12312
12508
|
this.iterationsSinceCompaction++;
|
|
12313
12509
|
}
|
|
@@ -12647,9 +12843,14 @@ class FactualCheck {
|
|
|
12647
12843
|
static NAME_CACHE_TTL_MS = 5000;
|
|
12648
12844
|
static RESCAN_COOLDOWN_MS = 2000;
|
|
12649
12845
|
static MAX_INDEXED_FILES = 20000;
|
|
12846
|
+
knownFiles = new Set;
|
|
12650
12847
|
constructor(baseDir) {
|
|
12651
12848
|
this.baseDir = baseDir;
|
|
12652
12849
|
}
|
|
12850
|
+
addKnownFiles(files) {
|
|
12851
|
+
for (const f of files)
|
|
12852
|
+
this.knownFiles.add(f);
|
|
12853
|
+
}
|
|
12653
12854
|
validate(response) {
|
|
12654
12855
|
const filePaths = this.extractFilePaths(response);
|
|
12655
12856
|
if (filePaths.length === 0)
|
|
@@ -12673,6 +12874,8 @@ class FactualCheck {
|
|
|
12673
12874
|
pathExists(fp) {
|
|
12674
12875
|
if (isAbsolute2(fp))
|
|
12675
12876
|
return existsSync23(fp);
|
|
12877
|
+
if (this.knownFiles.has(fp))
|
|
12878
|
+
return true;
|
|
12676
12879
|
if (!fp.includes("/") && !fp.includes("\\")) {
|
|
12677
12880
|
return this.bareNameExists(fp);
|
|
12678
12881
|
}
|
|
@@ -12683,6 +12886,11 @@ class FactualCheck {
|
|
|
12683
12886
|
return true;
|
|
12684
12887
|
if (this.indexHas(name))
|
|
12685
12888
|
return true;
|
|
12889
|
+
for (const known of this.knownFiles) {
|
|
12890
|
+
if (known.endsWith(`/${name}`) || known.endsWith(`\\${name}`) || known === name) {
|
|
12891
|
+
return true;
|
|
12892
|
+
}
|
|
12893
|
+
}
|
|
12686
12894
|
const now = Date.now();
|
|
12687
12895
|
if (now - this.lastRescan < FactualCheck.RESCAN_COOLDOWN_MS)
|
|
12688
12896
|
return false;
|
|
@@ -12862,6 +13070,9 @@ class HallucinationDetector {
|
|
|
12862
13070
|
getConfidenceCheck() {
|
|
12863
13071
|
return this.confidence;
|
|
12864
13072
|
}
|
|
13073
|
+
addKnownFiles(files) {
|
|
13074
|
+
this.factual?.addKnownFiles(files);
|
|
13075
|
+
}
|
|
12865
13076
|
async validate(response) {
|
|
12866
13077
|
const confidenceResult = this.confidence.validate(response);
|
|
12867
13078
|
if (confidenceResult.status === "retry" || confidenceResult.status === "block") {
|
|
@@ -13208,6 +13419,7 @@ var init_subagent = __esm(() => {
|
|
|
13208
13419
|
init_store();
|
|
13209
13420
|
subagentTool = {
|
|
13210
13421
|
name: "subagent",
|
|
13422
|
+
icon: "\uD83E\uDD16",
|
|
13211
13423
|
description: "Spawn an isolated sub-agent to work on a task independently. The sub-agent has its own context and executes autonomously. Use for parallel work or complex sub-tasks.",
|
|
13212
13424
|
tags: ["code"],
|
|
13213
13425
|
parameters: {
|
|
@@ -13506,6 +13718,7 @@ var init_chunk_query = __esm(() => {
|
|
|
13506
13718
|
init_scope_check();
|
|
13507
13719
|
chunkQueryTool = {
|
|
13508
13720
|
name: "chunk_query",
|
|
13721
|
+
icon: "\uD83E\uDDE9",
|
|
13509
13722
|
description: "Answer a query over a large text (file or inline) by splitting it into chunks and querying the model per chunk in parallel, then optionally synthesizing a final answer. Use when the input is too large for the context window.",
|
|
13510
13723
|
tags: ["research", "code"],
|
|
13511
13724
|
timeoutMs: 300000,
|
|
@@ -13705,6 +13918,7 @@ var init_web_search = __esm(() => {
|
|
|
13705
13918
|
init_session_isolation();
|
|
13706
13919
|
webSearchTool = {
|
|
13707
13920
|
name: "web_search",
|
|
13921
|
+
icon: "\uD83C\uDF0D",
|
|
13708
13922
|
description: "Search the web for information. Returns search results with titles and snippets. Use this for search queries instead of opening search engines (Google/Yandex/Bing) in the browser — they block headless browsers.",
|
|
13709
13923
|
tags: ["research"],
|
|
13710
13924
|
parameters: {
|
|
@@ -13772,6 +13986,7 @@ var init_web_fetch = __esm(() => {
|
|
|
13772
13986
|
init_security();
|
|
13773
13987
|
webFetchTool = {
|
|
13774
13988
|
name: "web_fetch",
|
|
13989
|
+
icon: "⬇️",
|
|
13775
13990
|
description: 'Fetch a URL and convert its content to markdown. Use for reading documentation, APIs, web pages. This is a plain HTTP request without a browser engine — it does NOT run JavaScript, so JS-rendered single-page apps (weather sites, dashboards, modern SPAs) return empty or near-empty content; use the "browser" tool for those.',
|
|
13776
13991
|
tags: ["research"],
|
|
13777
13992
|
parameters: {
|
|
@@ -13858,6 +14073,7 @@ var init_web_browse = __esm(() => {
|
|
|
13858
14073
|
init_session_isolation();
|
|
13859
14074
|
webBrowseTool = {
|
|
13860
14075
|
name: "web_browse",
|
|
14076
|
+
icon: "\uD83C\uDF10",
|
|
13861
14077
|
description: `Fetch and read a web page. Returns the page content as plain text (max ${MAX_PREVIEW_LINES} lines / ${MAX_CHARS2} chars). This is a plain HTTP request — it does NOT execute JavaScript, so JS-rendered single-page apps (weather sites, dashboards, modern SPAs) return empty or near-empty content. For such pages use the "browser" tool instead.`,
|
|
13862
14078
|
tags: ["research"],
|
|
13863
14079
|
parameters: {
|
|
@@ -13942,6 +14158,7 @@ var init_download_file = __esm(() => {
|
|
|
13942
14158
|
MAX_DOWNLOAD_BYTES = 100 * 1024 * 1024;
|
|
13943
14159
|
downloadFileTool = {
|
|
13944
14160
|
name: "download_file",
|
|
14161
|
+
icon: "⬇️",
|
|
13945
14162
|
description: "Download a file (image, archive, binary, font, etc.) from a URL and save it to disk. Returns only the path, size and content type — read the saved file with read_file/attach_image afterwards. Use this for binary files; web_fetch/web_browse return text only and cannot save bytes.",
|
|
13946
14163
|
tags: ["file", "research"],
|
|
13947
14164
|
parameters: {
|
|
@@ -14045,6 +14262,7 @@ var init_download_file = __esm(() => {
|
|
|
14045
14262
|
function createLoadSkillTool(skillsModule) {
|
|
14046
14263
|
return {
|
|
14047
14264
|
name: "load_skill",
|
|
14265
|
+
icon: "\uD83C\uDFAF",
|
|
14048
14266
|
tags: ["core"],
|
|
14049
14267
|
description: "Load a skill by name. Skills provide specialized instructions and workflows. When loaded, the skill content is injected into the system prompt (not conversation history) so it persists through context compaction. Only use when the task clearly requires domain-specific knowledge.",
|
|
14050
14268
|
parameters: {
|
|
@@ -14276,6 +14494,7 @@ var init_pipeline_run = __esm(() => {
|
|
|
14276
14494
|
engine = new PipelineEngine;
|
|
14277
14495
|
pipelineRunTool = {
|
|
14278
14496
|
name: "pipeline_run",
|
|
14497
|
+
icon: "▶️",
|
|
14279
14498
|
description: "Run a named pipeline with YAML definition. Creates a DAG of sub-agents that execute in dependency order.",
|
|
14280
14499
|
tags: ["shell", "code"],
|
|
14281
14500
|
parameters: {
|
|
@@ -14807,6 +15026,7 @@ var init_mcp_call = __esm(() => {
|
|
|
14807
15026
|
registry = new MCPRegistry;
|
|
14808
15027
|
mcpCallTool = {
|
|
14809
15028
|
name: "mcp_call",
|
|
15029
|
+
icon: "\uD83D\uDD17",
|
|
14810
15030
|
description: "Call a tool on an MCP (Model Context Protocol) server. MCP servers provide external capabilities like databases, APIs, or specialized tools.",
|
|
14811
15031
|
tags: ["code", "research"],
|
|
14812
15032
|
parameters: {
|
|
@@ -14876,6 +15096,7 @@ var init_search_history = __esm(() => {
|
|
|
14876
15096
|
init_i18n();
|
|
14877
15097
|
searchHistoryTool = {
|
|
14878
15098
|
name: "search_history",
|
|
15099
|
+
icon: "\uD83D\uDD75️",
|
|
14879
15100
|
description: "Search through session history for past interactions across all sessions.",
|
|
14880
15101
|
tags: ["research"],
|
|
14881
15102
|
parameters: {
|
|
@@ -15072,6 +15293,7 @@ var init_remember = __esm(() => {
|
|
|
15072
15293
|
CATEGORIES = ["preferences", "conventions", "decisions", "errors", "facts"];
|
|
15073
15294
|
rememberTool = {
|
|
15074
15295
|
name: "remember",
|
|
15296
|
+
icon: "\uD83E\uDDE0",
|
|
15075
15297
|
description: "Remember information across sessions. Use for user preferences, facts, conventions, decisions, or errors.",
|
|
15076
15298
|
tags: ["memory"],
|
|
15077
15299
|
parameters: {
|
|
@@ -15199,6 +15421,7 @@ var init_recall = __esm(() => {
|
|
|
15199
15421
|
CATEGORIES2 = ["preferences", "conventions", "decisions", "errors", "facts"];
|
|
15200
15422
|
recallTool = {
|
|
15201
15423
|
name: "recall",
|
|
15424
|
+
icon: "\uD83D\uDCBE",
|
|
15202
15425
|
description: "Recall stored information from memory. Search across preferences, facts, conventions, decisions, errors.",
|
|
15203
15426
|
tags: ["memory"],
|
|
15204
15427
|
parameters: {
|
|
@@ -16228,6 +16451,7 @@ function formatScreenshotResult(snapshot, screenshot, supportsVision) {
|
|
|
16228
16451
|
function createBrowserTool() {
|
|
16229
16452
|
return {
|
|
16230
16453
|
name: "browser",
|
|
16454
|
+
icon: "\uD83C\uDF10",
|
|
16231
16455
|
tags: ["browser", "vision"],
|
|
16232
16456
|
description: [
|
|
16233
16457
|
"Control a headless browser. Navigate pages, click elements, type text, scroll, take screenshots.",
|
|
@@ -16432,6 +16656,7 @@ var init_attach_image = __esm(() => {
|
|
|
16432
16656
|
init_audit_log();
|
|
16433
16657
|
attachImageTool = {
|
|
16434
16658
|
name: "attach_image",
|
|
16659
|
+
icon: "\uD83D\uDDBC️",
|
|
16435
16660
|
description: "Attach an image to the conversation from a file path, URL, or clipboard. The image will be included in the next message sent to the model. Supports PNG, JPEG, GIF, WebP.",
|
|
16436
16661
|
tags: ["vision", "image"],
|
|
16437
16662
|
parameters: {
|
|
@@ -16517,6 +16742,7 @@ var init_enable_tools = __esm(() => {
|
|
|
16517
16742
|
init_i18n();
|
|
16518
16743
|
enableToolsTool = {
|
|
16519
16744
|
name: "enable_tools",
|
|
16745
|
+
icon: "\uD83D\uDD0C",
|
|
16520
16746
|
description: "Enable hidden tool categories for the current session. Only the essential tools (file/code/shell) are active by default. Call this with the tags you need and they become available from the next turn. Available tags: file, code, shell, research, browser, vision, image, memory, core. Returns the newly available tools. To run a task in a separate context instead, use subagent with tool_tags.",
|
|
16521
16747
|
alwaysOn: true,
|
|
16522
16748
|
parameters: {
|
|
@@ -17741,6 +17967,7 @@ function createPlanToolDefinitions(deps) {
|
|
|
17741
17967
|
return [
|
|
17742
17968
|
{
|
|
17743
17969
|
name: "plan",
|
|
17970
|
+
icon: "\uD83D\uDCCB",
|
|
17744
17971
|
alwaysOn: true,
|
|
17745
17972
|
description: `Create, update, show, abort, list, switch, delete, purge, or re-plan multi-step plans.
|
|
17746
17973
|
|
|
@@ -18017,6 +18244,20 @@ ${progress2}`,
|
|
|
18017
18244
|
};
|
|
18018
18245
|
}
|
|
18019
18246
|
}
|
|
18247
|
+
if (status === "done" && target.kind !== "delete") {
|
|
18248
|
+
const missing = deps.missingStepDeliverables(target);
|
|
18249
|
+
if (missing.length > 0) {
|
|
18250
|
+
const existing = deps.stillExistingDeliverables(target);
|
|
18251
|
+
const allGone = deps.hasStepDeliverables(target) && existing.length === 0;
|
|
18252
|
+
if (allGone) {
|
|
18253
|
+
const wasDeleted = deps.wasFileDeleted ? missing.every((f) => deps.wasFileDeleted(f)) : false;
|
|
18254
|
+
if (wasDeleted) {
|
|
18255
|
+
target.kind = "delete";
|
|
18256
|
+
deps.store.saveActive(tracker.getPlan());
|
|
18257
|
+
}
|
|
18258
|
+
}
|
|
18259
|
+
}
|
|
18260
|
+
}
|
|
18020
18261
|
if (status === "done") {
|
|
18021
18262
|
if (target.kind === "delete") {
|
|
18022
18263
|
const leftovers = deps.stillExistingDeliverables(target);
|
|
@@ -18186,6 +18427,7 @@ ${progress}${vacuousNote}`,
|
|
|
18186
18427
|
},
|
|
18187
18428
|
{
|
|
18188
18429
|
name: "todo",
|
|
18430
|
+
icon: "☑️",
|
|
18189
18431
|
alwaysOn: true,
|
|
18190
18432
|
description: "Manage sub-tasks within current plan step. Use to break down complex steps into smaller tasks.",
|
|
18191
18433
|
parameters: {
|
|
@@ -18282,6 +18524,7 @@ ${lines.join(`
|
|
|
18282
18524
|
},
|
|
18283
18525
|
{
|
|
18284
18526
|
name: "verify",
|
|
18527
|
+
icon: "✅",
|
|
18285
18528
|
alwaysOn: true,
|
|
18286
18529
|
description: "Run verification for the current step. Checks files mentioned in the step description.",
|
|
18287
18530
|
parameters: {
|
|
@@ -18342,6 +18585,7 @@ class ExecutionModule {
|
|
|
18342
18585
|
retryWebSearchSignatures = new Set;
|
|
18343
18586
|
lastErrorSearchAt = 0;
|
|
18344
18587
|
errorSearchCooldownMs;
|
|
18588
|
+
hallucinationDetector = null;
|
|
18345
18589
|
state = {
|
|
18346
18590
|
lastRecoveryIteration: -STUCK_RECOVERY_COOLDOWN,
|
|
18347
18591
|
consecutivePlanWarnings: 0,
|
|
@@ -18380,6 +18624,9 @@ class ExecutionModule {
|
|
|
18380
18624
|
this.completedPlan = null;
|
|
18381
18625
|
this._auditSkipsRemaining = 0;
|
|
18382
18626
|
}
|
|
18627
|
+
setHallucinationDetector(detector) {
|
|
18628
|
+
this.hallucinationDetector = detector;
|
|
18629
|
+
}
|
|
18383
18630
|
recordCompleted(plan) {
|
|
18384
18631
|
this.completedPlan = plan;
|
|
18385
18632
|
}
|
|
@@ -18534,7 +18781,8 @@ class ExecutionModule {
|
|
|
18534
18781
|
parseKinds: (a, st) => this.parseKinds(a, st),
|
|
18535
18782
|
getTaskText: (c) => this.getTaskText(c),
|
|
18536
18783
|
typecheckFailures: this.state.typecheckFailures,
|
|
18537
|
-
baseDir: this.baseDir
|
|
18784
|
+
baseDir: this.baseDir,
|
|
18785
|
+
wasFileDeleted: this.hallucinationDetector ? (path) => this.hallucinationDetector.getConsistencyCheck().getDeletedFiles().includes(path) : undefined
|
|
18538
18786
|
});
|
|
18539
18787
|
}
|
|
18540
18788
|
getPlugin() {
|
|
@@ -20067,6 +20315,7 @@ ${items}`;
|
|
|
20067
20315
|
return [
|
|
20068
20316
|
{
|
|
20069
20317
|
name: "lsp_check",
|
|
20318
|
+
icon: "\uD83E\uDE7A",
|
|
20070
20319
|
description: 'Run static checks (LSP diagnostics) on a file or directory. For "check for errors" tasks: pass a file to check it, or a directory to check its source files (capped at 15). Returns [LSP errors] / [LSP warnings] for files with a configured LSP server.',
|
|
20071
20320
|
tags: ["code", "check"],
|
|
20072
20321
|
alwaysOn: true,
|
|
@@ -20801,6 +21050,7 @@ ${t("indexer.and_more", { count: result.files.length - 100 })}` : "";
|
|
|
20801
21050
|
createProjectMapTool() {
|
|
20802
21051
|
return {
|
|
20803
21052
|
name: "project_map",
|
|
21053
|
+
icon: "\uD83D\uDDFA️",
|
|
20804
21054
|
alwaysOn: true,
|
|
20805
21055
|
description: t("indexer.project_map_desc"),
|
|
20806
21056
|
parameters: {
|
|
@@ -21327,6 +21577,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21327
21577
|
execModule.restorePlan();
|
|
21328
21578
|
}
|
|
21329
21579
|
moduleRegistry.register(execModule);
|
|
21580
|
+
execModule.setHallucinationDetector(hallucinationDetector);
|
|
21330
21581
|
const sessionModule = new SessionModule(sessionManager);
|
|
21331
21582
|
moduleRegistry.register(sessionModule);
|
|
21332
21583
|
moduleRegistry.register(indexerModule);
|
|
@@ -22182,10 +22433,8 @@ async function runSetup(externalRl) {
|
|
|
22182
22433
|
console.log(t("setup.no_servers"));
|
|
22183
22434
|
apiBase = await ask(rl, t("setup.api_base"), "http://localhost:1234/v1");
|
|
22184
22435
|
}
|
|
22185
|
-
} else
|
|
22186
|
-
apiBase = "
|
|
22187
|
-
} else if (provider === "anthropic") {
|
|
22188
|
-
apiBase = "https://api.anthropic.com";
|
|
22436
|
+
} else {
|
|
22437
|
+
apiBase = HOSTED_BASE_URLS[provider] ?? "";
|
|
22189
22438
|
}
|
|
22190
22439
|
const defaultKey = provider === "openai-compat" ? "not-needed" : "";
|
|
22191
22440
|
const apiKey = await ask(rl, t("setup.api_key"), defaultKey);
|
|
@@ -22250,7 +22499,7 @@ async function runSetup(externalRl) {
|
|
|
22250
22499
|
console.log(l);
|
|
22251
22500
|
return answers;
|
|
22252
22501
|
}
|
|
22253
|
-
var PROVIDER_TYPES, KNOWN_PORTS;
|
|
22502
|
+
var PROVIDER_TYPES, KNOWN_PORTS, HOSTED_BASE_URLS;
|
|
22254
22503
|
var init_setup = __esm(() => {
|
|
22255
22504
|
init_colors();
|
|
22256
22505
|
init_i18n();
|
|
@@ -22263,7 +22512,9 @@ var init_setup = __esm(() => {
|
|
|
22263
22512
|
label: "OpenAI-compatible (LM Studio, Ollama, vLLM, etc.)"
|
|
22264
22513
|
},
|
|
22265
22514
|
{ value: "openai", label: "OpenAI API" },
|
|
22266
|
-
{ value: "anthropic", label: "Anthropic Claude" }
|
|
22515
|
+
{ value: "anthropic", label: "Anthropic Claude" },
|
|
22516
|
+
{ value: "opencode-zen", label: "OpenCode Zen (opencode.ai/zen)" },
|
|
22517
|
+
{ value: "opencode-go", label: "OpenCode Go (opencode.ai/go)" }
|
|
22267
22518
|
];
|
|
22268
22519
|
KNOWN_PORTS = [
|
|
22269
22520
|
{ port: 1234, label: "LM Studio" },
|
|
@@ -22271,6 +22522,12 @@ var init_setup = __esm(() => {
|
|
|
22271
22522
|
{ port: 8080, label: "vLLM / custom" },
|
|
22272
22523
|
{ port: 4891, label: "GPT4All" }
|
|
22273
22524
|
];
|
|
22525
|
+
HOSTED_BASE_URLS = {
|
|
22526
|
+
openai: "https://api.openai.com/v1",
|
|
22527
|
+
anthropic: "https://api.anthropic.com",
|
|
22528
|
+
"opencode-zen": "https://opencode.ai/zen/v1",
|
|
22529
|
+
"opencode-go": "https://opencode.ai/zen/go/v1"
|
|
22530
|
+
};
|
|
22274
22531
|
});
|
|
22275
22532
|
|
|
22276
22533
|
// src/modules/certification/manifest.ts
|
|
@@ -31285,6 +31542,7 @@ function createPluginCommand(program2) {
|
|
|
31285
31542
|
}
|
|
31286
31543
|
|
|
31287
31544
|
// src/cli/commands.ts
|
|
31545
|
+
init_setup();
|
|
31288
31546
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
31289
31547
|
function readVersion2() {
|
|
31290
31548
|
const here = dirname16(fileURLToPath4(import.meta.url));
|
|
@@ -31470,8 +31728,15 @@ function createProgram() {
|
|
|
31470
31728
|
const configPath = join44(homedir15(), ".mma", "config.json");
|
|
31471
31729
|
const { config } = await bootstrap();
|
|
31472
31730
|
config.provider.type = name;
|
|
31731
|
+
const baseUrl = HOSTED_BASE_URLS[name];
|
|
31732
|
+
if (baseUrl) {
|
|
31733
|
+
config.provider.baseUrl = baseUrl;
|
|
31734
|
+
}
|
|
31473
31735
|
saveConfig(config, configPath);
|
|
31474
31736
|
console.log(t("cli.provider_set", { name }));
|
|
31737
|
+
if (baseUrl) {
|
|
31738
|
+
console.log(t("cli.provider_base_hint", { baseUrl }));
|
|
31739
|
+
}
|
|
31475
31740
|
});
|
|
31476
31741
|
const session2 = program2.command("session").description(t("cli.manage_sessions"));
|
|
31477
31742
|
session2.command("list").description(t("cli.list_sessions")).action(async () => {
|
|
@@ -32276,9 +32541,8 @@ class LineEditor {
|
|
|
32276
32541
|
|
|
32277
32542
|
// src/cli/repl.ts
|
|
32278
32543
|
import { existsSync as existsSync53, readFileSync as readFileSync35, writeFileSync as writeFileSync17 } from "fs";
|
|
32279
|
-
import { join as join47
|
|
32544
|
+
import { join as join47 } from "path";
|
|
32280
32545
|
import { homedir as homedir17 } from "os";
|
|
32281
|
-
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
32282
32546
|
|
|
32283
32547
|
// src/cli/completer.ts
|
|
32284
32548
|
class SlashCommandProvider {
|
|
@@ -32582,6 +32846,10 @@ init_spinner();
|
|
|
32582
32846
|
init_box();
|
|
32583
32847
|
init_table();
|
|
32584
32848
|
init_i18n();
|
|
32849
|
+
init_prices();
|
|
32850
|
+
function formatUsd(cost) {
|
|
32851
|
+
return formatCost(cost);
|
|
32852
|
+
}
|
|
32585
32853
|
var GUTTER = " ";
|
|
32586
32854
|
var BUSY_TOOLS = new Set(["lsp_check"]);
|
|
32587
32855
|
function toolMarker(tool) {
|
|
@@ -32686,20 +32954,20 @@ class Renderer {
|
|
|
32686
32954
|
thinkingEnd() {
|
|
32687
32955
|
this.spinner.stop();
|
|
32688
32956
|
}
|
|
32689
|
-
toolStart(tool, args, stepContext) {
|
|
32957
|
+
toolStart(tool, args, stepContext, icon) {
|
|
32690
32958
|
this.endCard();
|
|
32691
32959
|
this.spinner.stop();
|
|
32692
32960
|
const summary = summarizeArgs2(args);
|
|
32693
32961
|
const step = stepContext ? ` ${pc2.cyan(`← ${stepContext}`)}` : "";
|
|
32962
|
+
const marker = icon || toolMarker(tool);
|
|
32694
32963
|
if (!this.rich) {
|
|
32695
32964
|
this.out.write(`
|
|
32696
|
-
${pc2.dim(
|
|
32965
|
+
${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}${step}
|
|
32697
32966
|
`);
|
|
32698
32967
|
return;
|
|
32699
32968
|
}
|
|
32700
32969
|
this.card = { tool, args, body: [], start: Date.now() };
|
|
32701
32970
|
if (this.toolStyle === "inline") {
|
|
32702
|
-
const marker = toolMarker(tool);
|
|
32703
32971
|
this.out.write(`
|
|
32704
32972
|
${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}${step}
|
|
32705
32973
|
`);
|
|
@@ -32708,7 +32976,7 @@ ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
|
32708
32976
|
}
|
|
32709
32977
|
return;
|
|
32710
32978
|
}
|
|
32711
|
-
this.spinner.start(`${pc2.dim(
|
|
32979
|
+
this.spinner.start(`${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}${step}`);
|
|
32712
32980
|
}
|
|
32713
32981
|
planBlock(lines) {
|
|
32714
32982
|
this.endCard();
|
|
@@ -32718,14 +32986,20 @@ ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
|
32718
32986
|
`);
|
|
32719
32987
|
}
|
|
32720
32988
|
}
|
|
32721
|
-
toolEnd(_tool, duration, error, ctxDelta) {
|
|
32989
|
+
toolEnd(_tool, duration, error, ctxDelta, costUsd) {
|
|
32722
32990
|
this.spinner.stop();
|
|
32723
32991
|
if (!this.rich) {
|
|
32992
|
+
const parts = [];
|
|
32724
32993
|
if (ctxDelta !== undefined && ctxDelta !== 0) {
|
|
32725
32994
|
const deltaStr = ctxDelta > 0 ? pc2.green(`+${ctxDelta}`) : pc2.yellow(`${ctxDelta} ↓`);
|
|
32726
|
-
|
|
32727
|
-
`);
|
|
32995
|
+
parts.push(`${pc2.dim("ctx")} ${deltaStr}`);
|
|
32728
32996
|
}
|
|
32997
|
+
if (costUsd !== undefined && costUsd > 0) {
|
|
32998
|
+
parts.push(`${pc2.dim("cost")} ${pc2.yellow(formatUsd(costUsd))}`);
|
|
32999
|
+
}
|
|
33000
|
+
if (parts.length > 0)
|
|
33001
|
+
this.out.write(`${parts.join(" ")}
|
|
33002
|
+
`);
|
|
32729
33003
|
return;
|
|
32730
33004
|
}
|
|
32731
33005
|
if (!this.card)
|
|
@@ -32737,6 +33011,9 @@ ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
|
32737
33011
|
const deltaStr = ctxDelta > 0 ? pc2.green(`+${ctxDelta}`) : pc2.yellow(`${ctxDelta} ↓`);
|
|
32738
33012
|
footer += ` ${pc2.dim("ctx")} ${deltaStr}`;
|
|
32739
33013
|
}
|
|
33014
|
+
if (costUsd !== undefined && costUsd > 0) {
|
|
33015
|
+
footer += ` ${pc2.dim("cost")} ${pc2.yellow(formatUsd(costUsd))}`;
|
|
33016
|
+
}
|
|
32740
33017
|
if (this.toolStyle === "inline") {
|
|
32741
33018
|
this.out.write(`${GUTTER}${footer}
|
|
32742
33019
|
`);
|
|
@@ -32964,21 +33241,7 @@ function stepContextForTool(plan, tool, args) {
|
|
|
32964
33241
|
}
|
|
32965
33242
|
|
|
32966
33243
|
// src/cli/repl.ts
|
|
32967
|
-
|
|
32968
|
-
const here = dirname18(fileURLToPath6(import.meta.url));
|
|
32969
|
-
const candidates = [join47(here, "..", "..", "package.json"), join47(here, "..", "package.json")];
|
|
32970
|
-
for (const p of candidates) {
|
|
32971
|
-
if (existsSync53(p)) {
|
|
32972
|
-
try {
|
|
32973
|
-
const raw = JSON.parse(readFileSync35(p, "utf8"));
|
|
32974
|
-
if (raw.version)
|
|
32975
|
-
return raw.version;
|
|
32976
|
-
} catch {}
|
|
32977
|
-
}
|
|
32978
|
-
}
|
|
32979
|
-
return "0.0.0";
|
|
32980
|
-
}
|
|
32981
|
-
var version3 = readVersion4();
|
|
33244
|
+
init_prices();
|
|
32982
33245
|
function formatContextBar(used, limit, compactions, quality) {
|
|
32983
33246
|
const pct = Math.min(100, Math.round(used / limit * 100));
|
|
32984
33247
|
const barLen = 20;
|
|
@@ -33268,9 +33531,9 @@ ${t("image.clipboard_empty")}`));
|
|
|
33268
33531
|
this.refreshActivePlan(renderer);
|
|
33269
33532
|
const result = await this.agent.run(input, (c) => renderer.text(c), (m) => renderer.meta(m), (ev) => {
|
|
33270
33533
|
if (ev.type === "start") {
|
|
33271
|
-
renderer.toolStart(ev.tool, ev.args, stepContextForTool(this.activePlan, ev.tool, ev.args));
|
|
33534
|
+
renderer.toolStart(ev.tool, ev.args, stepContextForTool(this.activePlan, ev.tool, ev.args), ev.icon);
|
|
33272
33535
|
} else {
|
|
33273
|
-
renderer.toolEnd(ev.tool, ev.duration ?? 0, ev.error, ev.ctxDelta);
|
|
33536
|
+
renderer.toolEnd(ev.tool, ev.duration ?? 0, ev.error, ev.ctxDelta, ev.costUsd);
|
|
33274
33537
|
if (ev.tool === "plan" || ev.tool === "todo") {
|
|
33275
33538
|
this.refreshActivePlan(renderer);
|
|
33276
33539
|
}
|
|
@@ -33389,6 +33652,9 @@ ${t("image.clipboard_empty")}`));
|
|
|
33389
33652
|
const apiLine = pc2.dim(` API: ${result.promptTokens} prompt + ${result.completionTokens} completion = ${result.totalTokens} total`);
|
|
33390
33653
|
console.log(apiLine);
|
|
33391
33654
|
}
|
|
33655
|
+
if (result.totalCost !== undefined && result.totalCost > 0) {
|
|
33656
|
+
console.log(pc2.yellow(` ${t("repl.cost", { cost: formatCost(result.totalCost) })}`));
|
|
33657
|
+
}
|
|
33392
33658
|
} else if (ui?.showCompaction && result.compactionCount !== undefined) {
|
|
33393
33659
|
if (result.compactionCount > this.lastCompactionShown) {
|
|
33394
33660
|
this.lastCompactionShown = result.compactionCount;
|
|
@@ -33420,9 +33686,9 @@ ${t("image.clipboard_empty")}`));
|
|
|
33420
33686
|
const infos = this.pluginManager.getPluginInfos().filter(({ plugin: plugin3 }) => !plugin3.isBuiltin);
|
|
33421
33687
|
if (infos.length > 0) {
|
|
33422
33688
|
const pluginNames = infos.map(({ plugin: plugin3, source }) => {
|
|
33423
|
-
const
|
|
33689
|
+
const version3 = plugin3.version ? `${pc2.dim(plugin3.version)}` : "";
|
|
33424
33690
|
const origin = source ? pc2.dim(` [${source}]`) : "";
|
|
33425
|
-
return `${plugin3.name}${
|
|
33691
|
+
return `${plugin3.name}${version3}${origin}`;
|
|
33426
33692
|
}).join(", ");
|
|
33427
33693
|
row(t("repl.plugins_label"), `${pc2.white(String(infos.length))} active ${pc2.dim(`(${pluginNames})`)}`);
|
|
33428
33694
|
}
|
|
@@ -33463,33 +33729,27 @@ ${t("image.clipboard_empty")}`));
|
|
|
33463
33729
|
if (lspEnabled) {
|
|
33464
33730
|
row(t("repl.lsp_label"), pc2.dim("…"));
|
|
33465
33731
|
}
|
|
33466
|
-
const
|
|
33467
|
-
|
|
33468
|
-
width: headerWidth
|
|
33469
|
-
});
|
|
33470
|
-
for (const line of boxLines) {
|
|
33471
|
-
console.log(line);
|
|
33732
|
+
for (const line of info) {
|
|
33733
|
+
console.log(pc2.dim(line).trimEnd());
|
|
33472
33734
|
}
|
|
33473
33735
|
console.log();
|
|
33474
33736
|
this.rl.prompt();
|
|
33475
33737
|
if (lspEnabled) {
|
|
33476
33738
|
this.probeLspBanner().then((lspSummary) => {
|
|
33477
33739
|
if (lspSummary)
|
|
33478
|
-
this.updateLspRow(
|
|
33740
|
+
this.updateLspRow(headerWidth, lspSummary);
|
|
33479
33741
|
}).catch(() => {});
|
|
33480
33742
|
}
|
|
33481
33743
|
}
|
|
33482
|
-
updateLspRow(
|
|
33744
|
+
updateLspRow(headerWidth, summary) {
|
|
33483
33745
|
if (this.agentRunning || !process.stdout.isTTY)
|
|
33484
33746
|
return;
|
|
33485
33747
|
if ((process.stdout.columns ?? 96) < headerWidth)
|
|
33486
33748
|
return;
|
|
33487
|
-
const inner = headerWidth - 4;
|
|
33488
33749
|
const rowText = `${pc2.yellow(t("repl.lsp_label"))} ${summary.replace(/\s+/g, " ").trim()}`;
|
|
33489
|
-
if (stringWidth(rowText) >
|
|
33750
|
+
if (stringWidth(rowText) > headerWidth)
|
|
33490
33751
|
return;
|
|
33491
|
-
const
|
|
33492
|
-
const line = pc2.dim("│") + " " + padded + " " + pc2.dim("│");
|
|
33752
|
+
const line = pc2.dim(rowText);
|
|
33493
33753
|
process.stdout.write(`\x1B[2A\r\x1B[2K${line}\x1B[2B\r`);
|
|
33494
33754
|
}
|
|
33495
33755
|
async probeLspBanner() {
|
|
@@ -33522,9 +33782,15 @@ ${t("image.clipboard_empty")}`));
|
|
|
33522
33782
|
// src/cli/run-result.ts
|
|
33523
33783
|
init_i18n();
|
|
33524
33784
|
init_colors();
|
|
33785
|
+
init_prices();
|
|
33525
33786
|
function printRunResult(result, flush) {
|
|
33526
33787
|
flush();
|
|
33527
33788
|
if (result.success) {
|
|
33789
|
+
if (result.totalCost !== undefined && result.totalCost > 0) {
|
|
33790
|
+
console.log(pc2.dim(`${t("repl.cost", { cost: formatCost(result.totalCost) })}`));
|
|
33791
|
+
} else if (result.totalTokens !== undefined && result.totalTokens > 0) {
|
|
33792
|
+
console.log(pc2.dim(`${t("repl.tokens", { tokens: result.totalTokens })}`));
|
|
33793
|
+
}
|
|
33528
33794
|
if (!result.text) {
|
|
33529
33795
|
console.log(pc2.yellow(t("cli.no_output")));
|
|
33530
33796
|
}
|
|
@@ -33540,9 +33806,9 @@ init_config2();
|
|
|
33540
33806
|
init_i18n();
|
|
33541
33807
|
init_colors();
|
|
33542
33808
|
import { existsSync as existsSync54, readFileSync as readFileSync36 } from "fs";
|
|
33543
|
-
import { join as join48, dirname as
|
|
33809
|
+
import { join as join48, dirname as dirname18 } from "path";
|
|
33544
33810
|
import { homedir as homedir18 } from "os";
|
|
33545
|
-
import { fileURLToPath as
|
|
33811
|
+
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
33546
33812
|
|
|
33547
33813
|
// src/modules/updater/index.ts
|
|
33548
33814
|
init_checker();
|
|
@@ -33642,8 +33908,8 @@ class UpdaterModule {
|
|
|
33642
33908
|
}
|
|
33643
33909
|
}
|
|
33644
33910
|
// src/cli/main.ts
|
|
33645
|
-
function
|
|
33646
|
-
const here =
|
|
33911
|
+
function readVersion4() {
|
|
33912
|
+
const here = dirname18(fileURLToPath6(import.meta.url));
|
|
33647
33913
|
const candidates = [join48(here, "..", "..", "package.json"), join48(here, "..", "package.json")];
|
|
33648
33914
|
for (const p of candidates) {
|
|
33649
33915
|
if (existsSync54(p)) {
|
|
@@ -33658,7 +33924,7 @@ function readVersion5() {
|
|
|
33658
33924
|
}
|
|
33659
33925
|
function startAutoUpdate(config) {
|
|
33660
33926
|
try {
|
|
33661
|
-
const module = new UpdaterModule(config.updater,
|
|
33927
|
+
const module = new UpdaterModule(config.updater, readVersion4(), "micro-models-agent", {
|
|
33662
33928
|
info: (m) => process.stderr.write(pc2.dim(m) + `
|
|
33663
33929
|
`),
|
|
33664
33930
|
warn: (m) => process.stderr.write(pc2.yellow(m) + `
|
|
@@ -33701,7 +33967,8 @@ async function main() {
|
|
|
33701
33967
|
contextLimit: result2.contextLimit ?? null,
|
|
33702
33968
|
promptTokens: result2.promptTokens ?? null,
|
|
33703
33969
|
completionTokens: result2.completionTokens ?? null,
|
|
33704
|
-
totalTokens: result2.totalTokens ?? null
|
|
33970
|
+
totalTokens: result2.totalTokens ?? null,
|
|
33971
|
+
totalCost: result2.totalCost ?? null
|
|
33705
33972
|
}, null, 2));
|
|
33706
33973
|
process.stdout.write(`
|
|
33707
33974
|
`);
|
|
@@ -33714,9 +33981,9 @@ async function main() {
|
|
|
33714
33981
|
});
|
|
33715
33982
|
const result = await agent.run(prompt, (chunk) => renderer.text(chunk), (meta) => renderer.meta(meta), (ev) => {
|
|
33716
33983
|
if (ev.type === "start") {
|
|
33717
|
-
renderer.toolStart(ev.tool, ev.args);
|
|
33984
|
+
renderer.toolStart(ev.tool, ev.args, undefined, ev.icon);
|
|
33718
33985
|
} else {
|
|
33719
|
-
renderer.toolEnd(ev.tool, ev.duration ?? 0, ev.error, ev.ctxDelta);
|
|
33986
|
+
renderer.toolEnd(ev.tool, ev.duration ?? 0, ev.error, ev.ctxDelta, ev.costUsd);
|
|
33720
33987
|
}
|
|
33721
33988
|
}, (phase) => {
|
|
33722
33989
|
if (phase === "thinking") {
|