micro-models-agent 0.36.1 → 0.36.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +213 -22
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -7909,6 +7909,12 @@ var init_process_kill = __esm(() => {
|
|
|
7909
7909
|
});
|
|
7910
7910
|
|
|
7911
7911
|
// src/core/prompt-builder.ts
|
|
7912
|
+
function blockLabel(content) {
|
|
7913
|
+
const firstLine = content.split(`
|
|
7914
|
+
`)[0].trim();
|
|
7915
|
+
return firstLine.length > 70 ? firstLine.slice(0, 67) + "..." : firstLine;
|
|
7916
|
+
}
|
|
7917
|
+
|
|
7912
7918
|
class PromptBuilder {
|
|
7913
7919
|
blocks = [];
|
|
7914
7920
|
budget;
|
|
@@ -7937,24 +7943,41 @@ class PromptBuilder {
|
|
|
7937
7943
|
let usedTokens = 0;
|
|
7938
7944
|
const included = [];
|
|
7939
7945
|
const excluded = [];
|
|
7946
|
+
const blocks = [];
|
|
7940
7947
|
for (const block of essential) {
|
|
7941
7948
|
included.push(block.content);
|
|
7942
7949
|
usedTokens += block.estimatedTokens;
|
|
7950
|
+
blocks.push({
|
|
7951
|
+
label: blockLabel(block.content),
|
|
7952
|
+
priority: block.priority,
|
|
7953
|
+
essential: true,
|
|
7954
|
+
tokens: block.estimatedTokens,
|
|
7955
|
+
included: true
|
|
7956
|
+
});
|
|
7943
7957
|
}
|
|
7944
7958
|
for (const block of nonEssential) {
|
|
7945
7959
|
const tokens = block.estimatedTokens;
|
|
7946
|
-
|
|
7960
|
+
const fits = usedTokens + tokens <= this.budget;
|
|
7961
|
+
if (fits) {
|
|
7947
7962
|
included.push(block.content);
|
|
7948
7963
|
usedTokens += tokens;
|
|
7949
7964
|
} else {
|
|
7950
7965
|
excluded.push(block.content);
|
|
7951
7966
|
}
|
|
7967
|
+
blocks.push({
|
|
7968
|
+
label: blockLabel(block.content),
|
|
7969
|
+
priority: block.priority,
|
|
7970
|
+
essential: false,
|
|
7971
|
+
tokens,
|
|
7972
|
+
included: fits
|
|
7973
|
+
});
|
|
7952
7974
|
}
|
|
7953
7975
|
return {
|
|
7954
7976
|
prompt: included.join(`
|
|
7955
7977
|
|
|
7956
7978
|
`),
|
|
7957
|
-
excluded
|
|
7979
|
+
excluded,
|
|
7980
|
+
blocks
|
|
7958
7981
|
};
|
|
7959
7982
|
}
|
|
7960
7983
|
}
|
|
@@ -8078,14 +8101,54 @@ class SessionLogger {
|
|
|
8078
8101
|
iteration
|
|
8079
8102
|
});
|
|
8080
8103
|
}
|
|
8081
|
-
logCompaction(
|
|
8104
|
+
logCompaction(info) {
|
|
8082
8105
|
this.session?.appendLog({
|
|
8083
8106
|
ts: new Date().toISOString(),
|
|
8084
8107
|
type: "compaction",
|
|
8085
|
-
content,
|
|
8108
|
+
content: `${info.reason}, iteration ${info.iteration}`,
|
|
8109
|
+
iteration: info.iteration,
|
|
8110
|
+
reason: info.reason,
|
|
8111
|
+
tokensBefore: info.tokensBefore,
|
|
8112
|
+
tokensAfter: info.tokensAfter,
|
|
8113
|
+
qualityBefore: info.qualityBefore,
|
|
8114
|
+
qualityAfter: info.qualityAfter,
|
|
8115
|
+
messagesBefore: info.messagesBefore,
|
|
8116
|
+
messagesAfter: info.messagesAfter,
|
|
8117
|
+
removedTurns: info.removedTurns,
|
|
8118
|
+
keptTurns: info.keptTurns,
|
|
8119
|
+
summary: info.summary
|
|
8120
|
+
});
|
|
8121
|
+
}
|
|
8122
|
+
logContext(info) {
|
|
8123
|
+
this.session?.appendLog({
|
|
8124
|
+
ts: new Date().toISOString(),
|
|
8125
|
+
type: "context",
|
|
8126
|
+
content: info.kind === "start" ? "context snapshot at session start" : `context at iteration ${info.iteration}`,
|
|
8127
|
+
iteration: info.iteration,
|
|
8128
|
+
window: info.window,
|
|
8129
|
+
systemBudget: info.systemBudget,
|
|
8130
|
+
reserveBudget: info.reserveBudget,
|
|
8131
|
+
historyBudget: info.historyBudget,
|
|
8132
|
+
systemTokens: info.systemTokens,
|
|
8133
|
+
toolTokens: info.toolTokens,
|
|
8134
|
+
contextTokens: info.tokens,
|
|
8135
|
+
quality: info.quality,
|
|
8136
|
+
messageCount: info.messageCount,
|
|
8137
|
+
compactionCount: info.compactionCount,
|
|
8138
|
+
iterationsSinceCompaction: info.iterationsSinceCompaction,
|
|
8139
|
+
blocks: info.blocks
|
|
8140
|
+
});
|
|
8141
|
+
}
|
|
8142
|
+
logLlmUsage(iteration, usage) {
|
|
8143
|
+
this.session?.appendLog({
|
|
8144
|
+
ts: new Date().toISOString(),
|
|
8145
|
+
type: "llm_usage",
|
|
8086
8146
|
iteration,
|
|
8087
|
-
|
|
8088
|
-
|
|
8147
|
+
promptTokens: usage.promptTokens,
|
|
8148
|
+
completionTokens: usage.completionTokens,
|
|
8149
|
+
totalTokens: usage.totalTokens,
|
|
8150
|
+
source: usage.source,
|
|
8151
|
+
durationMs: usage.durationMs
|
|
8089
8152
|
});
|
|
8090
8153
|
}
|
|
8091
8154
|
logError(message) {
|
|
@@ -10384,7 +10447,36 @@ class Agent {
|
|
|
10384
10447
|
if (pluginBlocks.length > 0) {
|
|
10385
10448
|
builder.addBlocks(pluginBlocks);
|
|
10386
10449
|
}
|
|
10387
|
-
|
|
10450
|
+
const result = builder.build();
|
|
10451
|
+
return {
|
|
10452
|
+
prompt: result.prompt,
|
|
10453
|
+
excluded: result.excluded,
|
|
10454
|
+
blocks: result.blocks
|
|
10455
|
+
};
|
|
10456
|
+
}
|
|
10457
|
+
logContextStat(kind, iteration, slog, blocks) {
|
|
10458
|
+
const cm = this.deps.contextManager;
|
|
10459
|
+
if (typeof cm.getSnapshot !== "function")
|
|
10460
|
+
return;
|
|
10461
|
+
const snap = cm.getSnapshot();
|
|
10462
|
+
const history = cm.getActiveHistory();
|
|
10463
|
+
const systemMsg = history.find((m) => m.role === "system");
|
|
10464
|
+
slog.logContext({
|
|
10465
|
+
kind,
|
|
10466
|
+
iteration,
|
|
10467
|
+
window: snap.window,
|
|
10468
|
+
systemBudget: snap.budget.systemPrompt,
|
|
10469
|
+
reserveBudget: snap.budget.responseReserve,
|
|
10470
|
+
historyBudget: snap.budget.history,
|
|
10471
|
+
systemTokens: kind === "start" && systemMsg && typeof systemMsg.content === "string" ? this.deps.llmProvider.countTokens(systemMsg.content) : undefined,
|
|
10472
|
+
toolTokens: snap.toolTokens,
|
|
10473
|
+
tokens: snap.tokens,
|
|
10474
|
+
quality: snap.quality,
|
|
10475
|
+
messageCount: snap.messageCount,
|
|
10476
|
+
compactionCount: snap.compactionCount,
|
|
10477
|
+
iterationsSinceCompaction: snap.iterationsSinceCompaction,
|
|
10478
|
+
blocks
|
|
10479
|
+
});
|
|
10388
10480
|
}
|
|
10389
10481
|
getSystemPromptInfo() {
|
|
10390
10482
|
const { prompt, excluded } = this.buildSystemPrompt();
|
|
@@ -10544,27 +10636,47 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
10544
10636
|
}
|
|
10545
10637
|
});
|
|
10546
10638
|
if (contextManager.needsCompaction()) {
|
|
10547
|
-
contextManager.compact();
|
|
10548
|
-
|
|
10549
|
-
|
|
10639
|
+
const result = contextManager.compact();
|
|
10640
|
+
if (result) {
|
|
10641
|
+
logger.debug("Context compacted");
|
|
10642
|
+
slog.logCompaction({ reason: "interval", iteration, ...result });
|
|
10643
|
+
}
|
|
10550
10644
|
}
|
|
10551
10645
|
const currentTokens = contextManager.getEstimatedTokens();
|
|
10552
10646
|
const budget2 = contextManager.getBudget();
|
|
10553
10647
|
const quality = contextManager.getQuality();
|
|
10554
10648
|
if (quality < QUALITY_TRIGGER_THRESHOLD && contextManager.getCompactionCount() > 0 && iteration - lastForcedCompactionIteration >= FORCED_COMPACTION_COOLDOWN) {
|
|
10555
10649
|
lastForcedCompactionIteration = iteration;
|
|
10556
|
-
contextManager.compact();
|
|
10650
|
+
const result = contextManager.compact();
|
|
10557
10651
|
logger.warn(`Low context quality (${quality}%) — forced compaction`);
|
|
10558
|
-
|
|
10652
|
+
if (result) {
|
|
10653
|
+
slog.logCompaction({
|
|
10654
|
+
reason: `quality-triggered (${quality}% < ${QUALITY_TRIGGER_THRESHOLD}%)`,
|
|
10655
|
+
iteration,
|
|
10656
|
+
...result
|
|
10657
|
+
});
|
|
10658
|
+
}
|
|
10559
10659
|
}
|
|
10560
10660
|
if (currentTokens > budget2.history) {
|
|
10561
|
-
contextManager.compact();
|
|
10661
|
+
const result = contextManager.compact();
|
|
10562
10662
|
logger.warn(`Context overflow (${currentTokens} > ${budget2.history}), forced compaction`);
|
|
10563
|
-
|
|
10663
|
+
if (result) {
|
|
10664
|
+
slog.logCompaction({
|
|
10665
|
+
reason: `overflow (${currentTokens} > ${budget2.history})`,
|
|
10666
|
+
iteration,
|
|
10667
|
+
...result
|
|
10668
|
+
});
|
|
10669
|
+
}
|
|
10564
10670
|
}
|
|
10565
10671
|
this.refreshSystemPrompt();
|
|
10566
10672
|
const history = contextManager.getActiveHistory();
|
|
10567
10673
|
slog.logToolDefs(allToolsForBudget.length, allToolsForBudget.map((t2) => t2.name), iteration);
|
|
10674
|
+
if (iteration === 1) {
|
|
10675
|
+
const { blocks } = this.buildSystemPrompt();
|
|
10676
|
+
this.logContextStat("start", iteration, slog, blocks);
|
|
10677
|
+
} else {
|
|
10678
|
+
this.logContextStat("iteration", iteration, slog);
|
|
10679
|
+
}
|
|
10568
10680
|
let textContent = "";
|
|
10569
10681
|
let reasoningContent = "";
|
|
10570
10682
|
const toolCalls = [];
|
|
@@ -10573,6 +10685,8 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
10573
10685
|
const textChunks = [];
|
|
10574
10686
|
this.emitPhase(iteration, "thinking", onPhase);
|
|
10575
10687
|
const llmStart = Date.now();
|
|
10688
|
+
const promptBefore = apiPromptTokens;
|
|
10689
|
+
const completionBefore = apiCompletionTokens;
|
|
10576
10690
|
logger.logLLMRequest(config.model, history.length, input, "agent");
|
|
10577
10691
|
try {
|
|
10578
10692
|
for await (const chunk of llmProvider.chat(history, allToolsForBudget, this.abortController?.signal)) {
|
|
@@ -10636,6 +10750,20 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
10636
10750
|
}
|
|
10637
10751
|
apiCompletionChars += (textContent || reasoningContent).length;
|
|
10638
10752
|
logger.logLLMResponse(config.model, (textContent || reasoningContent).length, Date.now() - llmStart, undefined, "agent");
|
|
10753
|
+
{
|
|
10754
|
+
const usagePrompt = apiPromptTokens - promptBefore;
|
|
10755
|
+
const usageCompletion = apiCompletionTokens - completionBefore;
|
|
10756
|
+
const source = usagePrompt > 0 || usageCompletion > 0 ? "api" : "estimate";
|
|
10757
|
+
const prompt = source === "api" ? usagePrompt : contextManager.getEstimatedTokens();
|
|
10758
|
+
const completion = source === "api" ? usageCompletion : Math.ceil((textContent || reasoningContent).length / 4);
|
|
10759
|
+
slog.logLlmUsage(iteration, {
|
|
10760
|
+
promptTokens: prompt,
|
|
10761
|
+
completionTokens: completion,
|
|
10762
|
+
totalTokens: prompt + completion,
|
|
10763
|
+
source,
|
|
10764
|
+
durationMs: Date.now() - llmStart
|
|
10765
|
+
});
|
|
10766
|
+
}
|
|
10639
10767
|
if (this.shutdownRequested) {
|
|
10640
10768
|
break;
|
|
10641
10769
|
}
|
|
@@ -10753,8 +10881,15 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
10753
10881
|
slog.logToolResult(call, result, duration, iteration);
|
|
10754
10882
|
}
|
|
10755
10883
|
if (contextManager.needsCompaction()) {
|
|
10756
|
-
contextManager.compact();
|
|
10757
|
-
|
|
10884
|
+
const result2 = contextManager.compact();
|
|
10885
|
+
if (result2) {
|
|
10886
|
+
logger.debug("Context compacted after tool result");
|
|
10887
|
+
slog.logCompaction({
|
|
10888
|
+
reason: "after_tool",
|
|
10889
|
+
iteration,
|
|
10890
|
+
...result2
|
|
10891
|
+
});
|
|
10892
|
+
}
|
|
10758
10893
|
}
|
|
10759
10894
|
if (!result.success) {
|
|
10760
10895
|
const key = call.name;
|
|
@@ -11362,9 +11497,12 @@ class ContextManager {
|
|
|
11362
11497
|
return totalTokens > this.budget.history * this.compactionThreshold;
|
|
11363
11498
|
}
|
|
11364
11499
|
compact() {
|
|
11500
|
+
const tokensBefore = this.getEstimatedTokens();
|
|
11501
|
+
const qualityBefore = this.getQuality();
|
|
11502
|
+
const messagesBefore = this.messages.length;
|
|
11365
11503
|
this.iterationsSinceCompaction = 0;
|
|
11366
11504
|
if (this.messages.length <= KEEP_LAST_N * 2)
|
|
11367
|
-
return;
|
|
11505
|
+
return null;
|
|
11368
11506
|
this.compactionCount++;
|
|
11369
11507
|
const cutoff = this.messages.length - KEEP_LAST_N * 2;
|
|
11370
11508
|
const oldTurns = this.messages.slice(0, cutoff);
|
|
@@ -11418,6 +11556,29 @@ ${lines.join(`
|
|
|
11418
11556
|
if (this.onCompact) {
|
|
11419
11557
|
this.onCompact(summary);
|
|
11420
11558
|
}
|
|
11559
|
+
return {
|
|
11560
|
+
removedTurns: oldTurns.length,
|
|
11561
|
+
keptTurns: freshRecent.length,
|
|
11562
|
+
tokensBefore,
|
|
11563
|
+
tokensAfter: this.getEstimatedTokens(),
|
|
11564
|
+
qualityBefore,
|
|
11565
|
+
qualityAfter: this.getQuality(),
|
|
11566
|
+
messagesBefore,
|
|
11567
|
+
messagesAfter: this.messages.length,
|
|
11568
|
+
summary: this.compactedBlock ?? ""
|
|
11569
|
+
};
|
|
11570
|
+
}
|
|
11571
|
+
getSnapshot() {
|
|
11572
|
+
return {
|
|
11573
|
+
window: this.contextWindow,
|
|
11574
|
+
budget: { ...this.budget },
|
|
11575
|
+
tokens: this.getEstimatedTokens(),
|
|
11576
|
+
toolTokens: this.toolTokens,
|
|
11577
|
+
messageCount: this.messages.length,
|
|
11578
|
+
quality: this.getQuality(),
|
|
11579
|
+
compactionCount: this.compactionCount,
|
|
11580
|
+
iterationsSinceCompaction: this.iterationsSinceCompaction
|
|
11581
|
+
};
|
|
11421
11582
|
}
|
|
11422
11583
|
updateSystemPrompt(content) {
|
|
11423
11584
|
const idx = this.messages.findIndex((m) => m.role === "system");
|
|
@@ -31602,6 +31763,17 @@ import { fileURLToPath as fileURLToPath6 } from "url";
|
|
|
31602
31763
|
// src/modules/updater/checker.ts
|
|
31603
31764
|
init_command();
|
|
31604
31765
|
import { platform as platform9 } from "os";
|
|
31766
|
+
function semverGt(a, b) {
|
|
31767
|
+
const pa = a.replace(/^v/, "").split(/[.-]/).map((p) => Number.parseInt(p, 10) || 0);
|
|
31768
|
+
const pb = b.replace(/^v/, "").split(/[.-]/).map((p) => Number.parseInt(p, 10) || 0);
|
|
31769
|
+
for (let i = 0;i < 3; i++) {
|
|
31770
|
+
const na = pa[i] ?? 0;
|
|
31771
|
+
const nb = pb[i] ?? 0;
|
|
31772
|
+
if (na !== nb)
|
|
31773
|
+
return na > nb;
|
|
31774
|
+
}
|
|
31775
|
+
return false;
|
|
31776
|
+
}
|
|
31605
31777
|
var defaultRunner2 = async (command, args, options) => {
|
|
31606
31778
|
const { execFile } = await import("child_process");
|
|
31607
31779
|
return new Promise((resolve24) => {
|
|
@@ -31638,7 +31810,7 @@ class Updater {
|
|
|
31638
31810
|
if (!latest) {
|
|
31639
31811
|
return { updateAvailable: false, current: this.currentVersion, error: "No latest tag" };
|
|
31640
31812
|
}
|
|
31641
|
-
const updateAvailable = latest
|
|
31813
|
+
const updateAvailable = semverGt(latest, this.currentVersion);
|
|
31642
31814
|
return { updateAvailable, current: this.currentVersion, latest };
|
|
31643
31815
|
} catch (e) {
|
|
31644
31816
|
return { updateAvailable: false, current: this.currentVersion, error: e.message };
|
|
@@ -31680,6 +31852,7 @@ class UpdaterModule {
|
|
|
31680
31852
|
logger;
|
|
31681
31853
|
started = false;
|
|
31682
31854
|
timer = null;
|
|
31855
|
+
idlePromise = null;
|
|
31683
31856
|
installEnabled = true;
|
|
31684
31857
|
constructor(config, currentVersion, packageName, logger, installRunner) {
|
|
31685
31858
|
this.config = config;
|
|
@@ -31703,7 +31876,7 @@ class UpdaterModule {
|
|
|
31703
31876
|
if (this.started || !this.config.enabled)
|
|
31704
31877
|
return;
|
|
31705
31878
|
this.started = true;
|
|
31706
|
-
this.runLoop();
|
|
31879
|
+
this.idlePromise = this.runLoop();
|
|
31707
31880
|
}
|
|
31708
31881
|
stop() {
|
|
31709
31882
|
this.started = false;
|
|
@@ -31712,6 +31885,12 @@ class UpdaterModule {
|
|
|
31712
31885
|
this.timer = null;
|
|
31713
31886
|
}
|
|
31714
31887
|
}
|
|
31888
|
+
async waitForIdle(timeoutMs = 130000) {
|
|
31889
|
+
const idle = this.idlePromise;
|
|
31890
|
+
if (!idle)
|
|
31891
|
+
return;
|
|
31892
|
+
await Promise.race([idle, new Promise((r) => setTimeout(r, timeoutMs))]);
|
|
31893
|
+
}
|
|
31715
31894
|
async runLoop() {
|
|
31716
31895
|
while (this.started) {
|
|
31717
31896
|
await this.checkOnce();
|
|
@@ -31775,9 +31954,19 @@ function readVersion5() {
|
|
|
31775
31954
|
}
|
|
31776
31955
|
function startAutoUpdate(config) {
|
|
31777
31956
|
try {
|
|
31778
|
-
const module = new UpdaterModule(config.updater, readVersion5(), "micro-models-agent"
|
|
31957
|
+
const module = new UpdaterModule(config.updater, readVersion5(), "micro-models-agent", {
|
|
31958
|
+
info: (m) => process.stderr.write(pc2.dim(m) + `
|
|
31959
|
+
`),
|
|
31960
|
+
warn: (m) => process.stderr.write(pc2.yellow(m) + `
|
|
31961
|
+
`),
|
|
31962
|
+
error: (m) => process.stderr.write(pc2.red(m) + `
|
|
31963
|
+
`)
|
|
31964
|
+
});
|
|
31779
31965
|
module.start();
|
|
31780
|
-
|
|
31966
|
+
return module;
|
|
31967
|
+
} catch {
|
|
31968
|
+
return;
|
|
31969
|
+
}
|
|
31781
31970
|
}
|
|
31782
31971
|
async function main() {
|
|
31783
31972
|
const program2 = createProgram();
|
|
@@ -31795,7 +31984,7 @@ async function main() {
|
|
|
31795
31984
|
if (program2.args.length > 0) {
|
|
31796
31985
|
const prompt = program2.args.join(" ");
|
|
31797
31986
|
const { agent, config } = await bootstrap(undefined, projectDir, noAgentsMd, exitOnComplete);
|
|
31798
|
-
startAutoUpdate(config);
|
|
31987
|
+
const updater = exitOnComplete ? undefined : startAutoUpdate(config);
|
|
31799
31988
|
if (jsonMode) {
|
|
31800
31989
|
const result2 = await agent.run(prompt);
|
|
31801
31990
|
agent.shutdown();
|
|
@@ -31812,6 +32001,7 @@ async function main() {
|
|
|
31812
32001
|
}, null, 2));
|
|
31813
32002
|
process.stdout.write(`
|
|
31814
32003
|
`);
|
|
32004
|
+
await updater?.waitForIdle();
|
|
31815
32005
|
process.exit(result2.success ? 0 : 1);
|
|
31816
32006
|
}
|
|
31817
32007
|
const renderer = new Renderer({
|
|
@@ -31834,6 +32024,7 @@ async function main() {
|
|
|
31834
32024
|
renderer.flush();
|
|
31835
32025
|
const exitCode = printRunResult(result, () => renderer.flush());
|
|
31836
32026
|
agent.shutdown();
|
|
32027
|
+
await updater?.waitForIdle();
|
|
31837
32028
|
process.exit(exitCode);
|
|
31838
32029
|
} else {
|
|
31839
32030
|
const configPath = join45(homedir18(), ".mma", "config.json");
|