@holoscript/holoscript-agent 2.1.2 → 2.1.3
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 +67 -0
- package/dist/index.js.map +1 -1
- package/dist/runner.js +67 -0
- package/dist/runner.js.map +1 -1
- package/dist/supervisor.js +67 -0
- package/dist/supervisor.js.map +1 -1
- package/package.json +1 -1
package/dist/runner.js
CHANGED
|
@@ -156,6 +156,8 @@ function isProductiveToolUse(use) {
|
|
|
156
156
|
return true;
|
|
157
157
|
case "str_replace":
|
|
158
158
|
return true;
|
|
159
|
+
case "vision_analyze":
|
|
160
|
+
return true;
|
|
159
161
|
default:
|
|
160
162
|
return false;
|
|
161
163
|
}
|
|
@@ -292,6 +294,28 @@ var MESH_TOOLS = [
|
|
|
292
294
|
},
|
|
293
295
|
required: ["title"]
|
|
294
296
|
}
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
name: "vision_analyze",
|
|
300
|
+
description: "Analyze an image using the local Fara-7B vision model (Ollama on loopback). Reads the image file at `image_path`, sends it to fara:7b via the local Ollama API, and returns the model's text analysis. Counts as a productive tool call \u2014 use for GUI-grounding, visual QA, image captioning, or any task that requires perceiving image content. Only available on surfaces with a local Ollama instance running fara:7b.",
|
|
301
|
+
input_schema: {
|
|
302
|
+
type: "object",
|
|
303
|
+
properties: {
|
|
304
|
+
image_path: {
|
|
305
|
+
type: "string",
|
|
306
|
+
description: "Absolute path to the image file (png, jpg, webp, gif)"
|
|
307
|
+
},
|
|
308
|
+
prompt: {
|
|
309
|
+
type: "string",
|
|
310
|
+
description: 'Instruction for the vision model (default: "Describe this image in detail.")'
|
|
311
|
+
},
|
|
312
|
+
model: {
|
|
313
|
+
type: "string",
|
|
314
|
+
description: 'Ollama model tag to use (default: "fara:7b")'
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
required: ["image_path"]
|
|
318
|
+
}
|
|
295
319
|
}
|
|
296
320
|
];
|
|
297
321
|
function resolveActiveTools(brain, opts = {}) {
|
|
@@ -535,6 +559,49 @@ ${truncated}`);
|
|
|
535
559
|
const result = await opts.addTask([{ title, description, priority: priority2, source, tags }]);
|
|
536
560
|
return okResult(use.id, `delegate_task: posted "${title}" to board \u2014 ${result.added} task(s) added`);
|
|
537
561
|
}
|
|
562
|
+
if (use.name === "vision_analyze") {
|
|
563
|
+
const imagePath = String(use.input.image_path ?? "").trim();
|
|
564
|
+
if (!imagePath) return errResult(use.id, "vision_analyze: image_path is required");
|
|
565
|
+
const denied = checkReadAllowed(imagePath);
|
|
566
|
+
if (denied) return errResult(use.id, `vision_analyze: ${denied}`);
|
|
567
|
+
const prompt = String(use.input.prompt ?? "Describe this image in detail.");
|
|
568
|
+
const model = String(use.input.model ?? "fara:7b");
|
|
569
|
+
const ollamaBase = process.env.HOLOSCRIPT_AGENT_LOCAL_LLM_BASE_URL;
|
|
570
|
+
if (!ollamaBase) {
|
|
571
|
+
return errResult(
|
|
572
|
+
use.id,
|
|
573
|
+
"vision_analyze: HOLOSCRIPT_AGENT_LOCAL_LLM_BASE_URL is not set \u2014 configure it to point to your local Ollama instance (e.g. http://holojetson.local:11434)"
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
const TIMEOUT_MS = 12e4;
|
|
577
|
+
const controller = new AbortController();
|
|
578
|
+
const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
579
|
+
try {
|
|
580
|
+
const imageBytes = await readFile2(imagePath);
|
|
581
|
+
const imageB64 = imageBytes.toString("base64");
|
|
582
|
+
const res = await fetch(`${ollamaBase}/api/generate`, {
|
|
583
|
+
method: "POST",
|
|
584
|
+
headers: { "content-type": "application/json" },
|
|
585
|
+
body: JSON.stringify({ model, prompt, images: [imageB64], stream: false }),
|
|
586
|
+
signal: controller.signal
|
|
587
|
+
});
|
|
588
|
+
clearTimeout(timer);
|
|
589
|
+
if (!res.ok) {
|
|
590
|
+
const text = await res.text();
|
|
591
|
+
return errResult(use.id, `vision_analyze: Ollama HTTP ${res.status}: ${text.slice(0, 500)}`);
|
|
592
|
+
}
|
|
593
|
+
const json = await res.json();
|
|
594
|
+
if (json.error) return errResult(use.id, `vision_analyze: model error \u2014 ${json.error}`);
|
|
595
|
+
return okResult(use.id, json.response ?? "");
|
|
596
|
+
} catch (err) {
|
|
597
|
+
clearTimeout(timer);
|
|
598
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
599
|
+
return errResult(
|
|
600
|
+
use.id,
|
|
601
|
+
msg.includes("abort") ? `vision_analyze: timed out after ${TIMEOUT_MS}ms` : `vision_analyze: ${msg}`
|
|
602
|
+
);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
538
605
|
return errResult(use.id, `unknown tool: ${use.name}`);
|
|
539
606
|
} catch (err) {
|
|
540
607
|
return errResult(use.id, err instanceof Error ? err.message : String(err));
|