micro-models-agent 0.56.4 → 0.57.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/CHANGELOG.md +18 -0
- package/dist/main.js +463 -326
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2329,7 +2329,7 @@ var init_defaults = __esm(() => {
|
|
|
2329
2329
|
maxToolIterations: 1000,
|
|
2330
2330
|
stuckThreshold: 6,
|
|
2331
2331
|
autoPlan: true,
|
|
2332
|
-
showReasoning:
|
|
2332
|
+
showReasoning: true,
|
|
2333
2333
|
logLevel: "info",
|
|
2334
2334
|
locale: "en",
|
|
2335
2335
|
session: {
|
|
@@ -2365,8 +2365,6 @@ var init_defaults = __esm(() => {
|
|
|
2365
2365
|
},
|
|
2366
2366
|
ui: {
|
|
2367
2367
|
spinner: true,
|
|
2368
|
-
toolStyle: "inline",
|
|
2369
|
-
toolComments: true,
|
|
2370
2368
|
showContextStats: false,
|
|
2371
2369
|
showCompaction: true
|
|
2372
2370
|
},
|
|
@@ -2401,8 +2399,8 @@ var init_defaults = __esm(() => {
|
|
|
2401
2399
|
lsp: DEFAULT_LSP_CONFIG,
|
|
2402
2400
|
updater: {
|
|
2403
2401
|
enabled: true,
|
|
2404
|
-
checkOnStart:
|
|
2405
|
-
autoInstall:
|
|
2402
|
+
checkOnStart: false,
|
|
2403
|
+
autoInstall: false,
|
|
2406
2404
|
intervalMs: 0
|
|
2407
2405
|
},
|
|
2408
2406
|
reasoning: {
|
|
@@ -2533,6 +2531,7 @@ The path was joined onto the working directory because it does not exist as give
|
|
|
2533
2531
|
"tool.friendly.web_fetch": "Fetching page",
|
|
2534
2532
|
"tool.friendly.web_browse": "Browsing page",
|
|
2535
2533
|
"tool.friendly.download_file": "Downloading file",
|
|
2534
|
+
"tool.friendly.chunk_query": "Querying chunks",
|
|
2536
2535
|
"tool.web_fetch_result": "Fetched page: {url} — {chars} chars, {lines} lines{truncated}",
|
|
2537
2536
|
"tool.web_browse_result": "Browsed page: {url} — {chars} chars, {lines} lines{truncated}",
|
|
2538
2537
|
"tool.web_search_result": 'Search results for "{query}" — {count} results',
|
|
@@ -3297,6 +3296,7 @@ var init_ru = __esm(() => {
|
|
|
3297
3296
|
"tool.friendly.web_fetch": "Загрузка страницы",
|
|
3298
3297
|
"tool.friendly.web_browse": "Просмотр страницы",
|
|
3299
3298
|
"tool.friendly.download_file": "Скачивание файла",
|
|
3299
|
+
"tool.friendly.chunk_query": "Запрос чанков",
|
|
3300
3300
|
"tool.web_fetch_result": "Загружена страница: {url} — {chars} симв., {lines} строк{truncated}",
|
|
3301
3301
|
"tool.web_browse_result": "Просмотрена страница: {url} — {chars} симв., {lines} строк{truncated}",
|
|
3302
3302
|
"tool.web_search_result": 'Результаты поиска "{query}" — {count} результатов',
|
|
@@ -13453,18 +13453,6 @@ function evaluateReasoningPolicy(input, state) {
|
|
|
13453
13453
|
var DECAY_THRESHOLD = 5;
|
|
13454
13454
|
|
|
13455
13455
|
// src/core/agent.ts
|
|
13456
|
-
function isToolCallJson(text) {
|
|
13457
|
-
const trimmed = text.trim();
|
|
13458
|
-
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
13459
|
-
try {
|
|
13460
|
-
JSON.parse(trimmed);
|
|
13461
|
-
return true;
|
|
13462
|
-
} catch {
|
|
13463
|
-
return false;
|
|
13464
|
-
}
|
|
13465
|
-
}
|
|
13466
|
-
return false;
|
|
13467
|
-
}
|
|
13468
13456
|
function toolOutputCharLimit(remainingBudget, historyBudget, bounded) {
|
|
13469
13457
|
if (bounded)
|
|
13470
13458
|
return Number.MAX_SAFE_INTEGER;
|
|
@@ -13687,6 +13675,10 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
13687
13675
|
onPhase,
|
|
13688
13676
|
signal: this.abortController.signal
|
|
13689
13677
|
}) : await this.executeSingleAgentLoop(input, onChunk, onMeta, countTool, onPhase);
|
|
13678
|
+
const provenance = this.callerProvenance();
|
|
13679
|
+
result.provider = provenance.provider;
|
|
13680
|
+
result.model = provenance.model;
|
|
13681
|
+
result.durationMs = Date.now() - startedAt;
|
|
13690
13682
|
emitTurnEnd(result);
|
|
13691
13683
|
return result;
|
|
13692
13684
|
} catch (err) {
|
|
@@ -13730,6 +13722,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
13730
13722
|
let emptyResponseExhausted = false;
|
|
13731
13723
|
let auditFailed = false;
|
|
13732
13724
|
let lastAuditSummary = "";
|
|
13725
|
+
let totalLlmDuration = 0;
|
|
13733
13726
|
let suppressRepetitionRetry = false;
|
|
13734
13727
|
let repeatedToolCount = 0;
|
|
13735
13728
|
const MAX_REPEATED_TOOL_CALLS = 2;
|
|
@@ -13868,6 +13861,8 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
13868
13861
|
}
|
|
13869
13862
|
textContent += chunk.content;
|
|
13870
13863
|
textChunks.push(chunk.content);
|
|
13864
|
+
const textOut = pluginManager.runOnText({ iteration, logger, contextManager }, chunk.content);
|
|
13865
|
+
onChunk?.(textOut);
|
|
13871
13866
|
}
|
|
13872
13867
|
if (chunk.type === "reasoning" && chunk.content) {
|
|
13873
13868
|
reasoningContent += chunk.content;
|
|
@@ -13930,6 +13925,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
13930
13925
|
}
|
|
13931
13926
|
apiCompletionChars += (textContent || reasoningContent).length;
|
|
13932
13927
|
logger.logLLMResponse(config.model, (textContent || reasoningContent).length, Date.now() - llmStart, undefined, "agent");
|
|
13928
|
+
totalLlmDuration += Date.now() - llmStart;
|
|
13933
13929
|
{
|
|
13934
13930
|
const usagePrompt = apiPromptTokens - promptBefore;
|
|
13935
13931
|
const usageCompletion = apiCompletionTokens - completionBefore;
|
|
@@ -13948,14 +13944,6 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
13948
13944
|
if (this.shutdownRequested) {
|
|
13949
13945
|
break;
|
|
13950
13946
|
}
|
|
13951
|
-
const toolComments = this.deps.config.ui?.toolComments ?? true;
|
|
13952
|
-
const showText = textChunks.length > 0 && (!sawToolCall || toolComments && !isToolCallJson(textContent));
|
|
13953
|
-
if (showText) {
|
|
13954
|
-
for (const chunk of textChunks) {
|
|
13955
|
-
const textOut = pluginManager.runOnText({ iteration, logger, contextManager }, chunk);
|
|
13956
|
-
onChunk?.(textOut);
|
|
13957
|
-
}
|
|
13958
|
-
}
|
|
13959
13947
|
let llmResponse = null;
|
|
13960
13948
|
if (sawToolCall) {
|
|
13961
13949
|
llmResponse = { type: "tool_call", calls: toolCalls };
|
|
@@ -14349,7 +14337,8 @@ ${warnLine}
|
|
|
14349
14337
|
totalCost: this.costTracker.total,
|
|
14350
14338
|
costBreakdown: this.costTracker.breakdown(),
|
|
14351
14339
|
compactionCount: contextManager.getCompactionCount(),
|
|
14352
|
-
contextQuality: contextManager.getQuality()
|
|
14340
|
+
contextQuality: contextManager.getQuality(),
|
|
14341
|
+
llmDurationMs: totalLlmDuration
|
|
14353
14342
|
};
|
|
14354
14343
|
}
|
|
14355
14344
|
clearContext() {
|
|
@@ -15050,12 +15039,15 @@ class FactualCheck {
|
|
|
15050
15039
|
for (const f of files)
|
|
15051
15040
|
this.knownFiles.add(f);
|
|
15052
15041
|
}
|
|
15053
|
-
validate(response) {
|
|
15042
|
+
validate(response, deletedFiles) {
|
|
15054
15043
|
const filePaths = this.extractFilePaths(response);
|
|
15055
15044
|
if (filePaths.length === 0)
|
|
15056
15045
|
return { status: "pass" };
|
|
15046
|
+
const deletedBasenames = deletedFiles ? new Set([...deletedFiles].map((p) => p.split(/[/\\]/).pop() ?? p)) : undefined;
|
|
15057
15047
|
const nonExistent = [];
|
|
15058
15048
|
for (const fp of filePaths) {
|
|
15049
|
+
if (deletedBasenames?.has(fp))
|
|
15050
|
+
continue;
|
|
15059
15051
|
if (!this.pathExists(fp)) {
|
|
15060
15052
|
nonExistent.push(fp);
|
|
15061
15053
|
}
|
|
@@ -15303,7 +15295,8 @@ class HallucinationDetector {
|
|
|
15303
15295
|
if (confidenceResult.status === "retry" || confidenceResult.status === "block") {
|
|
15304
15296
|
return confidenceResult;
|
|
15305
15297
|
}
|
|
15306
|
-
const
|
|
15298
|
+
const deletedFiles = new Set(this.consistency.getDeletedFiles());
|
|
15299
|
+
const factualResult = this.factual?.validate(response, deletedFiles);
|
|
15307
15300
|
if (factualResult && factualResult.status !== "pass") {
|
|
15308
15301
|
return factualResult;
|
|
15309
15302
|
}
|
|
@@ -16953,22 +16946,29 @@ class MCPClient {
|
|
|
16953
16946
|
if (!url)
|
|
16954
16947
|
throw new Error("SSE transport requires a url");
|
|
16955
16948
|
this.abortController = new AbortController;
|
|
16956
|
-
const
|
|
16957
|
-
|
|
16958
|
-
|
|
16959
|
-
|
|
16960
|
-
|
|
16961
|
-
|
|
16962
|
-
|
|
16963
|
-
|
|
16964
|
-
|
|
16965
|
-
|
|
16949
|
+
const timeout = setTimeout(() => this.abortController?.abort(), this.config.timeout || HTTP_TIMEOUT_MS);
|
|
16950
|
+
try {
|
|
16951
|
+
const response = await fetch(url, {
|
|
16952
|
+
method: "GET",
|
|
16953
|
+
headers: {
|
|
16954
|
+
Accept: "text/event-stream",
|
|
16955
|
+
...this.config.headers
|
|
16956
|
+
},
|
|
16957
|
+
signal: this.abortController.signal
|
|
16958
|
+
});
|
|
16959
|
+
clearTimeout(timeout);
|
|
16960
|
+
if (!response.ok) {
|
|
16961
|
+
throw new Error(`SSE connection failed: ${response.status} ${response.statusText}`);
|
|
16962
|
+
}
|
|
16963
|
+
this._connected = true;
|
|
16964
|
+
const reader = response.body.getReader();
|
|
16965
|
+
const decoder = new TextDecoder;
|
|
16966
|
+
let buffer = "";
|
|
16967
|
+
this.readSSE(reader, decoder, buffer);
|
|
16968
|
+
} catch (err) {
|
|
16969
|
+
clearTimeout(timeout);
|
|
16970
|
+
throw err;
|
|
16966
16971
|
}
|
|
16967
|
-
this._connected = true;
|
|
16968
|
-
const reader = response.body.getReader();
|
|
16969
|
-
const decoder = new TextDecoder;
|
|
16970
|
-
let buffer = "";
|
|
16971
|
-
this.readSSE(reader, decoder, buffer);
|
|
16972
16972
|
}
|
|
16973
16973
|
async readSSE(reader, decoder, buffer) {
|
|
16974
16974
|
try {
|
|
@@ -17162,7 +17162,8 @@ class MCPClient {
|
|
|
17162
17162
|
"Content-Type": "application/json",
|
|
17163
17163
|
...this.config.headers
|
|
17164
17164
|
},
|
|
17165
|
-
body: JSON.stringify(request)
|
|
17165
|
+
body: JSON.stringify(request),
|
|
17166
|
+
signal: AbortSignal.timeout(this.config.timeout || HTTP_TIMEOUT_MS)
|
|
17166
17167
|
});
|
|
17167
17168
|
if (!response.ok) {
|
|
17168
17169
|
const text = await response.text().catch(() => "");
|
|
@@ -17248,7 +17249,8 @@ class MCPClient {
|
|
|
17248
17249
|
"Content-Type": "application/json",
|
|
17249
17250
|
...this.config.headers
|
|
17250
17251
|
},
|
|
17251
|
-
body: JSON.stringify(request)
|
|
17252
|
+
body: JSON.stringify(request),
|
|
17253
|
+
signal: AbortSignal.timeout(this.config.timeout || HTTP_TIMEOUT_MS)
|
|
17252
17254
|
});
|
|
17253
17255
|
if (!response.ok) {
|
|
17254
17256
|
const text = await response.text().catch(() => "");
|
|
@@ -17325,6 +17327,7 @@ class MCPClient {
|
|
|
17325
17327
|
});
|
|
17326
17328
|
}
|
|
17327
17329
|
}
|
|
17330
|
+
var HTTP_TIMEOUT_MS = 1e4;
|
|
17328
17331
|
var init_client = () => {};
|
|
17329
17332
|
|
|
17330
17333
|
// src/modules/mcp/registry.ts
|
|
@@ -23978,9 +23981,11 @@ class MCPModule {
|
|
|
23978
23981
|
config;
|
|
23979
23982
|
name = "mcp";
|
|
23980
23983
|
connections = new Map;
|
|
23984
|
+
serverConfigs = new Map;
|
|
23981
23985
|
discovered = [];
|
|
23982
23986
|
initialized = false;
|
|
23983
23987
|
initError = null;
|
|
23988
|
+
failedServers = new Set;
|
|
23984
23989
|
constructor(config) {
|
|
23985
23990
|
this.config = config;
|
|
23986
23991
|
}
|
|
@@ -24007,13 +24012,58 @@ class MCPModule {
|
|
|
24007
24012
|
registry2.register(serverConfig);
|
|
24008
24013
|
}
|
|
24009
24014
|
for (const serverName of registry2.list()) {
|
|
24010
|
-
|
|
24015
|
+
this.serverConfigs.set(serverName, registry2.get(serverName));
|
|
24016
|
+
}
|
|
24017
|
+
this.discoverAllTools();
|
|
24018
|
+
}
|
|
24019
|
+
async discoverAllTools() {
|
|
24020
|
+
for (const [serverName, serverConfig] of this.serverConfigs) {
|
|
24021
|
+
if (this.failedServers.has(serverName))
|
|
24022
|
+
continue;
|
|
24011
24023
|
const client = new MCPClient(serverConfig);
|
|
24012
24024
|
try {
|
|
24013
|
-
await
|
|
24014
|
-
|
|
24015
|
-
|
|
24016
|
-
|
|
24025
|
+
await Promise.race([
|
|
24026
|
+
(async () => {
|
|
24027
|
+
await client.connect();
|
|
24028
|
+
const tools = await client.listTools();
|
|
24029
|
+
this.connections.set(serverName, client);
|
|
24030
|
+
for (const tool of tools) {
|
|
24031
|
+
this.discovered.push({
|
|
24032
|
+
serverName,
|
|
24033
|
+
toolName: tool.name,
|
|
24034
|
+
description: tool.description || `Tool on MCP server "${serverName}"`,
|
|
24035
|
+
inputSchema: tool.inputSchema || {}
|
|
24036
|
+
});
|
|
24037
|
+
}
|
|
24038
|
+
})(),
|
|
24039
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("discovery timeout")), DISCOVERY_TIMEOUT_MS))
|
|
24040
|
+
]);
|
|
24041
|
+
} catch (e) {
|
|
24042
|
+
this.failedServers.add(serverName);
|
|
24043
|
+
this.initError = `MCP server "${serverName}" init failed: ${e.message}`;
|
|
24044
|
+
await client.disconnect().catch((err) => {
|
|
24045
|
+
logger3.warn(`cleanup disconnect for "${serverName}" failed`, { error: String(err) });
|
|
24046
|
+
});
|
|
24047
|
+
}
|
|
24048
|
+
}
|
|
24049
|
+
}
|
|
24050
|
+
async ensureConnected(serverName) {
|
|
24051
|
+
const existing = this.connections.get(serverName);
|
|
24052
|
+
if (existing?.isConnected())
|
|
24053
|
+
return existing;
|
|
24054
|
+
if (this.failedServers.has(serverName))
|
|
24055
|
+
return null;
|
|
24056
|
+
const serverConfig = this.serverConfigs.get(serverName);
|
|
24057
|
+
if (!serverConfig)
|
|
24058
|
+
return null;
|
|
24059
|
+
const client = new MCPClient(serverConfig);
|
|
24060
|
+
try {
|
|
24061
|
+
await client.connect();
|
|
24062
|
+
const tools = await client.listTools();
|
|
24063
|
+
this.connections.set(serverName, client);
|
|
24064
|
+
for (const tool of tools) {
|
|
24065
|
+
const alreadyDiscovered = this.discovered.some((d) => d.serverName === serverName && d.toolName === tool.name);
|
|
24066
|
+
if (!alreadyDiscovered) {
|
|
24017
24067
|
this.discovered.push({
|
|
24018
24068
|
serverName,
|
|
24019
24069
|
toolName: tool.name,
|
|
@@ -24021,16 +24071,18 @@ class MCPModule {
|
|
|
24021
24071
|
inputSchema: tool.inputSchema || {}
|
|
24022
24072
|
});
|
|
24023
24073
|
}
|
|
24024
|
-
} catch (e) {
|
|
24025
|
-
this.initError = `MCP server "${serverName}" init failed: ${e.message}`;
|
|
24026
|
-
await client.disconnect().catch((err) => {
|
|
24027
|
-
logger3.warn(`cleanup disconnect for "${serverName}" failed`, { error: String(err) });
|
|
24028
|
-
});
|
|
24029
24074
|
}
|
|
24075
|
+
return client;
|
|
24076
|
+
} catch (e) {
|
|
24077
|
+
this.failedServers.add(serverName);
|
|
24078
|
+
logger3.warn(`MCP connect failed for "${serverName}": ${e.message}`);
|
|
24079
|
+
await client.disconnect().catch(() => {});
|
|
24080
|
+
return null;
|
|
24030
24081
|
}
|
|
24031
24082
|
}
|
|
24032
24083
|
getSystemPromptBlock() {
|
|
24033
|
-
|
|
24084
|
+
const serverNames = [...this.serverConfigs.keys()];
|
|
24085
|
+
if (serverNames.length === 0)
|
|
24034
24086
|
return null;
|
|
24035
24087
|
const lines = ["---", "MCP servers available:"];
|
|
24036
24088
|
const byServer = new Map;
|
|
@@ -24039,11 +24091,16 @@ class MCPModule {
|
|
|
24039
24091
|
list.push(d);
|
|
24040
24092
|
byServer.set(d.serverName, list);
|
|
24041
24093
|
}
|
|
24042
|
-
for (const
|
|
24043
|
-
lines.push(` [${
|
|
24044
|
-
|
|
24045
|
-
|
|
24046
|
-
|
|
24094
|
+
for (const serverName of serverNames) {
|
|
24095
|
+
lines.push(` [${serverName}]`);
|
|
24096
|
+
const tools = byServer.get(serverName);
|
|
24097
|
+
if (tools && tools.length > 0) {
|
|
24098
|
+
for (const t2 of tools) {
|
|
24099
|
+
const toolRef = sanitizeToolName(serverName, t2.toolName);
|
|
24100
|
+
lines.push(` - ${toolRef}: ${t2.description}`);
|
|
24101
|
+
}
|
|
24102
|
+
} else {
|
|
24103
|
+
lines.push(` (not yet connected — use mcp__${serverName}__connect to discover tools)`);
|
|
24047
24104
|
}
|
|
24048
24105
|
}
|
|
24049
24106
|
lines.push("---");
|
|
@@ -24056,33 +24113,60 @@ class MCPModule {
|
|
|
24056
24113
|
};
|
|
24057
24114
|
}
|
|
24058
24115
|
getToolDefinitions() {
|
|
24059
|
-
|
|
24060
|
-
|
|
24061
|
-
|
|
24062
|
-
|
|
24063
|
-
|
|
24064
|
-
|
|
24065
|
-
|
|
24066
|
-
|
|
24067
|
-
|
|
24068
|
-
|
|
24069
|
-
|
|
24070
|
-
|
|
24116
|
+
const defs = [];
|
|
24117
|
+
for (const d of this.discovered) {
|
|
24118
|
+
defs.push({
|
|
24119
|
+
name: sanitizeToolName(d.serverName, d.toolName),
|
|
24120
|
+
description: `${d.description} [MCP server: ${d.serverName}]`,
|
|
24121
|
+
parameters: convertInputSchema(d.inputSchema),
|
|
24122
|
+
tags: ["code", "research"],
|
|
24123
|
+
handler: async (_ctx, args) => {
|
|
24124
|
+
const client = this.connections.get(d.serverName);
|
|
24125
|
+
if (!client?.isConnected()) {
|
|
24126
|
+
return {
|
|
24127
|
+
success: false,
|
|
24128
|
+
output: `MCP server "${d.serverName}" not connected`
|
|
24129
|
+
};
|
|
24130
|
+
}
|
|
24131
|
+
try {
|
|
24132
|
+
const result = await client.callTool(d.toolName, args);
|
|
24133
|
+
return {
|
|
24134
|
+
success: true,
|
|
24135
|
+
output: typeof result === "string" ? result : JSON.stringify(result, null, 2)
|
|
24136
|
+
};
|
|
24137
|
+
} catch (e) {
|
|
24138
|
+
return { success: false, output: `MCP call failed: ${e.message}` };
|
|
24139
|
+
}
|
|
24071
24140
|
}
|
|
24072
|
-
|
|
24073
|
-
|
|
24074
|
-
|
|
24141
|
+
});
|
|
24142
|
+
}
|
|
24143
|
+
for (const [serverName] of this.serverConfigs) {
|
|
24144
|
+
if (this.failedServers.has(serverName))
|
|
24145
|
+
continue;
|
|
24146
|
+
const alreadyDiscovered = this.discovered.some((d) => d.serverName === serverName);
|
|
24147
|
+
if (alreadyDiscovered)
|
|
24148
|
+
continue;
|
|
24149
|
+
defs.push({
|
|
24150
|
+
name: sanitizeToolName(serverName, "connect"),
|
|
24151
|
+
description: `Connect to MCP server "${serverName}" and discover its tools`,
|
|
24152
|
+
parameters: { type: "object", properties: {} },
|
|
24153
|
+
tags: ["code", "research"],
|
|
24154
|
+
handler: async (_ctx, _args) => {
|
|
24155
|
+
const client = await this.ensureConnected(serverName);
|
|
24156
|
+
if (!client) {
|
|
24157
|
+
return { success: false, output: `MCP server "${serverName}" connection failed` };
|
|
24075
24158
|
}
|
|
24076
|
-
const
|
|
24159
|
+
const tools = this.discovered.filter((d) => d.serverName === serverName).map((d) => ` - ${sanitizeToolName(serverName, d.toolName)}: ${d.description}`);
|
|
24077
24160
|
return {
|
|
24078
24161
|
success: true,
|
|
24079
|
-
output:
|
|
24162
|
+
output: tools.length > 0 ? `Connected to "${serverName}". Tools:
|
|
24163
|
+
${tools.join(`
|
|
24164
|
+
`)}` : `Connected to "${serverName}" (no tools discovered)`
|
|
24080
24165
|
};
|
|
24081
|
-
} catch (e) {
|
|
24082
|
-
return { success: false, output: `MCP call failed: ${e.message}` };
|
|
24083
24166
|
}
|
|
24084
|
-
}
|
|
24085
|
-
}
|
|
24167
|
+
});
|
|
24168
|
+
}
|
|
24169
|
+
return defs;
|
|
24086
24170
|
}
|
|
24087
24171
|
getPlugin() {
|
|
24088
24172
|
return {
|
|
@@ -24100,7 +24184,7 @@ class MCPModule {
|
|
|
24100
24184
|
};
|
|
24101
24185
|
}
|
|
24102
24186
|
}
|
|
24103
|
-
var logger3;
|
|
24187
|
+
var logger3, DISCOVERY_TIMEOUT_MS = 5000;
|
|
24104
24188
|
var init_module7 = __esm(() => {
|
|
24105
24189
|
init_client();
|
|
24106
24190
|
init_app_logger();
|
|
@@ -24580,6 +24664,12 @@ __export(exports_probe, {
|
|
|
24580
24664
|
getCachedProbeResult: () => getCachedProbeResult,
|
|
24581
24665
|
cacheKey: () => cacheKey
|
|
24582
24666
|
});
|
|
24667
|
+
import { existsSync as existsSync50, readFileSync as readFileSync31, writeFileSync as writeFileSync19, mkdirSync as mkdirSync20 } from "fs";
|
|
24668
|
+
import { join as join42, dirname as dirname18 } from "path";
|
|
24669
|
+
import { homedir as homedir14 } from "os";
|
|
24670
|
+
function cachePath() {
|
|
24671
|
+
return join42(homedir14(), ".mma", "reasoning-cache.json");
|
|
24672
|
+
}
|
|
24583
24673
|
async function probeReasoningSupport(provider, strategy, signal) {
|
|
24584
24674
|
if (strategy === "none")
|
|
24585
24675
|
return false;
|
|
@@ -24602,20 +24692,58 @@ function cacheKey(baseUrl, model) {
|
|
|
24602
24692
|
return `${baseUrl}|${model}`;
|
|
24603
24693
|
}
|
|
24604
24694
|
function getCachedProbeResult(key) {
|
|
24605
|
-
|
|
24695
|
+
const mem = memCache.get(key);
|
|
24696
|
+
if (mem && Date.now() - mem.ts < CACHE_TTL_MS) {
|
|
24697
|
+
return mem.result;
|
|
24698
|
+
}
|
|
24699
|
+
const disk = readDiskCache();
|
|
24700
|
+
const entry = disk[key];
|
|
24701
|
+
if (entry) {
|
|
24702
|
+
const age = Date.now() - new Date(entry.ts).getTime();
|
|
24703
|
+
if (age < CACHE_TTL_MS) {
|
|
24704
|
+
memCache.set(key, { result: entry.result, ts: Date.now() });
|
|
24705
|
+
return entry.result;
|
|
24706
|
+
}
|
|
24707
|
+
}
|
|
24708
|
+
return;
|
|
24606
24709
|
}
|
|
24607
24710
|
function setCachedProbeResult(key, result) {
|
|
24608
|
-
|
|
24711
|
+
const now = new Date().toISOString();
|
|
24712
|
+
memCache.set(key, { result, ts: Date.now() });
|
|
24713
|
+
const disk = readDiskCache();
|
|
24714
|
+
disk[key] = { result, ts: now };
|
|
24715
|
+
writeDiskCache(disk);
|
|
24609
24716
|
}
|
|
24610
24717
|
function resetProbeCache() {
|
|
24611
|
-
|
|
24718
|
+
memCache.clear();
|
|
24719
|
+
const path = cachePath();
|
|
24720
|
+
if (existsSync50(path)) {
|
|
24721
|
+
writeFileSync19(path, "{}", "utf-8");
|
|
24722
|
+
}
|
|
24723
|
+
}
|
|
24724
|
+
function readDiskCache() {
|
|
24725
|
+
try {
|
|
24726
|
+
const path = cachePath();
|
|
24727
|
+
if (existsSync50(path)) {
|
|
24728
|
+
return JSON.parse(readFileSync31(path, "utf-8"));
|
|
24729
|
+
}
|
|
24730
|
+
} catch {}
|
|
24731
|
+
return {};
|
|
24612
24732
|
}
|
|
24613
|
-
|
|
24733
|
+
function writeDiskCache(data) {
|
|
24734
|
+
try {
|
|
24735
|
+
const path = cachePath();
|
|
24736
|
+
mkdirSync20(dirname18(path), { recursive: true });
|
|
24737
|
+
writeFileSync19(path, JSON.stringify(data, null, 2), "utf-8");
|
|
24738
|
+
} catch {}
|
|
24739
|
+
}
|
|
24740
|
+
var PROBE_MESSAGES, CACHE_TTL_MS, memCache;
|
|
24614
24741
|
var init_probe = __esm(() => {
|
|
24615
24742
|
PROBE_MESSAGES = [
|
|
24616
24743
|
{ role: "user", content: "Reply with exactly: ok" }
|
|
24617
24744
|
];
|
|
24618
|
-
|
|
24745
|
+
CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
24746
|
+
memCache = new Map;
|
|
24619
24747
|
});
|
|
24620
24748
|
|
|
24621
24749
|
// src/tools/set-thinking.ts
|
|
@@ -24697,9 +24825,9 @@ __export(exports_bootstrap, {
|
|
|
24697
24825
|
buildSystemInfo: () => buildSystemInfo,
|
|
24698
24826
|
bootstrap: () => bootstrap
|
|
24699
24827
|
});
|
|
24700
|
-
import { homedir as
|
|
24701
|
-
import { join as
|
|
24702
|
-
import { existsSync as
|
|
24828
|
+
import { homedir as homedir15 } from "os";
|
|
24829
|
+
import { join as join43, resolve as resolve22 } from "path";
|
|
24830
|
+
import { existsSync as existsSync51, readFileSync as readFileSync32, writeFileSync as writeFileSync20 } from "fs";
|
|
24703
24831
|
function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
24704
24832
|
const now = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
24705
24833
|
const isWin = profileCompressed.toLowerCase().includes("win32");
|
|
@@ -24752,8 +24880,8 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
|
24752
24880
|
`);
|
|
24753
24881
|
}
|
|
24754
24882
|
async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reasoningLevel) {
|
|
24755
|
-
const dir = configDir || process.env.MMA_CONFIG_DIR ||
|
|
24756
|
-
const projectConfigPath = projectDir ?
|
|
24883
|
+
const dir = configDir || process.env.MMA_CONFIG_DIR || join43(homedir15(), ".mma");
|
|
24884
|
+
const projectConfigPath = projectDir ? join43(projectDir, ".mmrc") : join43(process.cwd(), ".mmrc");
|
|
24757
24885
|
const { config, legacyDetected } = loadConfig({ configDir: dir, projectConfigPath });
|
|
24758
24886
|
setLocale(config.locale);
|
|
24759
24887
|
if (reasoningLevel && reasoningLevel !== "auto") {
|
|
@@ -24769,7 +24897,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
24769
24897
|
}
|
|
24770
24898
|
} catch {}
|
|
24771
24899
|
const logger4 = new Logger(config.logLevel);
|
|
24772
|
-
logger4.setLogDir(
|
|
24900
|
+
logger4.setLogDir(join43(dir, "logs"));
|
|
24773
24901
|
logger4.debug("MMA bootstrap", {
|
|
24774
24902
|
version: config.version,
|
|
24775
24903
|
model: config.model
|
|
@@ -24798,7 +24926,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
24798
24926
|
logger4.info(`Model ${config.model} loaded in ${loadResult.loadTime}s`);
|
|
24799
24927
|
}
|
|
24800
24928
|
}
|
|
24801
|
-
const profile = new UserProfile(
|
|
24929
|
+
const profile = new UserProfile(join43(dir));
|
|
24802
24930
|
profile.load() || profile.collect();
|
|
24803
24931
|
profile.save();
|
|
24804
24932
|
const providerManager = new ProviderManager(config.provider, {
|
|
@@ -24848,7 +24976,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
24848
24976
|
for (const warning of envReport.warnings) {
|
|
24849
24977
|
logger4.warn(warning);
|
|
24850
24978
|
}
|
|
24851
|
-
const projectMapCacheDir =
|
|
24979
|
+
const projectMapCacheDir = join43(baseDir, ".mma");
|
|
24852
24980
|
const indexerModule = new IndexerModule({
|
|
24853
24981
|
baseDir,
|
|
24854
24982
|
cacheDir: projectMapCacheDir
|
|
@@ -24859,9 +24987,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
24859
24987
|
logger4.warn(`Project indexing failed: ${err.message}`);
|
|
24860
24988
|
}
|
|
24861
24989
|
const skillsLoader = new SkillsLoader;
|
|
24862
|
-
const builtinDir =
|
|
24863
|
-
const globalDir =
|
|
24864
|
-
const projectSkillsDir =
|
|
24990
|
+
const builtinDir = join43(import.meta.dirname, "skills", "builtin");
|
|
24991
|
+
const globalDir = join43(homedir15(), ".agents", "skills");
|
|
24992
|
+
const projectSkillsDir = join43(baseDir, ".mma", "skills");
|
|
24865
24993
|
const availableSkills = skillsLoader.loadFromAllSources(builtinDir, globalDir, projectSkillsDir);
|
|
24866
24994
|
const skillsBudget = Math.floor(config.contextWindow * config.skills.budget);
|
|
24867
24995
|
const skillsModule = new SkillsModule(availableSkills, skillsBudget);
|
|
@@ -24877,11 +25005,11 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
24877
25005
|
essential: true,
|
|
24878
25006
|
estimatedTokens: Math.ceil(systemInfoContent.length / 4)
|
|
24879
25007
|
};
|
|
24880
|
-
const agentsMdGlobal =
|
|
24881
|
-
if (!
|
|
24882
|
-
|
|
25008
|
+
const agentsMdGlobal = join43(dir, "AGENTS.md");
|
|
25009
|
+
if (!existsSync51(agentsMdGlobal)) {
|
|
25010
|
+
writeFileSync20(agentsMdGlobal, "", "utf-8");
|
|
24883
25011
|
}
|
|
24884
|
-
const sessionDir =
|
|
25012
|
+
const sessionDir = join43(dir, "sessions");
|
|
24885
25013
|
const sessionStore = new SessionStore(sessionDir);
|
|
24886
25014
|
sessionStore.init();
|
|
24887
25015
|
const sessionManager = new SessionManager(sessionStore, {
|
|
@@ -24955,7 +25083,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
24955
25083
|
const mcpModule = new MCPModule(config);
|
|
24956
25084
|
await mcpModule.initialize();
|
|
24957
25085
|
moduleRegistry.register(mcpModule);
|
|
24958
|
-
const memoryStore = new MemoryStore(
|
|
25086
|
+
const memoryStore = new MemoryStore(join43(dir, "memory"));
|
|
24959
25087
|
const memoryModule = new MemoryModule(memoryStore);
|
|
24960
25088
|
moduleRegistry.register(memoryModule);
|
|
24961
25089
|
if (config.browser.enabled) {
|
|
@@ -25009,8 +25137,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
25009
25137
|
pluginManager.register(plugin);
|
|
25010
25138
|
pluginManager.register(plugin2);
|
|
25011
25139
|
const pluginLoader = new PluginLoader;
|
|
25012
|
-
const globalPluginsDir =
|
|
25013
|
-
const projectPluginsDir =
|
|
25140
|
+
const globalPluginsDir = join43(homedir15(), ".mma", "plugins");
|
|
25141
|
+
const projectPluginsDir = join43(baseDir, ".mma", "plugins");
|
|
25014
25142
|
const mmaVersion = readMmaVersion();
|
|
25015
25143
|
pluginLoader.loadFromDir(globalPluginsDir, pluginManager, logger4, {
|
|
25016
25144
|
source: "global",
|
|
@@ -25036,13 +25164,13 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
25036
25164
|
const skipAgentsMd = noAgentsMd === true;
|
|
25037
25165
|
if (!skipAgentsMd) {
|
|
25038
25166
|
const agentsMdCandidates = [
|
|
25039
|
-
|
|
25040
|
-
|
|
25041
|
-
|
|
25167
|
+
join43(baseDir, "AGENTS.md"),
|
|
25168
|
+
join43(baseDir, ".mma", "AGENTS.md"),
|
|
25169
|
+
join43(dir, "AGENTS.md")
|
|
25042
25170
|
];
|
|
25043
25171
|
for (const p of agentsMdCandidates) {
|
|
25044
|
-
if (
|
|
25045
|
-
const content =
|
|
25172
|
+
if (existsSync51(p)) {
|
|
25173
|
+
const content = readFileSync32(p, "utf-8").trim();
|
|
25046
25174
|
if (content) {
|
|
25047
25175
|
agentsMdBlocks.push({
|
|
25048
25176
|
content,
|
|
@@ -33428,8 +33556,8 @@ var init_scenarios = __esm(() => {
|
|
|
33428
33556
|
});
|
|
33429
33557
|
|
|
33430
33558
|
// src/modules/certification/loader.ts
|
|
33431
|
-
import { existsSync as
|
|
33432
|
-
import { join as
|
|
33559
|
+
import { existsSync as existsSync53, readdirSync as readdirSync17, readFileSync as readFileSync34 } from "fs";
|
|
33560
|
+
import { join as join46 } from "path";
|
|
33433
33561
|
function validateScenario(s) {
|
|
33434
33562
|
const errors2 = [];
|
|
33435
33563
|
const isSkip = s.mode === "skip";
|
|
@@ -33481,12 +33609,12 @@ function loadScenarios(userDir) {
|
|
|
33481
33609
|
else
|
|
33482
33610
|
scenarios.push(s);
|
|
33483
33611
|
}
|
|
33484
|
-
if (userDir &&
|
|
33612
|
+
if (userDir && existsSync53(userDir)) {
|
|
33485
33613
|
for (const file of readdirSync17(userDir)) {
|
|
33486
33614
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
|
|
33487
33615
|
continue;
|
|
33488
33616
|
try {
|
|
33489
|
-
const raw =
|
|
33617
|
+
const raw = readFileSync34(join46(userDir, file), "utf-8");
|
|
33490
33618
|
const data = $parse(raw);
|
|
33491
33619
|
const parsed = normalizeScenario(data, file);
|
|
33492
33620
|
const errs = validateScenario(parsed);
|
|
@@ -33549,8 +33677,8 @@ var init_loader3 = __esm(() => {
|
|
|
33549
33677
|
});
|
|
33550
33678
|
|
|
33551
33679
|
// src/modules/certification/fact-checker.ts
|
|
33552
|
-
import { existsSync as
|
|
33553
|
-
import { join as
|
|
33680
|
+
import { existsSync as existsSync54, readFileSync as readFileSync35, statSync as statSync9 } from "fs";
|
|
33681
|
+
import { join as join47 } from "path";
|
|
33554
33682
|
function checkSandbox(sandboxDir, checks, exitCode, output) {
|
|
33555
33683
|
const failures = [];
|
|
33556
33684
|
for (const check of checks) {
|
|
@@ -33567,16 +33695,16 @@ function runCheck2(sandboxDir, check, exitCode, output) {
|
|
|
33567
33695
|
case "outputContains":
|
|
33568
33696
|
return output.includes(check.text);
|
|
33569
33697
|
case "fileExists":
|
|
33570
|
-
return isFile(
|
|
33698
|
+
return isFile(join47(sandboxDir, check.path));
|
|
33571
33699
|
case "fileNotExists":
|
|
33572
|
-
return !
|
|
33700
|
+
return !existsSync54(join47(sandboxDir, check.path));
|
|
33573
33701
|
case "dirExists":
|
|
33574
|
-
return isDir(
|
|
33702
|
+
return isDir(join47(sandboxDir, check.path));
|
|
33575
33703
|
case "fileContent": {
|
|
33576
|
-
const abs =
|
|
33704
|
+
const abs = join47(sandboxDir, check.path);
|
|
33577
33705
|
if (!isFile(abs))
|
|
33578
33706
|
return false;
|
|
33579
|
-
const content =
|
|
33707
|
+
const content = readFileSync35(abs, "utf-8");
|
|
33580
33708
|
if (check.contains !== undefined)
|
|
33581
33709
|
return content.includes(check.contains);
|
|
33582
33710
|
if (check.equals !== undefined)
|
|
@@ -33584,10 +33712,10 @@ function runCheck2(sandboxDir, check, exitCode, output) {
|
|
|
33584
33712
|
return false;
|
|
33585
33713
|
}
|
|
33586
33714
|
case "fileRegex": {
|
|
33587
|
-
const abs =
|
|
33715
|
+
const abs = join47(sandboxDir, check.path);
|
|
33588
33716
|
if (!isFile(abs))
|
|
33589
33717
|
return false;
|
|
33590
|
-
return new RegExp(check.pattern).test(
|
|
33718
|
+
return new RegExp(check.pattern).test(readFileSync35(abs, "utf-8"));
|
|
33591
33719
|
}
|
|
33592
33720
|
default:
|
|
33593
33721
|
return false;
|
|
@@ -33595,14 +33723,14 @@ function runCheck2(sandboxDir, check, exitCode, output) {
|
|
|
33595
33723
|
}
|
|
33596
33724
|
function isFile(p) {
|
|
33597
33725
|
try {
|
|
33598
|
-
return
|
|
33726
|
+
return existsSync54(p) && statSync9(p).isFile();
|
|
33599
33727
|
} catch {
|
|
33600
33728
|
return false;
|
|
33601
33729
|
}
|
|
33602
33730
|
}
|
|
33603
33731
|
function isDir(p) {
|
|
33604
33732
|
try {
|
|
33605
|
-
return
|
|
33733
|
+
return existsSync54(p) && statSync9(p).isDirectory();
|
|
33606
33734
|
} catch {
|
|
33607
33735
|
return false;
|
|
33608
33736
|
}
|
|
@@ -33633,8 +33761,8 @@ var init_fact_checker = () => {};
|
|
|
33633
33761
|
|
|
33634
33762
|
// src/modules/certification/runner.ts
|
|
33635
33763
|
import { spawn as spawn10 } from "child_process";
|
|
33636
|
-
import { existsSync as
|
|
33637
|
-
import { join as
|
|
33764
|
+
import { existsSync as existsSync55, mkdirSync as mkdirSync21, rmSync as rmSync4, cpSync as cpSync2, writeFileSync as writeFileSync21, readdirSync as readdirSync18, readFileSync as readFileSync36 } from "fs";
|
|
33765
|
+
import { join as join48, resolve as resolve23, dirname as dirname21, relative as relative7 } from "path";
|
|
33638
33766
|
async function runScenario(scenario, opts) {
|
|
33639
33767
|
if (scenario.mode === "skip") {
|
|
33640
33768
|
return {
|
|
@@ -33654,7 +33782,7 @@ async function runScenario(scenario, opts) {
|
|
|
33654
33782
|
let firstError;
|
|
33655
33783
|
let lastFailedSandbox;
|
|
33656
33784
|
for (let i = 1;i <= reps; i++) {
|
|
33657
|
-
const sandbox =
|
|
33785
|
+
const sandbox = join48(opts.sandboxBase, `run-${scenario.id}-${i}`);
|
|
33658
33786
|
let failures = [];
|
|
33659
33787
|
let exitCode = -1;
|
|
33660
33788
|
let output = "";
|
|
@@ -33678,9 +33806,9 @@ async function runScenario(scenario, opts) {
|
|
|
33678
33806
|
env3.MMA_PROVIDER_APIKEY = opts.providerKey;
|
|
33679
33807
|
if (scenario.config && opts.baseConfig) {
|
|
33680
33808
|
const merged = deepMergeAny(opts.baseConfig, scenario.config);
|
|
33681
|
-
const certConfigDir =
|
|
33682
|
-
|
|
33683
|
-
|
|
33809
|
+
const certConfigDir = join48(sandbox, ".mma");
|
|
33810
|
+
mkdirSync21(certConfigDir, { recursive: true });
|
|
33811
|
+
writeFileSync21(join48(certConfigDir, "config.json"), JSON.stringify(merged, null, 2), "utf-8");
|
|
33684
33812
|
env3.MMA_CONFIG_DIR = certConfigDir;
|
|
33685
33813
|
}
|
|
33686
33814
|
const res = await runner(env3, opts.mmaRoot, args, timeoutMs);
|
|
@@ -33725,14 +33853,14 @@ ${res.stderr}`;
|
|
|
33725
33853
|
}
|
|
33726
33854
|
function prepareSandbox(sandbox, scenario, mmaRoot) {
|
|
33727
33855
|
rmSync4(sandbox, { recursive: true, force: true });
|
|
33728
|
-
|
|
33856
|
+
mkdirSync21(sandbox, { recursive: true });
|
|
33729
33857
|
for (const f of scenario.fixtures ?? []) {
|
|
33730
|
-
const src =
|
|
33731
|
-
if (!
|
|
33858
|
+
const src = join48(mmaRoot, f.source);
|
|
33859
|
+
if (!existsSync55(src)) {
|
|
33732
33860
|
throw new Error(`fixture missing: ${f.source}`);
|
|
33733
33861
|
}
|
|
33734
|
-
const dest =
|
|
33735
|
-
|
|
33862
|
+
const dest = join48(sandbox, f.dest);
|
|
33863
|
+
mkdirSync21(dirname21(dest), { recursive: true });
|
|
33736
33864
|
cpSync2(src, dest);
|
|
33737
33865
|
}
|
|
33738
33866
|
}
|
|
@@ -33744,10 +33872,10 @@ function collectDiagnostics(sandbox) {
|
|
|
33744
33872
|
} else {
|
|
33745
33873
|
lines.push(" Files created: (none)");
|
|
33746
33874
|
}
|
|
33747
|
-
const planPath =
|
|
33748
|
-
if (
|
|
33875
|
+
const planPath = join48(sandbox, ".mma", "plans", "active.json");
|
|
33876
|
+
if (existsSync55(planPath)) {
|
|
33749
33877
|
try {
|
|
33750
|
-
const plan = JSON.parse(
|
|
33878
|
+
const plan = JSON.parse(readFileSync36(planPath, "utf-8"));
|
|
33751
33879
|
const steps = plan.steps ?? [];
|
|
33752
33880
|
const done = steps.filter((s) => s.status === "done").length;
|
|
33753
33881
|
const pending = steps.filter((s) => s.status === "pending" || s.status === "in_progress");
|
|
@@ -33766,7 +33894,7 @@ function listFiles(dir, root) {
|
|
|
33766
33894
|
for (const entry of readdirSync18(dir, { withFileTypes: true })) {
|
|
33767
33895
|
if (entry.name === ".mma")
|
|
33768
33896
|
continue;
|
|
33769
|
-
const abs =
|
|
33897
|
+
const abs = join48(dir, entry.name);
|
|
33770
33898
|
const rel = toForwardSlash(relative7(root, abs));
|
|
33771
33899
|
if (entry.isDirectory()) {
|
|
33772
33900
|
result.push(...listFiles(abs, root));
|
|
@@ -33778,15 +33906,15 @@ function listFiles(dir, root) {
|
|
|
33778
33906
|
return result;
|
|
33779
33907
|
}
|
|
33780
33908
|
function resolveMmaEntry(mmaRoot) {
|
|
33781
|
-
const dev =
|
|
33782
|
-
if (
|
|
33909
|
+
const dev = join48(mmaRoot, "src", "cli", "main.ts");
|
|
33910
|
+
if (existsSync55(dev))
|
|
33783
33911
|
return dev;
|
|
33784
|
-
return
|
|
33912
|
+
return join48(mmaRoot, "dist", "main.js");
|
|
33785
33913
|
}
|
|
33786
33914
|
function findMmaRoot(fromDir) {
|
|
33787
33915
|
const candidates = [resolve23(fromDir, "..", "..", ".."), resolve23(fromDir, "..")];
|
|
33788
33916
|
for (const c of candidates) {
|
|
33789
|
-
if (
|
|
33917
|
+
if (existsSync55(join48(c, "package.json")))
|
|
33790
33918
|
return c;
|
|
33791
33919
|
}
|
|
33792
33920
|
return process.cwd();
|
|
@@ -33853,16 +33981,16 @@ __export(exports_cli, {
|
|
|
33853
33981
|
certStatus: () => certStatus,
|
|
33854
33982
|
certList: () => certList
|
|
33855
33983
|
});
|
|
33856
|
-
import { rmSync as rmSync5, writeFileSync as
|
|
33857
|
-
import { join as
|
|
33984
|
+
import { rmSync as rmSync5, writeFileSync as writeFileSync22 } from "fs";
|
|
33985
|
+
import { join as join49, dirname as dirname22 } from "path";
|
|
33858
33986
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
33859
|
-
import { existsSync as
|
|
33987
|
+
import { existsSync as existsSync56, readFileSync as readFileSync37 } from "fs";
|
|
33860
33988
|
function readVersion() {
|
|
33861
|
-
const candidates = [
|
|
33989
|
+
const candidates = [join49(MMA_ROOT, "package.json")];
|
|
33862
33990
|
for (const p of candidates) {
|
|
33863
|
-
if (
|
|
33991
|
+
if (existsSync56(p)) {
|
|
33864
33992
|
try {
|
|
33865
|
-
const raw = JSON.parse(
|
|
33993
|
+
const raw = JSON.parse(readFileSync37(p, "utf-8"));
|
|
33866
33994
|
if (raw.version)
|
|
33867
33995
|
return raw.version;
|
|
33868
33996
|
} catch {}
|
|
@@ -33875,7 +34003,7 @@ function parseTags(s) {
|
|
|
33875
34003
|
}
|
|
33876
34004
|
async function certify(opts) {
|
|
33877
34005
|
const providerUrl = opts.providerUrl || opts.config.provider.baseUrl;
|
|
33878
|
-
const { scenarios, errors: errors2 } = loadScenarios(
|
|
34006
|
+
const { scenarios, errors: errors2 } = loadScenarios(join49(opts.projectDir, ".mma", "certification", "scenarios"));
|
|
33879
34007
|
for (const e of errors2)
|
|
33880
34008
|
console.error(pc2.yellow(` ${e}`));
|
|
33881
34009
|
let selected = filterByTags(scenarios, opts.tags);
|
|
@@ -33906,7 +34034,7 @@ async function certify(opts) {
|
|
|
33906
34034
|
return;
|
|
33907
34035
|
}
|
|
33908
34036
|
console.log(t("cli.cert_started", { model: opts.name, provider: providerUrl }));
|
|
33909
|
-
const sandboxBase =
|
|
34037
|
+
const sandboxBase = join49(process.cwd(), ".mma", "certification");
|
|
33910
34038
|
const results = [];
|
|
33911
34039
|
const total = selected.length;
|
|
33912
34040
|
let idx = 0;
|
|
@@ -34039,10 +34167,10 @@ function printResults(results) {
|
|
|
34039
34167
|
}
|
|
34040
34168
|
}
|
|
34041
34169
|
function writeReport(entry, projectDir) {
|
|
34042
|
-
const reportDir =
|
|
34170
|
+
const reportDir = join49(projectDir, "certification");
|
|
34043
34171
|
const ts = entry.certifiedAt.replace(/[:.]/g, "-").slice(0, 19);
|
|
34044
34172
|
const filename = `report-${entry.model.replace(/[/\\:]/g, "_")}-${ts}.json`;
|
|
34045
|
-
const reportPath =
|
|
34173
|
+
const reportPath = join49(reportDir, filename);
|
|
34046
34174
|
const report = {
|
|
34047
34175
|
model: entry.model,
|
|
34048
34176
|
providerUrl: entry.providerUrl,
|
|
@@ -34061,7 +34189,7 @@ function writeReport(entry, projectDir) {
|
|
|
34061
34189
|
}))
|
|
34062
34190
|
};
|
|
34063
34191
|
try {
|
|
34064
|
-
|
|
34192
|
+
writeFileSync22(reportPath, JSON.stringify(report, null, 2), "utf-8");
|
|
34065
34193
|
console.log(pc2.dim(`
|
|
34066
34194
|
Report: ${reportPath}`));
|
|
34067
34195
|
} catch (e) {
|
|
@@ -34075,7 +34203,7 @@ var init_cli = __esm(() => {
|
|
|
34075
34203
|
init_loader3();
|
|
34076
34204
|
init_runner2();
|
|
34077
34205
|
init_manifest();
|
|
34078
|
-
HERE =
|
|
34206
|
+
HERE = dirname22(fileURLToPath5(import.meta.url));
|
|
34079
34207
|
MMA_ROOT = findMmaRoot(HERE);
|
|
34080
34208
|
});
|
|
34081
34209
|
|
|
@@ -34085,8 +34213,8 @@ __export(exports_repl_commands, {
|
|
|
34085
34213
|
registerAllCommands: () => registerAllCommands,
|
|
34086
34214
|
COMMAND_GROUPS: () => COMMAND_GROUPS
|
|
34087
34215
|
});
|
|
34088
|
-
import { join as
|
|
34089
|
-
import { existsSync as
|
|
34216
|
+
import { join as join51, dirname as dirname24 } from "path";
|
|
34217
|
+
import { existsSync as existsSync58 } from "fs";
|
|
34090
34218
|
function registerAllCommands(ctx) {
|
|
34091
34219
|
registerBuiltinCommands(ctx);
|
|
34092
34220
|
registerMmaCommands(ctx);
|
|
@@ -34143,7 +34271,7 @@ function registerMmaCommands(ctx) {
|
|
|
34143
34271
|
}
|
|
34144
34272
|
try {
|
|
34145
34273
|
const { loadFileAsDataUrl: loadFileAsDataUrl2, loadUrlAsDataUrl: loadUrlAsDataUrl2, readClipboardImage: readClipboardImage2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
|
|
34146
|
-
const { existsSync:
|
|
34274
|
+
const { existsSync: existsSync59 } = await import("fs");
|
|
34147
34275
|
const { resolve: resolve24 } = await import("path");
|
|
34148
34276
|
let dataUrl;
|
|
34149
34277
|
let label;
|
|
@@ -34163,7 +34291,7 @@ function registerMmaCommands(ctx) {
|
|
|
34163
34291
|
label = source;
|
|
34164
34292
|
} else {
|
|
34165
34293
|
const absPath = resolve24(process.cwd(), source);
|
|
34166
|
-
if (!
|
|
34294
|
+
if (!existsSync59(absPath)) {
|
|
34167
34295
|
console.log(pc2.red(t("image.not_found", { path: source })));
|
|
34168
34296
|
return;
|
|
34169
34297
|
}
|
|
@@ -34266,7 +34394,7 @@ function registerMmaCommands(ctx) {
|
|
|
34266
34394
|
console.log(pc2.yellow(t("repl.wizard_running")));
|
|
34267
34395
|
await ctx.withExclusiveInput(async () => {
|
|
34268
34396
|
const answers = await runSetup(ctx.rl);
|
|
34269
|
-
const configPath =
|
|
34397
|
+
const configPath = join51(ctx.configDir, "config.json");
|
|
34270
34398
|
ctx.config.provider.type = answers.provider;
|
|
34271
34399
|
ctx.config.provider.baseUrl = answers.apiBase;
|
|
34272
34400
|
ctx.config.provider.apiKey = answers.apiKey;
|
|
@@ -34274,7 +34402,7 @@ function registerMmaCommands(ctx) {
|
|
|
34274
34402
|
ctx.config.contextWindow = answers.contextWindow;
|
|
34275
34403
|
ctx.config.maxToolIterations = answers.maxToolIterations;
|
|
34276
34404
|
ctx.config.locale = answers.locale;
|
|
34277
|
-
saveConfig(ctx.config, configPath,
|
|
34405
|
+
saveConfig(ctx.config, configPath, dirname24(configPath));
|
|
34278
34406
|
await ctx.agent.reconfigure(ctx.config);
|
|
34279
34407
|
console.log(pc2.green(t("cli.config_saved")));
|
|
34280
34408
|
});
|
|
@@ -34388,8 +34516,8 @@ function registerMmaCommands(ctx) {
|
|
|
34388
34516
|
return;
|
|
34389
34517
|
}
|
|
34390
34518
|
ctx.config.model = name;
|
|
34391
|
-
const configPath =
|
|
34392
|
-
saveConfig(ctx.config, configPath,
|
|
34519
|
+
const configPath = join51(ctx.configDir, "config.json");
|
|
34520
|
+
saveConfig(ctx.config, configPath, dirname24(configPath));
|
|
34393
34521
|
await ctx.agent.reconfigure(ctx.config);
|
|
34394
34522
|
console.log(pc2.green(t("repl.model_set", { name })));
|
|
34395
34523
|
return;
|
|
@@ -34413,8 +34541,8 @@ function registerMmaCommands(ctx) {
|
|
|
34413
34541
|
return;
|
|
34414
34542
|
}
|
|
34415
34543
|
ctx.config.contextWindow = size;
|
|
34416
|
-
const configPath =
|
|
34417
|
-
saveConfig(ctx.config, configPath,
|
|
34544
|
+
const configPath = join51(ctx.configDir, "config.json");
|
|
34545
|
+
saveConfig(ctx.config, configPath, dirname24(configPath));
|
|
34418
34546
|
await ctx.agent.reconfigure(ctx.config);
|
|
34419
34547
|
console.log(pc2.green(t("cli.context_set", { size })));
|
|
34420
34548
|
}
|
|
@@ -34428,10 +34556,10 @@ function registerMmaCommands(ctx) {
|
|
|
34428
34556
|
if (ctx.sessionManager && ctx.config.session.autoSave) {}
|
|
34429
34557
|
ctx.agent.shutdown();
|
|
34430
34558
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
34431
|
-
const { join:
|
|
34559
|
+
const { join: join52 } = await import("path");
|
|
34432
34560
|
const configDir = ctx.configDir;
|
|
34433
34561
|
const baseDir = ctx.baseDir;
|
|
34434
|
-
const projectConfigPath =
|
|
34562
|
+
const projectConfigPath = join52(baseDir, ".mmrc");
|
|
34435
34563
|
const { config: freshConfig } = loadConfig2({ configDir, projectConfigPath });
|
|
34436
34564
|
Object.assign(ctx.config, freshConfig);
|
|
34437
34565
|
const { bootstrap: bootstrap2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
|
|
@@ -34785,21 +34913,21 @@ async function runConfigMigrate(ctx) {
|
|
|
34785
34913
|
const { hasDomainFiles: hasDomainFiles3 } = await Promise.resolve().then(() => (init_domains(), exports_domains));
|
|
34786
34914
|
const { loadConfig: loadCfg } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
34787
34915
|
const configDir = ctx.configDir;
|
|
34788
|
-
const configPath =
|
|
34916
|
+
const configPath = join51(configDir, "config.json");
|
|
34789
34917
|
if (hasDomainFiles3(configDir)) {
|
|
34790
34918
|
console.log(pc2.yellow(t("config.migrate_no_legacy")));
|
|
34791
34919
|
return;
|
|
34792
34920
|
}
|
|
34793
|
-
if (!
|
|
34921
|
+
if (!existsSync58(configPath)) {
|
|
34794
34922
|
console.log(pc2.yellow(t("config.migrate_no_legacy")));
|
|
34795
34923
|
return;
|
|
34796
34924
|
}
|
|
34797
34925
|
console.log(t("config.migrate_start"));
|
|
34798
|
-
const { config } = loadCfg({ configDir, projectConfigPath:
|
|
34926
|
+
const { config } = loadCfg({ configDir, projectConfigPath: join51(configDir, ".mmrc") });
|
|
34799
34927
|
saveConfig(config, configPath, configDir);
|
|
34800
34928
|
const { renameSync: renameSync4, readdirSync: readdirSync19 } = await import("fs");
|
|
34801
34929
|
renameSync4(configPath, configPath + ".bak");
|
|
34802
|
-
const domainFiles = readdirSync19(
|
|
34930
|
+
const domainFiles = readdirSync19(join51(configDir, "config")).filter((f) => f.endsWith(".json"));
|
|
34803
34931
|
console.log(pc2.green(t("config.migrate_done", { count: String(domainFiles.length) })));
|
|
34804
34932
|
}
|
|
34805
34933
|
var version2, COMMAND_GROUPS;
|
|
@@ -34859,15 +34987,15 @@ init_config2();
|
|
|
34859
34987
|
init_setup();
|
|
34860
34988
|
init_i18n();
|
|
34861
34989
|
init_colors();
|
|
34862
|
-
import { join as
|
|
34863
|
-
import { homedir as
|
|
34864
|
-
import { existsSync as
|
|
34990
|
+
import { join as join50, dirname as dirname23 } from "path";
|
|
34991
|
+
import { homedir as homedir17 } from "os";
|
|
34992
|
+
import { existsSync as existsSync57 } from "fs";
|
|
34865
34993
|
|
|
34866
34994
|
// src/cli/security-commands.ts
|
|
34867
34995
|
init_bootstrap();
|
|
34868
34996
|
init_config2();
|
|
34869
|
-
import { join as
|
|
34870
|
-
import { homedir as
|
|
34997
|
+
import { join as join44, dirname as dirname19 } from "path";
|
|
34998
|
+
import { homedir as homedir16 } from "os";
|
|
34871
34999
|
|
|
34872
35000
|
// src/modules/security/security-policies.ts
|
|
34873
35001
|
init_security();
|
|
@@ -35392,7 +35520,7 @@ function createSecurityCommand(program2) {
|
|
|
35392
35520
|
}
|
|
35393
35521
|
});
|
|
35394
35522
|
securityCmd.command("set-policy").argument("<preset>", t("cli.security.preset")).description(t("cli.security.set_policy")).action(async (preset) => {
|
|
35395
|
-
const configPath =
|
|
35523
|
+
const configPath = join44(homedir16(), ".mma", "config.json");
|
|
35396
35524
|
const { config: appConfig } = await bootstrap();
|
|
35397
35525
|
const validPresets = ["strict", "balanced", "permissive"];
|
|
35398
35526
|
if (!validPresets.includes(preset)) {
|
|
@@ -35402,40 +35530,40 @@ function createSecurityCommand(program2) {
|
|
|
35402
35530
|
const policy = getSecurityPolicy(preset);
|
|
35403
35531
|
const newSecurityConfig = applySecurityPolicy(preset);
|
|
35404
35532
|
appConfig.security = newSecurityConfig;
|
|
35405
|
-
saveConfig(appConfig, configPath,
|
|
35533
|
+
saveConfig(appConfig, configPath, dirname19(configPath));
|
|
35406
35534
|
console.log(t("cli.security.policy_applied", { name: policy.name }));
|
|
35407
35535
|
console.log(t("cli.security.policy_description", { description: policy.description }));
|
|
35408
35536
|
});
|
|
35409
35537
|
securityCmd.command("enable-encryption").description(t("cli.security.enable_encryption")).action(async () => {
|
|
35410
|
-
const configPath =
|
|
35538
|
+
const configPath = join44(homedir16(), ".mma", "config.json");
|
|
35411
35539
|
const { config: appConfig } = await bootstrap();
|
|
35412
35540
|
const security = appConfig.security = appConfig.security || {};
|
|
35413
35541
|
toggleSessionEncryption(security, true);
|
|
35414
|
-
saveConfig(appConfig, configPath,
|
|
35542
|
+
saveConfig(appConfig, configPath, dirname19(configPath));
|
|
35415
35543
|
console.log(t("cli.security.encryption_enabled"));
|
|
35416
35544
|
});
|
|
35417
35545
|
securityCmd.command("disable-encryption").description(t("cli.security.disable_encryption")).action(async () => {
|
|
35418
|
-
const configPath =
|
|
35546
|
+
const configPath = join44(homedir16(), ".mma", "config.json");
|
|
35419
35547
|
const { config: appConfig } = await bootstrap();
|
|
35420
35548
|
const security = appConfig.security = appConfig.security || {};
|
|
35421
35549
|
toggleSessionEncryption(security, false);
|
|
35422
|
-
saveConfig(appConfig, configPath,
|
|
35550
|
+
saveConfig(appConfig, configPath, dirname19(configPath));
|
|
35423
35551
|
console.log(t("cli.security.encryption_disabled"));
|
|
35424
35552
|
});
|
|
35425
35553
|
securityCmd.command("enable-audit").description(t("cli.security.enable_audit")).action(async () => {
|
|
35426
|
-
const configPath =
|
|
35554
|
+
const configPath = join44(homedir16(), ".mma", "config.json");
|
|
35427
35555
|
const { config: appConfig } = await bootstrap();
|
|
35428
35556
|
const security = appConfig.security = appConfig.security || {};
|
|
35429
35557
|
toggleAuditNotifier(security, true);
|
|
35430
|
-
saveConfig(appConfig, configPath,
|
|
35558
|
+
saveConfig(appConfig, configPath, dirname19(configPath));
|
|
35431
35559
|
console.log(t("cli.security.audit_enabled"));
|
|
35432
35560
|
});
|
|
35433
35561
|
securityCmd.command("disable-audit").description(t("cli.security.disable_audit")).action(async () => {
|
|
35434
|
-
const configPath =
|
|
35562
|
+
const configPath = join44(homedir16(), ".mma", "config.json");
|
|
35435
35563
|
const { config: appConfig } = await bootstrap();
|
|
35436
35564
|
const security = appConfig.security = appConfig.security || {};
|
|
35437
35565
|
toggleAuditNotifier(security, false);
|
|
35438
|
-
saveConfig(appConfig, configPath,
|
|
35566
|
+
saveConfig(appConfig, configPath, dirname19(configPath));
|
|
35439
35567
|
console.log(t("cli.security.audit_disabled"));
|
|
35440
35568
|
});
|
|
35441
35569
|
securityCmd.command("audit-stats").description(t("cli.security.audit_stats")).action(async () => {
|
|
@@ -35494,27 +35622,27 @@ init_presets();
|
|
|
35494
35622
|
init_version();
|
|
35495
35623
|
|
|
35496
35624
|
// src/modules/updater/changelog-reader.ts
|
|
35497
|
-
import { readFileSync as
|
|
35498
|
-
import { dirname as
|
|
35625
|
+
import { readFileSync as readFileSync33, existsSync as existsSync52 } from "fs";
|
|
35626
|
+
import { dirname as dirname20, join as join45 } from "path";
|
|
35499
35627
|
function readChangelog(packageName) {
|
|
35500
35628
|
try {
|
|
35501
|
-
let dir =
|
|
35629
|
+
let dir = dirname20(import.meta.url);
|
|
35502
35630
|
if (dir.startsWith("file://")) {
|
|
35503
35631
|
dir = decodeURIComponent(dir.slice(7));
|
|
35504
35632
|
}
|
|
35505
35633
|
for (let i = 0;i < 10; i++) {
|
|
35506
|
-
const pkgPath =
|
|
35507
|
-
if (
|
|
35508
|
-
const pkg = JSON.parse(
|
|
35634
|
+
const pkgPath = join45(dir, "package.json");
|
|
35635
|
+
if (existsSync52(pkgPath)) {
|
|
35636
|
+
const pkg = JSON.parse(readFileSync33(pkgPath, "utf-8"));
|
|
35509
35637
|
if (pkg.name === packageName) {
|
|
35510
|
-
const changelogPath =
|
|
35511
|
-
if (
|
|
35512
|
-
return
|
|
35638
|
+
const changelogPath = join45(dir, "CHANGELOG.md");
|
|
35639
|
+
if (existsSync52(changelogPath)) {
|
|
35640
|
+
return readFileSync33(changelogPath, "utf-8");
|
|
35513
35641
|
}
|
|
35514
35642
|
return null;
|
|
35515
35643
|
}
|
|
35516
35644
|
}
|
|
35517
|
-
dir =
|
|
35645
|
+
dir = dirname20(dir);
|
|
35518
35646
|
}
|
|
35519
35647
|
return null;
|
|
35520
35648
|
} catch {
|
|
@@ -35577,7 +35705,7 @@ function createProgram() {
|
|
|
35577
35705
|
const program2 = new Command().name("mma").description(t("cli.description")).version(version).option("--no-agents-md", t("cli.no_agents_md")).option("-d, --dir <path>", t("cli.dir")).option("-e, --exit-on-complete", t("cli.exit_on_complete")).option("-j, --json", t("cli.json")).option("--reasoning <level>", t("cli.reasoning_level"), "auto");
|
|
35578
35706
|
program2.command("init").description(t("cli.init")).action(async () => {
|
|
35579
35707
|
const answers = await runSetup();
|
|
35580
|
-
const configPath =
|
|
35708
|
+
const configPath = join50(homedir17(), ".mma", "config.json");
|
|
35581
35709
|
const { config } = await bootstrap();
|
|
35582
35710
|
config.provider.type = answers.provider;
|
|
35583
35711
|
config.provider.baseUrl = answers.apiBase;
|
|
@@ -35617,12 +35745,12 @@ function createProgram() {
|
|
|
35617
35745
|
config.security.paths.denied = [];
|
|
35618
35746
|
}
|
|
35619
35747
|
}
|
|
35620
|
-
saveConfig(config, configPath,
|
|
35748
|
+
saveConfig(config, configPath, dirname23(configPath));
|
|
35621
35749
|
console.log(t("cli.config_saved"));
|
|
35622
35750
|
});
|
|
35623
35751
|
const configCmd = program2.command("config").description(t("cli.manage_config"));
|
|
35624
35752
|
configCmd.command("set").argument("<key>", t("cli.config_key")).argument("<value>", "Config value").description(t("cli.set_value")).action(async (key, value) => {
|
|
35625
|
-
const configPath =
|
|
35753
|
+
const configPath = join50(homedir17(), ".mma", "config.json");
|
|
35626
35754
|
const { config } = await bootstrap();
|
|
35627
35755
|
const keys = key.split(".");
|
|
35628
35756
|
let obj = config;
|
|
@@ -35642,7 +35770,7 @@ function createProgram() {
|
|
|
35642
35770
|
obj[lastKey] = parseFloat(value);
|
|
35643
35771
|
else
|
|
35644
35772
|
obj[lastKey] = value;
|
|
35645
|
-
saveConfig(config, configPath,
|
|
35773
|
+
saveConfig(config, configPath, dirname23(configPath));
|
|
35646
35774
|
console.log(t("cli.set_done", { key, value }));
|
|
35647
35775
|
});
|
|
35648
35776
|
configCmd.command("show").description(t("cli.show_config")).action(async () => {
|
|
@@ -35652,24 +35780,24 @@ function createProgram() {
|
|
|
35652
35780
|
configCmd.command("migrate").description(t("cli.migrate_config")).action(async () => {
|
|
35653
35781
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
35654
35782
|
const { hasDomainFiles: hasDomainFiles3 } = await Promise.resolve().then(() => (init_domains(), exports_domains));
|
|
35655
|
-
const configDir =
|
|
35656
|
-
const configPath =
|
|
35783
|
+
const configDir = join50(homedir17(), ".mma");
|
|
35784
|
+
const configPath = join50(configDir, "config.json");
|
|
35657
35785
|
if (hasDomainFiles3(configDir)) {
|
|
35658
35786
|
console.log(pc2.yellow(t("config.migrate_no_legacy")));
|
|
35659
35787
|
return;
|
|
35660
35788
|
}
|
|
35661
|
-
if (!
|
|
35789
|
+
if (!existsSync57(configPath)) {
|
|
35662
35790
|
console.log(pc2.yellow(t("config.migrate_no_legacy")));
|
|
35663
35791
|
return;
|
|
35664
35792
|
}
|
|
35665
35793
|
console.log(t("config.migrate_start"));
|
|
35666
|
-
const { config } = loadConfig2({ configDir, projectConfigPath:
|
|
35794
|
+
const { config } = loadConfig2({ configDir, projectConfigPath: join50(configDir, ".mmrc") });
|
|
35667
35795
|
saveConfig(config, configPath, configDir);
|
|
35668
35796
|
const bakPath = configPath + ".bak";
|
|
35669
35797
|
const { renameSync: renameSync4 } = await import("fs");
|
|
35670
35798
|
renameSync4(configPath, bakPath);
|
|
35671
35799
|
const { readdirSync: readdirSync19 } = await import("fs");
|
|
35672
|
-
const domainFiles = readdirSync19(
|
|
35800
|
+
const domainFiles = readdirSync19(join50(configDir, "config")).filter((f) => f.endsWith(".json"));
|
|
35673
35801
|
console.log(pc2.green(t("config.migrate_done", { count: String(domainFiles.length) })));
|
|
35674
35802
|
});
|
|
35675
35803
|
const model = program2.command("model").description(t("cli.manage_models"));
|
|
@@ -35709,10 +35837,10 @@ function createProgram() {
|
|
|
35709
35837
|
console.log(t("cli.model_hint"));
|
|
35710
35838
|
});
|
|
35711
35839
|
model.command("use").argument("<name>", "Model name").description(t("cli.set_model")).action(async (name) => {
|
|
35712
|
-
const configPath =
|
|
35840
|
+
const configPath = join50(homedir17(), ".mma", "config.json");
|
|
35713
35841
|
const { config } = await bootstrap();
|
|
35714
35842
|
config.model = name;
|
|
35715
|
-
saveConfig(config, configPath,
|
|
35843
|
+
saveConfig(config, configPath, dirname23(configPath));
|
|
35716
35844
|
console.log(t("cli.model_set", { name }));
|
|
35717
35845
|
});
|
|
35718
35846
|
model.command("certify").argument("<name>", "Model name").option("--provider-url <url>", t("cli.cert_provider_url")).option("--provider-key <key>", t("cli.cert_provider_key")).option("--context-window <n>", t("cli.cert_context_window")).option("--tags <tags>", t("cli.cert_tags"), "core").option("--scenarios <ids>", t("cli.cert_scenarios")).option("--timeout <ms>", t("cli.cert_timeout")).option("--reps <n>", t("cli.cert_reps")).option("--force", t("cli.cert_force")).option("--clean", t("cli.cert_clean")).description(t("cli.certify")).action(async (name, cmdOpts) => {
|
|
@@ -35748,7 +35876,7 @@ function createProgram() {
|
|
|
35748
35876
|
await uncertify2(name, config, process.cwd());
|
|
35749
35877
|
});
|
|
35750
35878
|
program2.command("context").description(t("cli.manage_context")).argument("<size>", "Context window size in tokens").action(async (size) => {
|
|
35751
|
-
const configPath =
|
|
35879
|
+
const configPath = join50(homedir17(), ".mma", "config.json");
|
|
35752
35880
|
const { config } = await bootstrap();
|
|
35753
35881
|
const contextWindow = parseInt(size, 10);
|
|
35754
35882
|
if (isNaN(contextWindow) || contextWindow < 1024) {
|
|
@@ -35756,7 +35884,7 @@ function createProgram() {
|
|
|
35756
35884
|
return;
|
|
35757
35885
|
}
|
|
35758
35886
|
config.contextWindow = contextWindow;
|
|
35759
|
-
saveConfig(config, configPath,
|
|
35887
|
+
saveConfig(config, configPath, dirname23(configPath));
|
|
35760
35888
|
console.log(t("cli.context_set", { size: contextWindow }));
|
|
35761
35889
|
});
|
|
35762
35890
|
const provider = program2.command("provider").description(t("cli.manage_providers"));
|
|
@@ -35794,7 +35922,7 @@ function createProgram() {
|
|
|
35794
35922
|
console.log(t("cli.base_url"), config.provider.baseUrl);
|
|
35795
35923
|
});
|
|
35796
35924
|
provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
|
|
35797
|
-
const configPath =
|
|
35925
|
+
const configPath = join50(homedir17(), ".mma", "config.json");
|
|
35798
35926
|
const { config, agent } = await bootstrap();
|
|
35799
35927
|
if (config.provider.entries && config.provider.entries.length > 0) {
|
|
35800
35928
|
try {
|
|
@@ -35810,14 +35938,14 @@ function createProgram() {
|
|
|
35810
35938
|
if (baseUrl) {
|
|
35811
35939
|
config.provider.baseUrl = baseUrl;
|
|
35812
35940
|
}
|
|
35813
|
-
saveConfig(config, configPath,
|
|
35941
|
+
saveConfig(config, configPath, dirname23(configPath));
|
|
35814
35942
|
console.log(t("cli.provider_set", { name }));
|
|
35815
35943
|
if (baseUrl) {
|
|
35816
35944
|
console.log(t("cli.provider_base_hint", { baseUrl }));
|
|
35817
35945
|
}
|
|
35818
35946
|
});
|
|
35819
35947
|
provider.command("add").argument("<name>", "Provider type or label").option("--url <url>", "Base URL").option("--key <key>", "API key").option("--priority <n>", "Fallback priority (lower = tried first)").option("--context-window <n>", "Context window override for this entry").option("--rpm <n>", "Max requests per minute for this entry").option("--parallel <n>", "Max parallel tasks for this entry").description(t("cli.add_provider")).action(async (name, opts) => {
|
|
35820
|
-
const configPath =
|
|
35948
|
+
const configPath = join50(homedir17(), ".mma", "config.json");
|
|
35821
35949
|
const { config } = await bootstrap();
|
|
35822
35950
|
const entries = Array.isArray(config.provider.entries) ? config.provider.entries : [];
|
|
35823
35951
|
if (entries.length === 0) {
|
|
@@ -35849,7 +35977,7 @@ function createProgram() {
|
|
|
35849
35977
|
});
|
|
35850
35978
|
config.provider.entries = entries;
|
|
35851
35979
|
config.provider.active = config.provider.active || config.provider.type;
|
|
35852
|
-
saveConfig(config, configPath,
|
|
35980
|
+
saveConfig(config, configPath, dirname23(configPath));
|
|
35853
35981
|
console.log(pc2.green(t("cli.provider_added", { name })));
|
|
35854
35982
|
console.log(t("cli.provider_switch_hint"));
|
|
35855
35983
|
});
|
|
@@ -36791,9 +36919,9 @@ class LineEditor {
|
|
|
36791
36919
|
}
|
|
36792
36920
|
|
|
36793
36921
|
// src/cli/repl.ts
|
|
36794
|
-
import { existsSync as
|
|
36795
|
-
import { join as
|
|
36796
|
-
import { homedir as
|
|
36922
|
+
import { existsSync as existsSync59, readFileSync as readFileSync40, writeFileSync as writeFileSync23 } from "fs";
|
|
36923
|
+
import { join as join52 } from "path";
|
|
36924
|
+
import { homedir as homedir18 } from "os";
|
|
36797
36925
|
|
|
36798
36926
|
// src/cli/completer.ts
|
|
36799
36927
|
class SlashCommandProvider {
|
|
@@ -36979,9 +37107,12 @@ class FormattingStream {
|
|
|
36979
37107
|
codeLines = [];
|
|
36980
37108
|
tableBuffer = [];
|
|
36981
37109
|
onWrite;
|
|
37110
|
+
onRawWrite;
|
|
36982
37111
|
width;
|
|
36983
|
-
|
|
37112
|
+
partialWritten = 0;
|
|
37113
|
+
constructor(onWrite, width, onRawWrite) {
|
|
36984
37114
|
this.onWrite = onWrite;
|
|
37115
|
+
this.onRawWrite = onRawWrite ?? onWrite;
|
|
36985
37116
|
this.width = width ?? getTerminalWidth();
|
|
36986
37117
|
}
|
|
36987
37118
|
write(chunk) {
|
|
@@ -36991,8 +37122,20 @@ class FormattingStream {
|
|
|
36991
37122
|
`)) !== -1) {
|
|
36992
37123
|
const line = this.buffer.slice(0, idx);
|
|
36993
37124
|
this.buffer = this.buffer.slice(idx + 1);
|
|
37125
|
+
this.emitPartialRewind();
|
|
36994
37126
|
this.processLine(line);
|
|
36995
37127
|
}
|
|
37128
|
+
if (this.buffer.length > 0 && !this.inCodeBlock) {
|
|
37129
|
+
this.onRawWrite(this.buffer);
|
|
37130
|
+
this.partialWritten = this.buffer.length;
|
|
37131
|
+
this.buffer = "";
|
|
37132
|
+
}
|
|
37133
|
+
}
|
|
37134
|
+
emitPartialRewind() {
|
|
37135
|
+
if (this.partialWritten > 0) {
|
|
37136
|
+
this.onRawWrite(`\x1B[${this.partialWritten}D`);
|
|
37137
|
+
this.partialWritten = 0;
|
|
37138
|
+
}
|
|
36996
37139
|
}
|
|
36997
37140
|
flush() {
|
|
36998
37141
|
if (this.tableBuffer.length > 0) {
|
|
@@ -37129,7 +37272,6 @@ function formatWarning(text) {
|
|
|
37129
37272
|
|
|
37130
37273
|
// src/ui/renderer.ts
|
|
37131
37274
|
init_spinner();
|
|
37132
|
-
init_box();
|
|
37133
37275
|
init_table();
|
|
37134
37276
|
init_i18n();
|
|
37135
37277
|
init_prices();
|
|
@@ -37156,6 +37298,7 @@ function toDisplayPath(baseDir, p) {
|
|
|
37156
37298
|
return rel.split(sep2).join("/");
|
|
37157
37299
|
}
|
|
37158
37300
|
var GUTTER = " ";
|
|
37301
|
+
var MAX_OUTPUT_LINES = 50;
|
|
37159
37302
|
var BUSY_TOOLS = new Set(["lsp_check"]);
|
|
37160
37303
|
function toolMarker(tool) {
|
|
37161
37304
|
switch (tool) {
|
|
@@ -37207,15 +37350,19 @@ class Renderer {
|
|
|
37207
37350
|
out;
|
|
37208
37351
|
err;
|
|
37209
37352
|
width;
|
|
37210
|
-
toolStyle;
|
|
37211
37353
|
baseDir;
|
|
37212
37354
|
card = null;
|
|
37355
|
+
thoughtStarted = false;
|
|
37356
|
+
thoughtStartMs = 0;
|
|
37357
|
+
thoughtHeaderPrinted = false;
|
|
37358
|
+
textStarted = false;
|
|
37359
|
+
outputLineCount = 0;
|
|
37360
|
+
outputSuppressed = false;
|
|
37213
37361
|
constructor(opts = {}) {
|
|
37214
37362
|
this.rich = opts.rich ?? isRichTerminal();
|
|
37215
37363
|
this.out = opts.out ?? process.stdout;
|
|
37216
37364
|
this.err = opts.err ?? process.stderr;
|
|
37217
37365
|
this.width = opts.width ?? getTerminalWidth();
|
|
37218
|
-
this.toolStyle = opts.toolStyle ?? "inline";
|
|
37219
37366
|
this.baseDir = opts.baseDir;
|
|
37220
37367
|
this.spinner = new Spinner({
|
|
37221
37368
|
enabled: this.rich && (opts.spinner ?? true),
|
|
@@ -37223,21 +37370,32 @@ class Renderer {
|
|
|
37223
37370
|
width: this.width
|
|
37224
37371
|
});
|
|
37225
37372
|
this.fmt = new FormattingStream((line) => this.out.write(`${line}
|
|
37226
|
-
`), this.width);
|
|
37373
|
+
`), this.width, (text) => this.out.write(text));
|
|
37374
|
+
}
|
|
37375
|
+
showLoader() {
|
|
37376
|
+
this.spinner.start("thinking");
|
|
37227
37377
|
}
|
|
37228
37378
|
text(chunk) {
|
|
37229
37379
|
this.endCard();
|
|
37230
37380
|
this.spinner.stop();
|
|
37381
|
+
if (!this.textStarted) {
|
|
37382
|
+
this.textStarted = true;
|
|
37383
|
+
this.out.write(`
|
|
37384
|
+
${pc2.dim("-")} `);
|
|
37385
|
+
}
|
|
37231
37386
|
this.fmt.write(chunk);
|
|
37232
37387
|
}
|
|
37233
37388
|
meta(chunk) {
|
|
37234
37389
|
this.spinner.stop();
|
|
37235
|
-
if (this.
|
|
37236
|
-
if (this.
|
|
37237
|
-
this.
|
|
37238
|
-
|
|
37239
|
-
this.
|
|
37240
|
-
}
|
|
37390
|
+
if (this.thoughtStarted) {
|
|
37391
|
+
if (!this.thoughtHeaderPrinted) {
|
|
37392
|
+
this.out.write(`
|
|
37393
|
+
${pc2.dim("→")} Thought: `);
|
|
37394
|
+
this.thoughtHeaderPrinted = true;
|
|
37395
|
+
}
|
|
37396
|
+
this.out.write(pc2.dim(chunk));
|
|
37397
|
+
} else if (this.card) {
|
|
37398
|
+
this.writeInlineBody(chunk);
|
|
37241
37399
|
} else {
|
|
37242
37400
|
this.out.write(chunk);
|
|
37243
37401
|
}
|
|
@@ -37247,44 +37405,55 @@ class Renderer {
|
|
|
37247
37405
|
`)) {
|
|
37248
37406
|
if (line.trim() === "")
|
|
37249
37407
|
continue;
|
|
37408
|
+
this.outputLineCount++;
|
|
37409
|
+
if (this.outputLineCount > MAX_OUTPUT_LINES) {
|
|
37410
|
+
this.outputSuppressed = true;
|
|
37411
|
+
continue;
|
|
37412
|
+
}
|
|
37250
37413
|
this.out.write(`${GUTTER}${line}
|
|
37251
37414
|
`);
|
|
37252
37415
|
}
|
|
37253
37416
|
}
|
|
37254
37417
|
reasoning(chunk) {
|
|
37255
37418
|
this.spinner.stop();
|
|
37419
|
+
if (this.thoughtStarted && !this.thoughtHeaderPrinted) {
|
|
37420
|
+
this.out.write(`
|
|
37421
|
+
${pc2.dim("→")} Thought: `);
|
|
37422
|
+
this.thoughtHeaderPrinted = true;
|
|
37423
|
+
}
|
|
37256
37424
|
this.out.write(pc2.dim(chunk));
|
|
37257
37425
|
}
|
|
37258
37426
|
thinkingStart() {
|
|
37259
|
-
this.
|
|
37427
|
+
this.thoughtStarted = true;
|
|
37428
|
+
this.thoughtStartMs = Date.now();
|
|
37429
|
+
this.thoughtHeaderPrinted = false;
|
|
37260
37430
|
}
|
|
37261
37431
|
thinkingEnd() {
|
|
37262
37432
|
this.spinner.stop();
|
|
37433
|
+
if (this.thoughtStarted && this.thoughtHeaderPrinted) {
|
|
37434
|
+
const duration = Date.now() - this.thoughtStartMs;
|
|
37435
|
+
this.out.write(pc2.dim(` ${duration}ms
|
|
37436
|
+
`));
|
|
37437
|
+
}
|
|
37438
|
+
this.thoughtStarted = false;
|
|
37439
|
+
this.thoughtHeaderPrinted = false;
|
|
37263
37440
|
}
|
|
37264
37441
|
toolStart(tool, args, stepContext, icon) {
|
|
37265
37442
|
this.endCard();
|
|
37266
37443
|
this.spinner.stop();
|
|
37444
|
+
this.outputLineCount = 0;
|
|
37445
|
+
this.outputSuppressed = false;
|
|
37267
37446
|
const displayArgs = PATH_TOOLS.has(tool) && typeof args.path === "string" ? { ...args, path: toDisplayPath(this.baseDir, args.path) } : args;
|
|
37268
37447
|
const summary = summarizeArgs2(displayArgs);
|
|
37269
|
-
const step = stepContext ? ` ${pc2.cyan(`← ${stepContext}`)}` : "";
|
|
37270
37448
|
const marker = icon || toolMarker(tool);
|
|
37271
|
-
|
|
37449
|
+
this.card = { tool, args, start: Date.now() };
|
|
37450
|
+
if (stepContext) {
|
|
37272
37451
|
this.out.write(`
|
|
37273
|
-
${pc2.dim(
|
|
37452
|
+
${pc2.dim("↓")} ${pc2.cyan(stepContext)}
|
|
37274
37453
|
`);
|
|
37275
|
-
return;
|
|
37276
37454
|
}
|
|
37277
|
-
this.
|
|
37278
|
-
if (this.toolStyle === "inline") {
|
|
37279
|
-
this.out.write(`
|
|
37280
|
-
${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}${step}
|
|
37455
|
+
this.out.write(`${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
37281
37456
|
`);
|
|
37282
|
-
if (BUSY_TOOLS.has(tool)) {
|
|
37283
|
-
this.spinner.start(t("ui.tool_running", { tool: friendlyTool(tool) }));
|
|
37284
|
-
}
|
|
37285
|
-
return;
|
|
37286
|
-
}
|
|
37287
|
-
this.spinner.start(`${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}${step}`);
|
|
37288
37457
|
}
|
|
37289
37458
|
planBlock(lines) {
|
|
37290
37459
|
this.endCard();
|
|
@@ -37294,30 +37463,12 @@ ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
|
37294
37463
|
`);
|
|
37295
37464
|
}
|
|
37296
37465
|
}
|
|
37297
|
-
toolEnd(_tool, duration, error, ctxDelta, costUsd
|
|
37466
|
+
toolEnd(_tool, duration, error, ctxDelta, costUsd) {
|
|
37298
37467
|
this.spinner.stop();
|
|
37299
|
-
const prov = provider && model ? `${pc2.dim(`${provider}·${model}`)}` : undefined;
|
|
37300
|
-
if (!this.rich) {
|
|
37301
|
-
const parts = [];
|
|
37302
|
-
if (ctxDelta !== undefined && ctxDelta !== 0) {
|
|
37303
|
-
const deltaStr = ctxDelta > 0 ? pc2.green(`+${ctxDelta}`) : pc2.yellow(`${ctxDelta} ↓`);
|
|
37304
|
-
parts.push(`${pc2.dim("ctx")} ${deltaStr}`);
|
|
37305
|
-
}
|
|
37306
|
-
if (costUsd !== undefined && costUsd > 0) {
|
|
37307
|
-
parts.push(`${pc2.dim("cost")} ${pc2.yellow(formatUsd(costUsd))}`);
|
|
37308
|
-
}
|
|
37309
|
-
if (prov)
|
|
37310
|
-
parts.push(prov);
|
|
37311
|
-
if (parts.length > 0)
|
|
37312
|
-
this.out.write(`${parts.join(" ")}
|
|
37313
|
-
`);
|
|
37314
|
-
return;
|
|
37315
|
-
}
|
|
37316
37468
|
if (!this.card)
|
|
37317
37469
|
return;
|
|
37318
|
-
const { tool, args, body } = this.card;
|
|
37319
37470
|
const marker = error ? pc2.red("✗") : pc2.green("✓");
|
|
37320
|
-
let footer = `${marker} ${pc2.dim(`${duration}ms`)}`;
|
|
37471
|
+
let footer = `${GUTTER}${marker} ${pc2.dim(`${duration}ms`)}`;
|
|
37321
37472
|
if (ctxDelta !== undefined && ctxDelta !== 0) {
|
|
37322
37473
|
const deltaStr = ctxDelta > 0 ? pc2.green(`+${ctxDelta}`) : pc2.yellow(`${ctxDelta} ↓`);
|
|
37323
37474
|
footer += ` ${pc2.dim("ctx")} ${deltaStr}`;
|
|
@@ -37325,32 +37476,10 @@ ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
|
37325
37476
|
if (costUsd !== undefined && costUsd > 0) {
|
|
37326
37477
|
footer += ` ${pc2.dim("cost")} ${pc2.yellow(formatUsd(costUsd))}`;
|
|
37327
37478
|
}
|
|
37328
|
-
|
|
37329
|
-
footer += ` ${pc2.dim("via")} ${prov}`;
|
|
37330
|
-
}
|
|
37331
|
-
if (this.toolStyle === "inline") {
|
|
37332
|
-
this.out.write(`${GUTTER}${footer}
|
|
37479
|
+
this.out.write(`${footer}
|
|
37333
37480
|
`);
|
|
37334
|
-
|
|
37335
|
-
`)
|
|
37336
|
-
this.card = null;
|
|
37337
|
-
return;
|
|
37338
|
-
}
|
|
37339
|
-
const lines = [];
|
|
37340
|
-
const summary = summarizeArgs2(args);
|
|
37341
|
-
if (summary)
|
|
37342
|
-
lines.push(pc2.dim(summary));
|
|
37343
|
-
for (const chunk of body) {
|
|
37344
|
-
for (const line of chunk.split(`
|
|
37345
|
-
`)) {
|
|
37346
|
-
if (line.trim() !== "")
|
|
37347
|
-
lines.push(line);
|
|
37348
|
-
}
|
|
37349
|
-
}
|
|
37350
|
-
lines.push(footer);
|
|
37351
|
-
const title = `${marker} ${friendlyTool(tool)}`;
|
|
37352
|
-
for (const line of box(lines, { title, width: this.width })) {
|
|
37353
|
-
this.out.write(`${line}
|
|
37481
|
+
if (this.outputSuppressed) {
|
|
37482
|
+
this.out.write(`${GUTTER}${pc2.dim(`... (${this.outputLineCount - MAX_OUTPUT_LINES} more lines)`)}
|
|
37354
37483
|
`);
|
|
37355
37484
|
}
|
|
37356
37485
|
this.card = null;
|
|
@@ -37370,6 +37499,12 @@ ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
|
37370
37499
|
this.endCard();
|
|
37371
37500
|
this.spinner.stop();
|
|
37372
37501
|
this.fmt.flush();
|
|
37502
|
+
this.textStarted = false;
|
|
37503
|
+
}
|
|
37504
|
+
footer(model, provider, durationMs) {
|
|
37505
|
+
this.out.write(`
|
|
37506
|
+
${pc2.dim("▣")} ${model} · ${provider} · ${pc2.dim(`${durationMs}ms`)}
|
|
37507
|
+
`);
|
|
37373
37508
|
}
|
|
37374
37509
|
endCard() {
|
|
37375
37510
|
if (!this.card)
|
|
@@ -37523,20 +37658,16 @@ function stepContextForTool(plan, tool, args) {
|
|
|
37523
37658
|
const argStr = JSON.stringify(args);
|
|
37524
37659
|
const callPaths = extractFileLikeTokens(stripUrls(argStr)).map((p) => p.toLowerCase());
|
|
37525
37660
|
if (callPaths.length > 0) {
|
|
37526
|
-
for (const
|
|
37527
|
-
if (
|
|
37661
|
+
for (const step of plan.steps) {
|
|
37662
|
+
if (step.status === "done" || step.status === "skipped")
|
|
37528
37663
|
continue;
|
|
37529
|
-
const stepPaths = extractFileLikeTokens(stripUrls(
|
|
37664
|
+
const stepPaths = extractFileLikeTokens(stripUrls(step.description)).map((p) => p.toLowerCase());
|
|
37530
37665
|
if (stepPaths.length > 0 && stepPaths.some((s) => callPaths.some((c) => c.includes(s) || s.includes(c)))) {
|
|
37531
|
-
return t("ui.step_context", { id:
|
|
37666
|
+
return t("ui.step_context", { id: step.id, desc: truncate4(step.description) });
|
|
37532
37667
|
}
|
|
37533
37668
|
}
|
|
37534
37669
|
}
|
|
37535
|
-
|
|
37536
|
-
const step = plan.steps[cur];
|
|
37537
|
-
if (!step)
|
|
37538
|
-
return null;
|
|
37539
|
-
return t("ui.step_context", { id: step.id, desc: truncate4(step.description) });
|
|
37670
|
+
return null;
|
|
37540
37671
|
}
|
|
37541
37672
|
|
|
37542
37673
|
// src/cli/repl.ts
|
|
@@ -37619,10 +37750,10 @@ class Repl {
|
|
|
37619
37750
|
this.envReport = envReport;
|
|
37620
37751
|
this.execModule = execModule;
|
|
37621
37752
|
this.slog = new SessionLogger(sessionManager, logger4);
|
|
37622
|
-
this.configDir = configDir ||
|
|
37753
|
+
this.configDir = configDir || join52(homedir18(), ".mma");
|
|
37623
37754
|
this.baseDir = baseDir || process.cwd();
|
|
37624
37755
|
this.noAgentsMd = noAgentsMd === true;
|
|
37625
|
-
this.historyPath = historyPath ??
|
|
37756
|
+
this.historyPath = historyPath ?? join52(homedir18(), ".mma", "repl-history");
|
|
37626
37757
|
this.loadHistory();
|
|
37627
37758
|
this.rl = process.stdin.isTTY ? new LineEditor({
|
|
37628
37759
|
input: process.stdin,
|
|
@@ -37674,9 +37805,9 @@ class Repl {
|
|
|
37674
37805
|
}));
|
|
37675
37806
|
}
|
|
37676
37807
|
loadHistory() {
|
|
37677
|
-
if (
|
|
37808
|
+
if (existsSync59(this.historyPath)) {
|
|
37678
37809
|
try {
|
|
37679
|
-
const raw =
|
|
37810
|
+
const raw = readFileSync40(this.historyPath, "utf-8");
|
|
37680
37811
|
this.history = raw.split(`
|
|
37681
37812
|
`).filter(Boolean).slice(-this.maxHistory);
|
|
37682
37813
|
} catch {
|
|
@@ -37686,7 +37817,7 @@ class Repl {
|
|
|
37686
37817
|
}
|
|
37687
37818
|
saveHistory() {
|
|
37688
37819
|
const allHistory = this.history.slice(-this.maxHistory);
|
|
37689
|
-
|
|
37820
|
+
writeFileSync23(this.historyPath, allHistory.join(`
|
|
37690
37821
|
`), "utf-8");
|
|
37691
37822
|
}
|
|
37692
37823
|
setupCompleter() {
|
|
@@ -37903,14 +38034,14 @@ ${t("image.clipboard_empty")}`));
|
|
|
37903
38034
|
` + pc2.green(t("repl.agent")));
|
|
37904
38035
|
const renderer = new Renderer({
|
|
37905
38036
|
spinner: this.config.ui?.spinner ?? true,
|
|
37906
|
-
toolStyle: this.config.ui?.toolStyle ?? "inline",
|
|
37907
38037
|
baseDir: this.baseDir
|
|
37908
38038
|
});
|
|
38039
|
+
renderer.showLoader();
|
|
37909
38040
|
const result = await this.agent.run(input, (c) => renderer.text(c), (m) => renderer.meta(m), (ev) => {
|
|
37910
38041
|
if (ev.type === "start") {
|
|
37911
38042
|
renderer.toolStart(ev.tool, ev.args, stepContextForTool(this.execModule?.getActivePlan() ?? null, ev.tool, ev.args), ev.icon);
|
|
37912
38043
|
} else {
|
|
37913
|
-
renderer.toolEnd(ev.tool, ev.duration ?? 0, ev.error, ev.ctxDelta, ev.costUsd
|
|
38044
|
+
renderer.toolEnd(ev.tool, ev.duration ?? 0, ev.error, ev.ctxDelta, ev.costUsd);
|
|
37914
38045
|
if (ev.tool === "plan" || ev.tool === "todo") {
|
|
37915
38046
|
this.renderPlan(renderer);
|
|
37916
38047
|
}
|
|
@@ -37923,6 +38054,9 @@ ${t("image.clipboard_empty")}`));
|
|
|
37923
38054
|
}
|
|
37924
38055
|
});
|
|
37925
38056
|
renderer.flush();
|
|
38057
|
+
if (result.provider && result.model) {
|
|
38058
|
+
renderer.footer(result.model, result.provider, result.llmDurationMs ?? result.durationMs ?? 0);
|
|
38059
|
+
}
|
|
37926
38060
|
process.stdout.write(`
|
|
37927
38061
|
`);
|
|
37928
38062
|
this.logger?.logREPL(result.success ? "assistant" : "system", result.text?.slice(0, 400) || result.error || "");
|
|
@@ -38074,11 +38208,11 @@ ${t("image.clipboard_empty")}`));
|
|
|
38074
38208
|
row(t("repl.agents_label"), pc2.red(t("repl.disabled")));
|
|
38075
38209
|
} else {
|
|
38076
38210
|
const agentsMdCandidates = [
|
|
38077
|
-
|
|
38078
|
-
|
|
38079
|
-
|
|
38211
|
+
join52(this.baseDir, "AGENTS.md"),
|
|
38212
|
+
join52(this.baseDir, ".mma", "AGENTS.md"),
|
|
38213
|
+
join52(this.configDir, "AGENTS.md")
|
|
38080
38214
|
];
|
|
38081
|
-
const foundAgents = agentsMdCandidates.filter((p) =>
|
|
38215
|
+
const foundAgents = agentsMdCandidates.filter((p) => existsSync59(p));
|
|
38082
38216
|
if (foundAgents.length > 0) {
|
|
38083
38217
|
for (const p of foundAgents) {
|
|
38084
38218
|
row(t("repl.agents_label"), pc2.dim(p));
|
|
@@ -38089,7 +38223,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
38089
38223
|
}
|
|
38090
38224
|
const meta = this.sessionManager?.getActiveMeta();
|
|
38091
38225
|
if (meta) {
|
|
38092
|
-
const sessionPath =
|
|
38226
|
+
const sessionPath = join52(this.configDir, "sessions", meta.id);
|
|
38093
38227
|
row(t("repl.session_label"), `${pc2.cyan(meta.name)} ${pc2.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc2.dim(sessionPath)}`);
|
|
38094
38228
|
}
|
|
38095
38229
|
const isTty2 = process.stdout.isTTY === true;
|
|
@@ -38204,9 +38338,9 @@ init_setup();
|
|
|
38204
38338
|
init_config2();
|
|
38205
38339
|
init_i18n();
|
|
38206
38340
|
init_colors();
|
|
38207
|
-
import { existsSync as
|
|
38208
|
-
import { join as
|
|
38209
|
-
import { homedir as
|
|
38341
|
+
import { existsSync as existsSync60 } from "fs";
|
|
38342
|
+
import { join as join54, dirname as dirname25 } from "path";
|
|
38343
|
+
import { homedir as homedir20 } from "os";
|
|
38210
38344
|
|
|
38211
38345
|
// src/modules/updater/index.ts
|
|
38212
38346
|
init_checker();
|
|
@@ -38318,10 +38452,10 @@ ${t("cli.changelog_title", { version: result.latest })}
|
|
|
38318
38452
|
init_environment();
|
|
38319
38453
|
init_data_sanitizer();
|
|
38320
38454
|
init_i18n();
|
|
38321
|
-
import { appendFileSync as appendFileSync7, mkdirSync as
|
|
38322
|
-
import { join as
|
|
38323
|
-
import { homedir as
|
|
38324
|
-
var CRASH_LOG_DIR =
|
|
38455
|
+
import { appendFileSync as appendFileSync7, mkdirSync as mkdirSync22 } from "fs";
|
|
38456
|
+
import { join as join53 } from "path";
|
|
38457
|
+
import { homedir as homedir19 } from "os";
|
|
38458
|
+
var CRASH_LOG_DIR = join53(homedir19(), ".mma", "logs");
|
|
38325
38459
|
var CRASH_LOG_FILE = "crash.jsonl";
|
|
38326
38460
|
function formatCrashEntry(type2, err) {
|
|
38327
38461
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -38331,13 +38465,13 @@ function formatCrashEntry(type2, err) {
|
|
|
38331
38465
|
type: type2,
|
|
38332
38466
|
message: sanitizeLogMessage(message),
|
|
38333
38467
|
stack: sanitizeLogMessage(stack),
|
|
38334
|
-
environment: collectEnvironment({ configDir:
|
|
38468
|
+
environment: collectEnvironment({ configDir: homedir19(), scanTools: false })
|
|
38335
38469
|
};
|
|
38336
38470
|
}
|
|
38337
38471
|
function writeCrashEntry(dir, entry) {
|
|
38338
38472
|
try {
|
|
38339
|
-
|
|
38340
|
-
appendFileSync7(
|
|
38473
|
+
mkdirSync22(dir, { recursive: true });
|
|
38474
|
+
appendFileSync7(join53(dir, CRASH_LOG_FILE), JSON.stringify(entry) + `
|
|
38341
38475
|
`, "utf-8");
|
|
38342
38476
|
} catch {}
|
|
38343
38477
|
}
|
|
@@ -38419,14 +38553,14 @@ async function main() {
|
|
|
38419
38553
|
}, null, 2));
|
|
38420
38554
|
process.stdout.write(`
|
|
38421
38555
|
`);
|
|
38422
|
-
await updater?.waitForIdle();
|
|
38556
|
+
await updater?.waitForIdle(1e4);
|
|
38423
38557
|
process.exit(result2.success ? 0 : 1);
|
|
38424
38558
|
}
|
|
38425
38559
|
const renderer = new Renderer({
|
|
38426
38560
|
spinner: config.ui?.spinner ?? true,
|
|
38427
|
-
toolStyle: config.ui?.toolStyle ?? "inline",
|
|
38428
38561
|
baseDir
|
|
38429
38562
|
});
|
|
38563
|
+
renderer.showLoader();
|
|
38430
38564
|
const result = await agent.run(prompt, (chunk) => renderer.text(chunk), (meta) => renderer.meta(meta), (ev) => {
|
|
38431
38565
|
if (ev.type === "start") {
|
|
38432
38566
|
renderer.toolStart(ev.tool, ev.args, undefined, ev.icon);
|
|
@@ -38441,14 +38575,17 @@ async function main() {
|
|
|
38441
38575
|
}
|
|
38442
38576
|
});
|
|
38443
38577
|
renderer.flush();
|
|
38578
|
+
if (result.provider && result.model) {
|
|
38579
|
+
renderer.footer(result.model, result.provider, result.llmDurationMs ?? result.durationMs ?? 0);
|
|
38580
|
+
}
|
|
38444
38581
|
const exitCode = printRunResult(result, () => renderer.flush());
|
|
38445
38582
|
agent.shutdown();
|
|
38446
38583
|
await updater?.waitForIdle();
|
|
38447
38584
|
process.exit(exitCode);
|
|
38448
38585
|
} else {
|
|
38449
|
-
const mmaDir =
|
|
38450
|
-
const legacyConfigPath =
|
|
38451
|
-
let hasAnyConfig =
|
|
38586
|
+
const mmaDir = join54(homedir20(), ".mma");
|
|
38587
|
+
const legacyConfigPath = join54(mmaDir, "config.json");
|
|
38588
|
+
let hasAnyConfig = existsSync60(legacyConfigPath);
|
|
38452
38589
|
if (!hasAnyConfig) {
|
|
38453
38590
|
try {
|
|
38454
38591
|
const { hasDomainFiles: hasDomainFiles3 } = await Promise.resolve().then(() => (init_domains(), exports_domains));
|
|
@@ -38511,7 +38648,7 @@ async function main() {
|
|
|
38511
38648
|
config.security.paths.denied = [];
|
|
38512
38649
|
}
|
|
38513
38650
|
}
|
|
38514
|
-
saveConfig(config, legacyConfigPath,
|
|
38651
|
+
saveConfig(config, legacyConfigPath, dirname25(legacyConfigPath));
|
|
38515
38652
|
await agent.reconfigure(config);
|
|
38516
38653
|
}
|
|
38517
38654
|
startAutoUpdate(config);
|