micro-models-agent 0.24.11 → 0.24.12
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 +98 -33
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -3810,10 +3810,6 @@ var init_data_sanitizer = __esm(() => {
|
|
|
3810
3810
|
{
|
|
3811
3811
|
pattern: /Bearer\s+[a-zA-Z0-9_-]{20,}/gi,
|
|
3812
3812
|
replacement: "Bearer [REDACTED]"
|
|
3813
|
-
},
|
|
3814
|
-
{
|
|
3815
|
-
pattern: /\b([a-zA-Z0-9_-]{30,})\b/g,
|
|
3816
|
-
replacement: "[REDACTED]"
|
|
3817
3813
|
}
|
|
3818
3814
|
];
|
|
3819
3815
|
});
|
|
@@ -5012,6 +5008,14 @@ class ToolResultCache {
|
|
|
5012
5008
|
has(key) {
|
|
5013
5009
|
return this.get(key) !== undefined;
|
|
5014
5010
|
}
|
|
5011
|
+
cleanExpired() {
|
|
5012
|
+
const now = Date.now();
|
|
5013
|
+
for (const [key, entry] of this.cache) {
|
|
5014
|
+
if (now > entry.expiresAt) {
|
|
5015
|
+
this.cache.delete(key);
|
|
5016
|
+
}
|
|
5017
|
+
}
|
|
5018
|
+
}
|
|
5015
5019
|
clear() {
|
|
5016
5020
|
this.cache.clear();
|
|
5017
5021
|
}
|
|
@@ -5132,6 +5136,7 @@ class ToolExecutor {
|
|
|
5132
5136
|
this.cache.set(key, result.output);
|
|
5133
5137
|
this.ctx.logger.debug(`Tool ${call.name}: CACHED`);
|
|
5134
5138
|
}
|
|
5139
|
+
this.cache.cleanExpired();
|
|
5135
5140
|
this.ctx.logger.debug(`Tool ${call.name}: ${result.success ? "OK" : "FAIL"}`);
|
|
5136
5141
|
return result;
|
|
5137
5142
|
}
|
|
@@ -5147,6 +5152,9 @@ class ToolExecutor {
|
|
|
5147
5152
|
setScope(scope) {
|
|
5148
5153
|
this.ctx.scope = scope;
|
|
5149
5154
|
}
|
|
5155
|
+
setOnMeta(onMeta) {
|
|
5156
|
+
this.ctx.onMeta = onMeta;
|
|
5157
|
+
}
|
|
5150
5158
|
updateProvider(provider) {
|
|
5151
5159
|
this.ctx.llmProvider = provider;
|
|
5152
5160
|
}
|
|
@@ -6260,7 +6268,8 @@ var init_edit_file = __esm(() => {
|
|
|
6260
6268
|
output: t("file.string_not_found", { str: oldStr })
|
|
6261
6269
|
};
|
|
6262
6270
|
}
|
|
6263
|
-
const
|
|
6271
|
+
const occurrences = content.split(oldStr).length - 1;
|
|
6272
|
+
const updated = occurrences > 1 ? content.replaceAll(oldStr, newStr) : content.replace(oldStr, newStr);
|
|
6264
6273
|
const scanResult = scanContent(updated, path, ctx.config.security?.contentScan);
|
|
6265
6274
|
if (!scanResult.allowed) {
|
|
6266
6275
|
logSecurityBlock(ctx.sessionId, "file_write", scanResult.reason || "Content contains dangerous patterns", path);
|
|
@@ -6667,6 +6676,12 @@ var init_file_info = __esm(() => {
|
|
|
6667
6676
|
});
|
|
6668
6677
|
|
|
6669
6678
|
// src/modules/security/command-validator.ts
|
|
6679
|
+
function hasShellIndirection(command) {
|
|
6680
|
+
return /\$\{[^}]+\}/.test(command) || /\$\(/.test(command) || /`[^`]+`/.test(command) || /\$\(\(/.test(command) || /\$\{[!]/.test(command);
|
|
6681
|
+
}
|
|
6682
|
+
function hasEvalConstruct(command) {
|
|
6683
|
+
return /\beval\b/.test(command) || /\bsource\b/.test(command);
|
|
6684
|
+
}
|
|
6670
6685
|
function extractBaseCommand(trimmed) {
|
|
6671
6686
|
const tokens = trimmed.split(/\s+/);
|
|
6672
6687
|
let i = 0;
|
|
@@ -6722,6 +6737,18 @@ function isCommandAllowed(command, securityConfig) {
|
|
|
6722
6737
|
reason: `Shell wrapper "${baseForShellCheck}" is blocked — use the bash tool directly`
|
|
6723
6738
|
};
|
|
6724
6739
|
}
|
|
6740
|
+
if (hasShellIndirection(trimmedCommand)) {
|
|
6741
|
+
return {
|
|
6742
|
+
allowed: false,
|
|
6743
|
+
reason: `Shell indirection (variable expansion, command substitution, or backtick execution) is not allowed`
|
|
6744
|
+
};
|
|
6745
|
+
}
|
|
6746
|
+
if (hasEvalConstruct(trimmedCommand)) {
|
|
6747
|
+
return {
|
|
6748
|
+
allowed: false,
|
|
6749
|
+
reason: `eval/source constructs are not allowed`
|
|
6750
|
+
};
|
|
6751
|
+
}
|
|
6725
6752
|
if (config.blockDangerousFlags) {
|
|
6726
6753
|
for (const op of config.dangerousOperators || []) {
|
|
6727
6754
|
if (containsOperator(trimmedCommand, op)) {
|
|
@@ -6732,7 +6759,15 @@ function isCommandAllowed(command, securityConfig) {
|
|
|
6732
6759
|
}
|
|
6733
6760
|
}
|
|
6734
6761
|
}
|
|
6735
|
-
const baseCommand =
|
|
6762
|
+
const baseCommand = baseForShellCheck;
|
|
6763
|
+
if (!baseCommand || baseCommand === trimmedCommand.trim()) {
|
|
6764
|
+
if (baseCommand === "sudo" || baseCommand === "env" || baseCommand === "nohup" || baseCommand === "exec") {
|
|
6765
|
+
return {
|
|
6766
|
+
allowed: false,
|
|
6767
|
+
reason: `Prefix "${baseCommand}" requires a target command`
|
|
6768
|
+
};
|
|
6769
|
+
}
|
|
6770
|
+
}
|
|
6736
6771
|
if (config.whitelist.length > 0) {
|
|
6737
6772
|
if (!config.whitelist.includes(baseCommand)) {
|
|
6738
6773
|
return {
|
|
@@ -8408,7 +8443,12 @@ function validatePlan(plan, config) {
|
|
|
8408
8443
|
const warnings = [];
|
|
8409
8444
|
const autoFixes = [];
|
|
8410
8445
|
if (!plan.subtasks || plan.subtasks.length === 0) {
|
|
8411
|
-
return {
|
|
8446
|
+
return {
|
|
8447
|
+
valid: false,
|
|
8448
|
+
errors: ["Plan has no subtasks"],
|
|
8449
|
+
warnings: [],
|
|
8450
|
+
autoFixes: []
|
|
8451
|
+
};
|
|
8412
8452
|
}
|
|
8413
8453
|
errors.push(...expertTagsExist(plan.subtasks, config));
|
|
8414
8454
|
errors.push(...hasCycle(plan.subtasks));
|
|
@@ -8417,7 +8457,10 @@ function validatePlan(plan, config) {
|
|
|
8417
8457
|
const readOverlaps = deleteReadOverlap(plan.subtasks);
|
|
8418
8458
|
for (const overlap of readOverlaps) {
|
|
8419
8459
|
if (overlap.canAutoFix) {
|
|
8420
|
-
autoFixes.push({
|
|
8460
|
+
autoFixes.push({
|
|
8461
|
+
subtaskId: overlap.subtaskId,
|
|
8462
|
+
fix: `Add depends_on: ${overlap.dependsOn}`
|
|
8463
|
+
});
|
|
8421
8464
|
} else if (overlap.error) {
|
|
8422
8465
|
errors.push(overlap.error);
|
|
8423
8466
|
}
|
|
@@ -8463,7 +8506,6 @@ function hasCycle(subtasks) {
|
|
|
8463
8506
|
}
|
|
8464
8507
|
const errors = [];
|
|
8465
8508
|
for (const s of subtasks) {
|
|
8466
|
-
visited.clear();
|
|
8467
8509
|
inStack.clear();
|
|
8468
8510
|
if (dfs(s.id)) {
|
|
8469
8511
|
errors.push(`Cycle detected involving subtask "${s.id}"`);
|
|
@@ -8721,13 +8763,26 @@ class MoEExecutor {
|
|
|
8721
8763
|
constructor(deps) {
|
|
8722
8764
|
this.deps = deps;
|
|
8723
8765
|
}
|
|
8724
|
-
async executePlan(plan) {
|
|
8766
|
+
async executePlan(plan, signal) {
|
|
8725
8767
|
const results = [];
|
|
8726
8768
|
const errors = [];
|
|
8727
8769
|
const warnings = [];
|
|
8770
|
+
if (signal?.aborted) {
|
|
8771
|
+
return {
|
|
8772
|
+
success: false,
|
|
8773
|
+
results: [],
|
|
8774
|
+
errors: ["Execution aborted before start"],
|
|
8775
|
+
warnings: []
|
|
8776
|
+
};
|
|
8777
|
+
}
|
|
8728
8778
|
const waves = topologicalSort(plan.subtasks);
|
|
8729
8779
|
if (waves.length === 0) {
|
|
8730
|
-
return {
|
|
8780
|
+
return {
|
|
8781
|
+
success: false,
|
|
8782
|
+
results: [],
|
|
8783
|
+
errors: ["Failed to topologically sort subtasks (possible cycle)"],
|
|
8784
|
+
warnings: []
|
|
8785
|
+
};
|
|
8731
8786
|
}
|
|
8732
8787
|
const sortedCount = waves.flat().length;
|
|
8733
8788
|
if (sortedCount < plan.subtasks.length) {
|
|
@@ -8735,11 +8790,17 @@ class MoEExecutor {
|
|
|
8735
8790
|
return {
|
|
8736
8791
|
success: false,
|
|
8737
8792
|
results: [],
|
|
8738
|
-
errors: [
|
|
8793
|
+
errors: [
|
|
8794
|
+
`Missing subtasks after topological sort: ${missing.join(", ")} (dangling or invalid depends_on)`
|
|
8795
|
+
],
|
|
8739
8796
|
warnings: []
|
|
8740
8797
|
};
|
|
8741
8798
|
}
|
|
8742
8799
|
for (let waveIdx = 0;waveIdx < waves.length; waveIdx++) {
|
|
8800
|
+
if (signal?.aborted) {
|
|
8801
|
+
warnings.push(`Execution aborted during wave ${waveIdx + 1}/${waves.length}`);
|
|
8802
|
+
break;
|
|
8803
|
+
}
|
|
8743
8804
|
const wave = waves[waveIdx];
|
|
8744
8805
|
const wavePromises = wave.map((subtask) => executeSubtask(subtask, this.deps, plan.shared_context).then((result) => {
|
|
8745
8806
|
results.push(result);
|
|
@@ -8939,7 +9000,12 @@ var init_verifier = __esm(() => {
|
|
|
8939
9000
|
// src/core/agent-moe.ts
|
|
8940
9001
|
async function runWithMoE(deps, input, fallback, opts = {}) {
|
|
8941
9002
|
const { config, llmProvider, logger, toolExecutor, baseDir } = deps;
|
|
8942
|
-
const { onMeta, onPhase } = opts;
|
|
9003
|
+
const { onMeta, onPhase, signal } = opts;
|
|
9004
|
+
const abortCheck = () => {
|
|
9005
|
+
if (signal?.aborted)
|
|
9006
|
+
return true;
|
|
9007
|
+
return false;
|
|
9008
|
+
};
|
|
8943
9009
|
const orchestrator = new OrchestratorClient({
|
|
8944
9010
|
model: config.orchestrator.model,
|
|
8945
9011
|
provider: config.orchestrator.provider
|
|
@@ -8985,7 +9051,7 @@ async function runWithMoE(deps, input, fallback, opts = {}) {
|
|
|
8985
9051
|
const executor = new MoEExecutor(moeDeps);
|
|
8986
9052
|
onMeta?.(`⚙️ Executing ${plan.subtasks.length} subtasks...
|
|
8987
9053
|
`);
|
|
8988
|
-
const planResults = await executor.executePlan(plan);
|
|
9054
|
+
const planResults = await executor.executePlan(plan, signal);
|
|
8989
9055
|
onMeta?.(`✅ Execution complete: ${planResults.results.filter((r) => r.success).length}/${planResults.results.length} succeeded
|
|
8990
9056
|
`);
|
|
8991
9057
|
const verifier = new StepVerifier(baseDir);
|
|
@@ -9196,10 +9262,6 @@ class Agent {
|
|
|
9196
9262
|
const systemBudget = Math.floor(this.deps.config.contextWindow * this.deps.config.contextBudget.systemPrompt);
|
|
9197
9263
|
const builder = new PromptBuilder(systemBudget);
|
|
9198
9264
|
builder.addBlocks(this.deps.promptBlocks);
|
|
9199
|
-
const dynamic = this.deps.getDynamicPromptBlocks?.() ?? [];
|
|
9200
|
-
if (dynamic.length > 0) {
|
|
9201
|
-
builder.addBlocks(dynamic);
|
|
9202
|
-
}
|
|
9203
9265
|
const pluginBlocks = (this.deps.pluginManager.runOnBuildPrompt?.() ?? []).filter((s) => Boolean(s && s.trim() !== "")).map((content) => ({
|
|
9204
9266
|
content,
|
|
9205
9267
|
priority: "low",
|
|
@@ -9209,6 +9271,10 @@ class Agent {
|
|
|
9209
9271
|
if (pluginBlocks.length > 0) {
|
|
9210
9272
|
builder.addBlocks(pluginBlocks);
|
|
9211
9273
|
}
|
|
9274
|
+
const dynamic = this.deps.getDynamicPromptBlocks?.() ?? [];
|
|
9275
|
+
if (dynamic.length > 0) {
|
|
9276
|
+
builder.addBlocks(dynamic);
|
|
9277
|
+
}
|
|
9212
9278
|
return builder.build();
|
|
9213
9279
|
}
|
|
9214
9280
|
getSystemPromptInfo() {
|
|
@@ -9279,7 +9345,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
9279
9345
|
toolExecutor,
|
|
9280
9346
|
logger,
|
|
9281
9347
|
baseDir: this.deps.baseDir
|
|
9282
|
-
}, input, () => this.executeSingleAgentLoop(input, onChunk, onMeta, onTool, onPhase), { onMeta, onTool, onPhase });
|
|
9348
|
+
}, input, () => this.executeSingleAgentLoop(input, onChunk, onMeta, onTool, onPhase), { onMeta, onTool, onPhase, signal: this.abortController?.signal });
|
|
9283
9349
|
}
|
|
9284
9350
|
return this.executeSingleAgentLoop(input, onChunk, onMeta, onTool, onPhase);
|
|
9285
9351
|
}
|
|
@@ -9449,15 +9515,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
9449
9515
|
onTool?.({ type: "start", tool: call.name, args: call.arguments });
|
|
9450
9516
|
slog.logToolCall(call, iteration);
|
|
9451
9517
|
const tokensBeforeTool = contextManager.getEstimatedTokens();
|
|
9452
|
-
const toolCtx = this.deps.toolExecutor?.getContext?.();
|
|
9453
|
-
const prevOnMeta = toolCtx?.onMeta;
|
|
9454
|
-
if (toolCtx) {
|
|
9455
|
-
toolCtx.onMeta = onMeta;
|
|
9456
|
-
}
|
|
9457
9518
|
const result = await toolExecutor.execute(call, this.abortController?.signal);
|
|
9458
|
-
if (toolCtx) {
|
|
9459
|
-
toolCtx.onMeta = prevOnMeta;
|
|
9460
|
-
}
|
|
9461
9519
|
const duration = Date.now() - startTime;
|
|
9462
9520
|
pluginManager.runOnToolEnd({ iteration, logger }, { id: call.id, name: call.name, arguments: call.arguments }, result, duration);
|
|
9463
9521
|
return { call, result, duration, tokensBefore: tokensBeforeTool };
|
|
@@ -9510,11 +9568,12 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
9510
9568
|
if (config.session.autoSave) {
|
|
9511
9569
|
slog.logToolResult(call, result, duration, iteration);
|
|
9512
9570
|
}
|
|
9513
|
-
if (contextManager.needsCompaction()) {
|
|
9514
|
-
contextManager.compact();
|
|
9515
|
-
logger.debug("Context compacted after tool result");
|
|
9516
|
-
}
|
|
9517
9571
|
};
|
|
9572
|
+
const toolExecutorForMeta = this.deps.toolExecutor;
|
|
9573
|
+
const savedOnMeta = toolExecutorForMeta?.getContext?.()?.onMeta;
|
|
9574
|
+
if (toolExecutorForMeta?.setOnMeta) {
|
|
9575
|
+
toolExecutorForMeta.setOnMeta(onMeta);
|
|
9576
|
+
}
|
|
9518
9577
|
if (canRunInParallel(toolCalls)) {
|
|
9519
9578
|
const entries = await Promise.all(toolCalls.map(executeToolCall));
|
|
9520
9579
|
for (const entry of entries) {
|
|
@@ -9526,6 +9585,13 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
9526
9585
|
processToolResult(entry);
|
|
9527
9586
|
}
|
|
9528
9587
|
}
|
|
9588
|
+
if (toolExecutorForMeta?.setOnMeta) {
|
|
9589
|
+
toolExecutorForMeta.setOnMeta(savedOnMeta);
|
|
9590
|
+
}
|
|
9591
|
+
if (contextManager.needsCompaction()) {
|
|
9592
|
+
contextManager.compact();
|
|
9593
|
+
logger.debug("Context compacted after tool results");
|
|
9594
|
+
}
|
|
9529
9595
|
if (anyToolFailed) {
|
|
9530
9596
|
consecutiveToolFailures++;
|
|
9531
9597
|
} else {
|
|
@@ -10454,8 +10520,7 @@ var init_subagent = __esm(() => {
|
|
|
10454
10520
|
baseDir: ctx.baseDir,
|
|
10455
10521
|
scope,
|
|
10456
10522
|
toolTags,
|
|
10457
|
-
promptBlocks: [systemPrompt]
|
|
10458
|
-
recursionDepth: currentDepth + 1
|
|
10523
|
+
promptBlocks: [systemPrompt]
|
|
10459
10524
|
};
|
|
10460
10525
|
const subAgent = new Agent(subDeps);
|
|
10461
10526
|
const fullTask = context ? `${task}
|