open-agents-ai 0.64.0 → 0.66.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/dist/index.js +109 -14
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13801,7 +13801,7 @@ Rules:
|
|
|
13801
13801
|
const keepRecentDivisor = tier === "small" ? 2e3 : tier === "medium" ? 3e3 : 4e3;
|
|
13802
13802
|
keepRecent = Math.max(4, Math.min(keepRecentMax, Math.floor(ctx / keepRecentDivisor)));
|
|
13803
13803
|
} else {
|
|
13804
|
-
keepRecent = deep ? 20 : 12;
|
|
13804
|
+
keepRecent = deep ? tier === "small" ? 8 : tier === "medium" ? 14 : 20 : tier === "small" ? 4 : tier === "medium" ? 6 : 12;
|
|
13805
13805
|
}
|
|
13806
13806
|
const maxOutputTokens = ctx > 0 ? Math.min(this.options.maxTokens, Math.max(2048, Math.floor(ctx * 0.25))) : this.options.maxTokens;
|
|
13807
13807
|
const toolOutputCeiling = deep ? 16e3 : 8e3;
|
|
@@ -14088,7 +14088,14 @@ Integrate this guidance into your current approach. Continue working on the task
|
|
|
14088
14088
|
const choiceContent = response.choices[0]?.message?.content ?? "";
|
|
14089
14089
|
const choiceArgs = response.choices[0]?.message?.toolCalls?.map((tc) => JSON.stringify(tc.arguments)).join("") ?? "";
|
|
14090
14090
|
estimatedTokens += Math.ceil((choiceContent.length + choiceArgs.length) / 4);
|
|
14091
|
-
const estimatedContextTokens = Math.ceil(compacted.reduce((sum, m) =>
|
|
14091
|
+
const estimatedContextTokens = Math.ceil(compacted.reduce((sum, m) => {
|
|
14092
|
+
let chars = typeof m.content === "string" ? m.content.length : 100;
|
|
14093
|
+
if (m.tool_calls) {
|
|
14094
|
+
for (const tc of m.tool_calls)
|
|
14095
|
+
chars += tc.function.arguments?.length ?? 0;
|
|
14096
|
+
}
|
|
14097
|
+
return sum + chars;
|
|
14098
|
+
}, 0) / 4);
|
|
14092
14099
|
this.emit({
|
|
14093
14100
|
type: "token_usage",
|
|
14094
14101
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -14386,7 +14393,14 @@ Integrate this guidance into your current approach. Continue working on the task
|
|
|
14386
14393
|
const choiceContent2 = response.choices[0]?.message?.content ?? "";
|
|
14387
14394
|
const choiceArgs2 = response.choices[0]?.message?.toolCalls?.map((tc) => JSON.stringify(tc.arguments)).join("") ?? "";
|
|
14388
14395
|
estimatedTokens += Math.ceil((choiceContent2.length + choiceArgs2.length) / 4);
|
|
14389
|
-
const bfEstCtx = Math.ceil(compactedMsgs.reduce((sum, m) =>
|
|
14396
|
+
const bfEstCtx = Math.ceil(compactedMsgs.reduce((sum, m) => {
|
|
14397
|
+
let chars = typeof m.content === "string" ? m.content.length : 100;
|
|
14398
|
+
if (m.tool_calls) {
|
|
14399
|
+
for (const tc of m.tool_calls)
|
|
14400
|
+
chars += tc.function.arguments?.length ?? 0;
|
|
14401
|
+
}
|
|
14402
|
+
return sum + chars;
|
|
14403
|
+
}, 0) / 4);
|
|
14390
14404
|
this.emit({
|
|
14391
14405
|
type: "token_usage",
|
|
14392
14406
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -14659,12 +14673,19 @@ ${tail}`;
|
|
|
14659
14673
|
if (messages.length < 3)
|
|
14660
14674
|
return messages;
|
|
14661
14675
|
const totalChars = messages.reduce((sum, m) => {
|
|
14676
|
+
let chars = 0;
|
|
14662
14677
|
if (typeof m.content === "string")
|
|
14663
|
-
|
|
14664
|
-
if (Array.isArray(m.content)) {
|
|
14665
|
-
|
|
14678
|
+
chars += m.content.length;
|
|
14679
|
+
else if (Array.isArray(m.content)) {
|
|
14680
|
+
chars += m.content.reduce((s, p) => s + (p.text?.length || 0) + (p.image_url ? 1e3 : 0), 0);
|
|
14681
|
+
}
|
|
14682
|
+
if (m.tool_calls) {
|
|
14683
|
+
for (const tc of m.tool_calls) {
|
|
14684
|
+
chars += tc.function.arguments?.length ?? 0;
|
|
14685
|
+
chars += tc.function.name?.length ?? 0;
|
|
14686
|
+
}
|
|
14666
14687
|
}
|
|
14667
|
-
return sum;
|
|
14688
|
+
return sum + chars;
|
|
14668
14689
|
}, 0);
|
|
14669
14690
|
const estimatedTokens = totalChars / 4;
|
|
14670
14691
|
const limits = this.contextLimits();
|
|
@@ -14758,7 +14779,34 @@ ${fullSummary}
|
|
|
14758
14779
|
[Continue from the recent context below. Do not repeat work already completed above.]`
|
|
14759
14780
|
};
|
|
14760
14781
|
this.persistCheckpoint(fullSummary);
|
|
14761
|
-
|
|
14782
|
+
let result = [...head, compactionMsg, ...recent];
|
|
14783
|
+
const ctxWindow = this.options.contextWindowSize;
|
|
14784
|
+
if (ctxWindow > 0) {
|
|
14785
|
+
const estimateResult = (msgs) => msgs.reduce((sum, m) => {
|
|
14786
|
+
let chars = typeof m.content === "string" ? m.content.length : 100;
|
|
14787
|
+
if (m.tool_calls) {
|
|
14788
|
+
for (const tc of m.tool_calls)
|
|
14789
|
+
chars += tc.function.arguments?.length ?? 0;
|
|
14790
|
+
}
|
|
14791
|
+
return sum + chars;
|
|
14792
|
+
}, 0) / 4;
|
|
14793
|
+
const safetyTarget = Math.floor(ctxWindow * 0.65);
|
|
14794
|
+
let trimmedRecent = [...recent];
|
|
14795
|
+
while (estimateResult(result) > safetyTarget && trimmedRecent.length > 2) {
|
|
14796
|
+
trimmedRecent = trimmedRecent.slice(1);
|
|
14797
|
+
while (trimmedRecent.length > 1 && trimmedRecent[0]?.role === "tool") {
|
|
14798
|
+
trimmedRecent = trimmedRecent.slice(1);
|
|
14799
|
+
}
|
|
14800
|
+
result = [...head, compactionMsg, ...trimmedRecent];
|
|
14801
|
+
}
|
|
14802
|
+
if (trimmedRecent.length < recent.length) {
|
|
14803
|
+
this.emit({
|
|
14804
|
+
type: "status",
|
|
14805
|
+
content: `Post-compaction trim: reduced recent from ${recent.length} to ${trimmedRecent.length} messages to fit ${ctxWindow.toLocaleString()}-token context window`,
|
|
14806
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
14807
|
+
});
|
|
14808
|
+
}
|
|
14809
|
+
}
|
|
14762
14810
|
if (result.length < 2)
|
|
14763
14811
|
return messages;
|
|
14764
14812
|
return result;
|
|
@@ -25423,14 +25471,39 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
25423
25471
|
async function switchModel(query, ctx, local = false) {
|
|
25424
25472
|
try {
|
|
25425
25473
|
const models = await fetchModels(ctx.config.backendUrl, ctx.config.apiKey);
|
|
25426
|
-
|
|
25474
|
+
let match = findModel(models, query);
|
|
25427
25475
|
if (!match) {
|
|
25428
|
-
|
|
25429
|
-
|
|
25430
|
-
|
|
25431
|
-
|
|
25476
|
+
if (ctx.config.backendType === "ollama") {
|
|
25477
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9._:/-]*$/.test(query)) {
|
|
25478
|
+
renderError(`Invalid model name: "${query}"`);
|
|
25479
|
+
return;
|
|
25480
|
+
}
|
|
25481
|
+
renderInfo(`Model "${query}" not found locally. Pulling from Ollama registry...`);
|
|
25482
|
+
try {
|
|
25483
|
+
pullModelWithAutoUpdate(query);
|
|
25484
|
+
const refreshedModels = await fetchModels(ctx.config.backendUrl, ctx.config.apiKey);
|
|
25485
|
+
match = findModel(refreshedModels, query);
|
|
25486
|
+
if (!match) {
|
|
25487
|
+
renderError(`Model "${query}" was pulled but could not be found.`);
|
|
25488
|
+
return;
|
|
25489
|
+
}
|
|
25490
|
+
} catch {
|
|
25491
|
+
renderError(`Model "${query}" could not be pulled from Ollama registry.`);
|
|
25492
|
+
renderInfo("Check that the model name is correct: https://ollama.com/library");
|
|
25493
|
+
renderInfo("Available local models:");
|
|
25494
|
+
for (const m of models.slice(0, 10)) {
|
|
25495
|
+
renderInfo(` ${m.name}`);
|
|
25496
|
+
}
|
|
25497
|
+
return;
|
|
25498
|
+
}
|
|
25499
|
+
} else {
|
|
25500
|
+
renderError(`Model not found: "${query}"`);
|
|
25501
|
+
renderInfo("Available models:");
|
|
25502
|
+
for (const m of models.slice(0, 10)) {
|
|
25503
|
+
renderInfo(` ${m.name}`);
|
|
25504
|
+
}
|
|
25505
|
+
return;
|
|
25432
25506
|
}
|
|
25433
|
-
return;
|
|
25434
25507
|
}
|
|
25435
25508
|
let finalModel = match.name;
|
|
25436
25509
|
if (ctx.config.backendType === "ollama") {
|
|
@@ -25464,6 +25537,7 @@ async function switchModel(query, ctx, local = false) {
|
|
|
25464
25537
|
const caps = await queryModelCapabilities(ctx.config.backendUrl, finalModel);
|
|
25465
25538
|
ctx.setCapabilities(caps);
|
|
25466
25539
|
}
|
|
25540
|
+
ctx.refreshModelCache?.();
|
|
25467
25541
|
} catch (err) {
|
|
25468
25542
|
renderError(`Failed to switch model: ${err instanceof Error ? err.message : String(err)}`);
|
|
25469
25543
|
}
|
|
@@ -35012,6 +35086,9 @@ async function startInteractive(config, repoPath) {
|
|
|
35012
35086
|
if (ctxSize) {
|
|
35013
35087
|
resolvedContextWindowSize = ctxSize;
|
|
35014
35088
|
statusBar.setContextWindowSize(ctxSize);
|
|
35089
|
+
if (activeTask) {
|
|
35090
|
+
activeTask.runner.setContextWindowSize(ctxSize);
|
|
35091
|
+
}
|
|
35015
35092
|
}
|
|
35016
35093
|
}).catch(() => {
|
|
35017
35094
|
});
|
|
@@ -35239,9 +35316,26 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
35239
35316
|
];
|
|
35240
35317
|
const discoveredSkillNames = discoverSkills(repoRoot).map((s) => `/${s.name}`);
|
|
35241
35318
|
const allCompletions = [.../* @__PURE__ */ new Set([...BUILTIN_COMMANDS, ...discoveredSkillNames])].sort();
|
|
35319
|
+
let cachedModelNames = [];
|
|
35320
|
+
function refreshModelCache() {
|
|
35321
|
+
fetchModels(config.backendUrl, config.apiKey).then((models) => {
|
|
35322
|
+
cachedModelNames = models.map((m) => m.name);
|
|
35323
|
+
}).catch(() => {
|
|
35324
|
+
});
|
|
35325
|
+
}
|
|
35326
|
+
refreshModelCache();
|
|
35242
35327
|
function completer(line) {
|
|
35243
35328
|
if (!line.startsWith("/"))
|
|
35244
35329
|
return [[], line];
|
|
35330
|
+
const modelMatch = line.match(/^\/model\s+(.*)$/i);
|
|
35331
|
+
if (modelMatch) {
|
|
35332
|
+
const partial = modelMatch[1].toLowerCase();
|
|
35333
|
+
const hits2 = cachedModelNames.filter((n) => n.toLowerCase().startsWith(partial));
|
|
35334
|
+
if (hits2.length === 0 && partial.length > 0) {
|
|
35335
|
+
return [[modelMatch[1]], modelMatch[1]];
|
|
35336
|
+
}
|
|
35337
|
+
return [hits2, modelMatch[1]];
|
|
35338
|
+
}
|
|
35245
35339
|
const lower = line.toLowerCase();
|
|
35246
35340
|
const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
|
|
35247
35341
|
return [hits, line];
|
|
@@ -35914,6 +36008,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
35914
36008
|
resolvedCaps = caps;
|
|
35915
36009
|
statusBar.setCapabilities(caps);
|
|
35916
36010
|
},
|
|
36011
|
+
refreshModelCache,
|
|
35917
36012
|
hasActiveTask: () => activeTask !== null,
|
|
35918
36013
|
requestCompaction(strategy) {
|
|
35919
36014
|
if (!activeTask)
|
package/package.json
CHANGED