open-agents-ai 0.172.0 → 0.173.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 +84 -34
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25688,7 +25688,32 @@ Respond with your assessment, then take action.`;
|
|
|
25688
25688
|
|
|
25689
25689
|
TASK: ${task}` : task }
|
|
25690
25690
|
];
|
|
25691
|
-
|
|
25691
|
+
let toolDefs = this.buildToolDefinitions();
|
|
25692
|
+
let textToolModeActive = this.options.textToolMode ?? false;
|
|
25693
|
+
if (textToolModeActive) {
|
|
25694
|
+
const toolDescriptions = Array.from(this.tools.values()).map((t) => `- ${t.name}: ${t.description}`).join("\n");
|
|
25695
|
+
messages[0].content += [
|
|
25696
|
+
"\n\n[TEXT TOOL MODE]",
|
|
25697
|
+
"This model uses text-based tool invocation (no native tool API).",
|
|
25698
|
+
"To use a tool, output a JSON block in your response:",
|
|
25699
|
+
"```json",
|
|
25700
|
+
'{"tool": "tool_name", "args": {"param": "value"}}',
|
|
25701
|
+
"```",
|
|
25702
|
+
"\nAvailable tools:",
|
|
25703
|
+
toolDescriptions,
|
|
25704
|
+
"\nRules:",
|
|
25705
|
+
"- Output EXACTLY ONE tool call per response in the JSON format above",
|
|
25706
|
+
"- After seeing the tool result, continue or call another tool",
|
|
25707
|
+
'- When done: {"tool": "task_complete", "args": {"summary": "what you did"}}',
|
|
25708
|
+
"- You CAN also write ```bash ... ``` blocks which will be auto-executed"
|
|
25709
|
+
].join("\n");
|
|
25710
|
+
toolDefs = [];
|
|
25711
|
+
this.emit({
|
|
25712
|
+
type: "status",
|
|
25713
|
+
content: "Text tool mode active \u2014 tools described in prompt, parsed from JSON/code blocks",
|
|
25714
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
25715
|
+
});
|
|
25716
|
+
}
|
|
25692
25717
|
let totalTokens = 0;
|
|
25693
25718
|
let promptTokens = 0;
|
|
25694
25719
|
let completionTokens = 0;
|
|
@@ -39132,6 +39157,34 @@ import { promisify as promisify6 } from "node:util";
|
|
|
39132
39157
|
import { existsSync as existsSync37, writeFileSync as writeFileSync16, readFileSync as readFileSync28, appendFileSync as appendFileSync2, mkdirSync as mkdirSync15 } from "node:fs";
|
|
39133
39158
|
import { join as join54 } from "node:path";
|
|
39134
39159
|
import { homedir as homedir12, platform as platform2 } from "node:os";
|
|
39160
|
+
async function checkToolSupport(modelName, backendUrl = "http://localhost:11434") {
|
|
39161
|
+
if (_toolSupportCache.has(modelName))
|
|
39162
|
+
return _toolSupportCache.get(modelName);
|
|
39163
|
+
try {
|
|
39164
|
+
const resp = await fetch(`${backendUrl.replace(/\/+$/, "")}/api/show`, {
|
|
39165
|
+
method: "POST",
|
|
39166
|
+
headers: { "Content-Type": "application/json" },
|
|
39167
|
+
body: JSON.stringify({ name: modelName }),
|
|
39168
|
+
signal: AbortSignal.timeout(5e3)
|
|
39169
|
+
});
|
|
39170
|
+
if (!resp.ok) {
|
|
39171
|
+
_toolSupportCache.set(modelName, false);
|
|
39172
|
+
return false;
|
|
39173
|
+
}
|
|
39174
|
+
const data = await resp.json();
|
|
39175
|
+
const template = data.template ?? "";
|
|
39176
|
+
const hasTools = template.includes("{{.Tools}}") || template.includes("{{ .Tools }}");
|
|
39177
|
+
_toolSupportCache.set(modelName, hasTools);
|
|
39178
|
+
return hasTools;
|
|
39179
|
+
} catch {
|
|
39180
|
+
_toolSupportCache.set(modelName, false);
|
|
39181
|
+
return false;
|
|
39182
|
+
}
|
|
39183
|
+
}
|
|
39184
|
+
async function needsTextToolMode(modelName, backendUrl) {
|
|
39185
|
+
const hasTools = await checkToolSupport(modelName, backendUrl);
|
|
39186
|
+
return !hasTools;
|
|
39187
|
+
}
|
|
39135
39188
|
function detectSystemSpecs() {
|
|
39136
39189
|
let totalRamGB = 0;
|
|
39137
39190
|
let availableRamGB = 0;
|
|
@@ -39259,14 +39312,6 @@ function calculateContextWindow(specs, modelSizeGB2, kvBytesPerToken, archMax) {
|
|
|
39259
39312
|
const label = numCtx >= 1024 ? `${Math.floor(numCtx / 1024)}K` : String(numCtx);
|
|
39260
39313
|
return { numCtx, label };
|
|
39261
39314
|
}
|
|
39262
|
-
function modelSupportsToolCalling(modelName) {
|
|
39263
|
-
const lower = modelName.toLowerCase();
|
|
39264
|
-
for (const known of TOOL_CALLING_MODELS) {
|
|
39265
|
-
if (lower.startsWith(known) || lower.includes(known))
|
|
39266
|
-
return true;
|
|
39267
|
-
}
|
|
39268
|
-
return false;
|
|
39269
|
-
}
|
|
39270
39315
|
function ask(rl, question) {
|
|
39271
39316
|
return new Promise((resolve34) => {
|
|
39272
39317
|
rl.question(question, (answer) => resolve34(answer.trim()));
|
|
@@ -40065,33 +40110,42 @@ async function doSetup(config, rl) {
|
|
|
40065
40110
|
process.stdout.write(` ${c2.yellow("\u26A0")} Default model ${c2.bold(config.model)} is not available.
|
|
40066
40111
|
|
|
40067
40112
|
`);
|
|
40068
|
-
|
|
40069
|
-
|
|
40070
|
-
|
|
40113
|
+
if (models.length > 0) {
|
|
40114
|
+
const backendUrl = config.backendUrl || "http://localhost:11434";
|
|
40115
|
+
const modelChecks = await Promise.all(models.slice(0, 15).map(async (m) => ({
|
|
40116
|
+
...m,
|
|
40117
|
+
hasTools: await checkToolSupport(m.name, backendUrl)
|
|
40118
|
+
})));
|
|
40119
|
+
process.stdout.write(` ${c2.cyan("\u25CF")} Available models:
|
|
40071
40120
|
|
|
40072
40121
|
`);
|
|
40073
|
-
for (let i = 0; i <
|
|
40074
|
-
const m =
|
|
40075
|
-
|
|
40122
|
+
for (let i = 0; i < modelChecks.length; i++) {
|
|
40123
|
+
const m = modelChecks[i];
|
|
40124
|
+
const toolTag = m.hasTools ? c2.green("tools \u2713") : c2.yellow("text mode");
|
|
40125
|
+
process.stdout.write(` ${c2.bold(String(i + 1))}. ${m.name} ${c2.dim(`(${m.size})`)} ${toolTag}
|
|
40076
40126
|
`);
|
|
40077
40127
|
}
|
|
40078
40128
|
process.stdout.write(`
|
|
40079
40129
|
${c2.dim("0")}. Pull a new qwen3.5 model instead
|
|
40130
|
+
`);
|
|
40131
|
+
process.stdout.write(`
|
|
40132
|
+
${c2.dim("Models marked 'text mode' work via instruct-and-parse (no native tool API needed)")}
|
|
40080
40133
|
`);
|
|
40081
40134
|
process.stdout.write("\n");
|
|
40082
|
-
const choice = await ask(rl, ` ${c2.bold("Select a model")} (1-${
|
|
40135
|
+
const choice = await ask(rl, ` ${c2.bold("Select a model")} (1-${modelChecks.length}, or 0 to pull new): `);
|
|
40083
40136
|
const idx = parseInt(choice, 10);
|
|
40084
|
-
if (idx > 0 && idx <=
|
|
40085
|
-
const selected =
|
|
40137
|
+
if (idx > 0 && idx <= modelChecks.length) {
|
|
40138
|
+
const selected = modelChecks[idx - 1];
|
|
40086
40139
|
setConfigValue("model", selected.name);
|
|
40140
|
+
const mode = selected.hasTools ? "native tool calling" : "text mode (instruct-and-parse)";
|
|
40087
40141
|
process.stdout.write(`
|
|
40088
|
-
${c2.green("\u2714")} Selected ${c2.bold(selected.name)}. Saved to config.
|
|
40142
|
+
${c2.green("\u2714")} Selected ${c2.bold(selected.name)} \u2014 ${mode}. Saved to config.
|
|
40089
40143
|
|
|
40090
40144
|
`);
|
|
40091
40145
|
return selected.name;
|
|
40092
40146
|
}
|
|
40093
40147
|
} else {
|
|
40094
|
-
process.stdout.write(` ${c2.yellow("\u26A0")} No
|
|
40148
|
+
process.stdout.write(` ${c2.yellow("\u26A0")} No models found on this system.
|
|
40095
40149
|
|
|
40096
40150
|
`);
|
|
40097
40151
|
}
|
|
@@ -40809,7 +40863,7 @@ export PATH="${binDir}:$PATH" # Added by open-agents for nvim
|
|
|
40809
40863
|
} catch {
|
|
40810
40864
|
}
|
|
40811
40865
|
}
|
|
40812
|
-
var execAsync, QWEN_VARIANTS,
|
|
40866
|
+
var execAsync, QWEN_VARIANTS, _toolSupportCache, _cloudflaredInstallPromise;
|
|
40813
40867
|
var init_setup = __esm({
|
|
40814
40868
|
"packages/cli/dist/tui/setup.js"() {
|
|
40815
40869
|
"use strict";
|
|
@@ -40829,19 +40883,7 @@ var init_setup = __esm({
|
|
|
40829
40883
|
{ tag: "qwen3.5:cloud", sizeGB: 0, label: "Cloud (Ollama Cloud)", cloud: true },
|
|
40830
40884
|
{ tag: "qwen3.5:397b-cloud", sizeGB: 0, label: "397B Cloud (Ollama Cloud)", cloud: true }
|
|
40831
40885
|
];
|
|
40832
|
-
|
|
40833
|
-
"qwen3.5",
|
|
40834
|
-
"qwen3",
|
|
40835
|
-
"qwen2.5",
|
|
40836
|
-
"llama3.3",
|
|
40837
|
-
"llama3.1",
|
|
40838
|
-
"mistral",
|
|
40839
|
-
"mixtral",
|
|
40840
|
-
"command-r",
|
|
40841
|
-
"gemma3",
|
|
40842
|
-
"devstral",
|
|
40843
|
-
"deepseek"
|
|
40844
|
-
]);
|
|
40886
|
+
_toolSupportCache = /* @__PURE__ */ new Map();
|
|
40845
40887
|
_cloudflaredInstallPromise = null;
|
|
40846
40888
|
}
|
|
40847
40889
|
});
|
|
@@ -60073,9 +60115,17 @@ ${lines.join("\n")}
|
|
|
60073
60115
|
personalityName: personality ?? void 0,
|
|
60074
60116
|
identityInjection,
|
|
60075
60117
|
environmentProvider
|
|
60118
|
+
// Text tool mode is set dynamically after runner creation (async check)
|
|
60119
|
+
// The runner also auto-detects this when Ollama returns HTTP 400 for tools
|
|
60076
60120
|
});
|
|
60077
60121
|
runner.setWorkingDirectory(repoRoot);
|
|
60078
60122
|
_activeRunnerRef = runner;
|
|
60123
|
+
needsTextToolMode(config.model, config.backendUrl).then((needsText) => {
|
|
60124
|
+
if (needsText) {
|
|
60125
|
+
runner.options.textToolMode = true;
|
|
60126
|
+
}
|
|
60127
|
+
}).catch(() => {
|
|
60128
|
+
});
|
|
60079
60129
|
const tools = buildTools(repoRoot, config, contextWindowSize);
|
|
60080
60130
|
if (contextWindowSize && contextWindowSize > 0) {
|
|
60081
60131
|
for (const tool of tools) {
|
package/package.json
CHANGED