open-agents-ai 0.187.592 → 0.187.593
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 +330 -94
- package/npm-shrinkwrap.json +5 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -527374,9 +527374,11 @@ RECOVERY: cd to the directory containing '${file}', run a plain install with no
|
|
|
527374
527374
|
});
|
|
527375
527375
|
|
|
527376
527376
|
// packages/orchestrator/dist/agenticRunner.js
|
|
527377
|
-
import { existsSync as _fsExistsSync, readFileSync as _fsReadFileSync, writeFileSync as _fsWriteFileSync, mkdirSync as _fsMkdirSync } from "node:fs";
|
|
527377
|
+
import { existsSync as _fsExistsSync, readFileSync as _fsReadFileSync, writeFileSync as _fsWriteFileSync, unlinkSync as _fsUnlinkSync, mkdirSync as _fsMkdirSync } from "node:fs";
|
|
527378
|
+
import { execFile as _execFile } from "node:child_process";
|
|
527378
527379
|
import { createHash as _createHash } from "node:crypto";
|
|
527379
527380
|
import { join as _pathJoin } from "node:path";
|
|
527381
|
+
import { tmpdir as _osTmpdir } from "node:os";
|
|
527380
527382
|
import { homedir as _osHomedir } from "node:os";
|
|
527381
527383
|
import { z as z15 } from "zod";
|
|
527382
527384
|
function repairJson(raw) {
|
|
@@ -532289,45 +532291,7 @@ ${_staleSamples.join("\n")}` : ``,
|
|
|
532289
532291
|
}
|
|
532290
532292
|
while (this.pendingUserMessages.length > 0) {
|
|
532291
532293
|
const userMsg = this.pendingUserMessages.shift();
|
|
532292
|
-
|
|
532293
|
-
const imgMatch = userMsg.match(imagePattern);
|
|
532294
|
-
if (imgMatch) {
|
|
532295
|
-
const mime = imgMatch[1];
|
|
532296
|
-
const base642 = imgMatch[2];
|
|
532297
|
-
const textContent = userMsg.replace(imagePattern, "").trim();
|
|
532298
|
-
const parts = [];
|
|
532299
|
-
if (textContent) {
|
|
532300
|
-
parts.push({
|
|
532301
|
-
type: "text",
|
|
532302
|
-
text: `[User added context]: ${textContent}
|
|
532303
|
-
|
|
532304
|
-
Describe what you see and integrate this into your current approach.`
|
|
532305
|
-
});
|
|
532306
|
-
} else {
|
|
532307
|
-
parts.push({
|
|
532308
|
-
type: "text",
|
|
532309
|
-
text: "[User shared an image]. Describe what you see and integrate this into your current approach."
|
|
532310
|
-
});
|
|
532311
|
-
}
|
|
532312
|
-
parts.push({
|
|
532313
|
-
type: "image_url",
|
|
532314
|
-
image_url: { url: `data:${mime};base64,${base642}` }
|
|
532315
|
-
});
|
|
532316
|
-
messages2.push({ role: "user", content: parts });
|
|
532317
|
-
} else {
|
|
532318
|
-
messages2.push({
|
|
532319
|
-
role: "user",
|
|
532320
|
-
content: `[User added context]: ${userMsg}
|
|
532321
|
-
|
|
532322
|
-
Integrate this guidance into your current approach. Continue working on the task.`
|
|
532323
|
-
});
|
|
532324
|
-
}
|
|
532325
|
-
this.emit({
|
|
532326
|
-
type: "user_interrupt",
|
|
532327
|
-
content: userMsg.replace(/\[IMAGE_BASE64:[^\]]+\]/, "[image]").slice(0, 200),
|
|
532328
|
-
turn,
|
|
532329
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
532330
|
-
});
|
|
532294
|
+
await this.appendInjectedUserMessage(userMsg, messages2, turn);
|
|
532331
532295
|
}
|
|
532332
532296
|
{
|
|
532333
532297
|
const maybeReminder = this.getTodoReminderContent(turn);
|
|
@@ -532648,12 +532612,28 @@ ${memoryLines.join("\n")}`
|
|
|
532648
532612
|
timeoutMs: this.options.requestTimeoutMs
|
|
532649
532613
|
};
|
|
532650
532614
|
{
|
|
532615
|
+
const _imgB64Pat = /\[IMAGE_BASE64:[^\]]+\]/g;
|
|
532651
532616
|
const ctxChars = compacted.reduce((s2, m2) => {
|
|
532652
|
-
let c9 =
|
|
532617
|
+
let c9 = 0;
|
|
532618
|
+
let imgCount = 0;
|
|
532619
|
+
if (typeof m2.content === "string") {
|
|
532620
|
+
const imgMatches = m2.content.match(_imgB64Pat);
|
|
532621
|
+
imgCount = imgMatches ? imgMatches.length : 0;
|
|
532622
|
+
c9 = m2.content.replace(_imgB64Pat, "").length;
|
|
532623
|
+
} else if (Array.isArray(m2.content)) {
|
|
532624
|
+
for (const p2 of m2.content) {
|
|
532625
|
+
if (p2.type === "text" && p2.text)
|
|
532626
|
+
c9 += p2.text.length;
|
|
532627
|
+
else if (p2.type === "image_url")
|
|
532628
|
+
imgCount++;
|
|
532629
|
+
}
|
|
532630
|
+
} else {
|
|
532631
|
+
c9 = 100;
|
|
532632
|
+
}
|
|
532653
532633
|
if (m2.tool_calls)
|
|
532654
532634
|
for (const tc of m2.tool_calls)
|
|
532655
532635
|
c9 += tc.function.arguments?.length ?? 0;
|
|
532656
|
-
return s2 + c9;
|
|
532636
|
+
return s2 + c9 + imgCount * 1500 * 4;
|
|
532657
532637
|
}, 0);
|
|
532658
532638
|
const estTokens = Math.ceil(ctxChars / 4);
|
|
532659
532639
|
const limits = this.contextLimits();
|
|
@@ -532867,13 +532847,31 @@ ${memoryLines.join("\n")}`
|
|
|
532867
532847
|
const choiceContent = response.choices[0]?.message?.content ?? "";
|
|
532868
532848
|
const choiceArgs = response.choices[0]?.message?.toolCalls?.map((tc) => JSON.stringify(tc.arguments)).join("") ?? "";
|
|
532869
532849
|
estimatedTokens += Math.ceil((choiceContent.length + choiceArgs.length) / 4);
|
|
532850
|
+
const IMAGE_TOKEN_ESTIMATE = 1500;
|
|
532851
|
+
const imageBase64Pattern = /\[IMAGE_BASE64:[^\]]+\]/g;
|
|
532870
532852
|
const estimatedContextTokens = Math.ceil(compacted.reduce((sum, m2) => {
|
|
532871
|
-
let chars =
|
|
532853
|
+
let chars = 0;
|
|
532854
|
+
let imageCount = 0;
|
|
532855
|
+
if (typeof m2.content === "string") {
|
|
532856
|
+
const imageMatches = m2.content.match(imageBase64Pattern);
|
|
532857
|
+
imageCount = imageMatches ? imageMatches.length : 0;
|
|
532858
|
+
chars = m2.content.replace(imageBase64Pattern, "").length;
|
|
532859
|
+
} else if (Array.isArray(m2.content)) {
|
|
532860
|
+
for (const part of m2.content) {
|
|
532861
|
+
if (part.type === "text" && part.text) {
|
|
532862
|
+
chars += part.text.length;
|
|
532863
|
+
} else if (part.type === "image_url") {
|
|
532864
|
+
imageCount++;
|
|
532865
|
+
}
|
|
532866
|
+
}
|
|
532867
|
+
} else {
|
|
532868
|
+
chars = 100;
|
|
532869
|
+
}
|
|
532872
532870
|
if (m2.tool_calls) {
|
|
532873
532871
|
for (const tc of m2.tool_calls)
|
|
532874
532872
|
chars += tc.function.arguments?.length ?? 0;
|
|
532875
532873
|
}
|
|
532876
|
-
return sum + chars;
|
|
532874
|
+
return sum + chars + imageCount * IMAGE_TOKEN_ESTIMATE * 4;
|
|
532877
532875
|
}, 0) / 4);
|
|
532878
532876
|
this.emit({
|
|
532879
532877
|
type: "token_usage",
|
|
@@ -535327,45 +535325,7 @@ You have ${this.options.maxTurns} more turns. Continue making progress. Call tas
|
|
|
535327
535325
|
}
|
|
535328
535326
|
while (this.pendingUserMessages.length > 0) {
|
|
535329
535327
|
const userMsg = this.pendingUserMessages.shift();
|
|
535330
|
-
|
|
535331
|
-
const imgMatch = userMsg.match(imagePattern);
|
|
535332
|
-
if (imgMatch) {
|
|
535333
|
-
const mime = imgMatch[1];
|
|
535334
|
-
const base642 = imgMatch[2];
|
|
535335
|
-
const textContent = userMsg.replace(imagePattern, "").trim();
|
|
535336
|
-
const parts = [];
|
|
535337
|
-
if (textContent) {
|
|
535338
|
-
parts.push({
|
|
535339
|
-
type: "text",
|
|
535340
|
-
text: `[User added context]: ${textContent}
|
|
535341
|
-
|
|
535342
|
-
Describe what you see and integrate this into your current approach.`
|
|
535343
|
-
});
|
|
535344
|
-
} else {
|
|
535345
|
-
parts.push({
|
|
535346
|
-
type: "text",
|
|
535347
|
-
text: "[User shared an image]. Describe what you see and integrate this into your current approach."
|
|
535348
|
-
});
|
|
535349
|
-
}
|
|
535350
|
-
parts.push({
|
|
535351
|
-
type: "image_url",
|
|
535352
|
-
image_url: { url: `data:${mime};base64,${base642}` }
|
|
535353
|
-
});
|
|
535354
|
-
messages2.push({ role: "user", content: parts });
|
|
535355
|
-
} else {
|
|
535356
|
-
messages2.push({
|
|
535357
|
-
role: "user",
|
|
535358
|
-
content: `[User added context]: ${userMsg}
|
|
535359
|
-
|
|
535360
|
-
Integrate this guidance into your current approach. Continue working on the task.`
|
|
535361
|
-
});
|
|
535362
|
-
}
|
|
535363
|
-
this.emit({
|
|
535364
|
-
type: "user_interrupt",
|
|
535365
|
-
content: userMsg.replace(/\[IMAGE_BASE64:[^\]]+\]/, "[image]").slice(0, 200),
|
|
535366
|
-
turn,
|
|
535367
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
535368
|
-
});
|
|
535328
|
+
await this.appendInjectedUserMessage(userMsg, messages2, turn);
|
|
535369
535329
|
}
|
|
535370
535330
|
let compactedMsgs;
|
|
535371
535331
|
if (this._pendingCompaction) {
|
|
@@ -535440,13 +535400,29 @@ Integrate this guidance into your current approach. Continue working on the task
|
|
|
535440
535400
|
const choiceContent2 = response.choices[0]?.message?.content ?? "";
|
|
535441
535401
|
const choiceArgs2 = response.choices[0]?.message?.toolCalls?.map((tc) => JSON.stringify(tc.arguments)).join("") ?? "";
|
|
535442
535402
|
estimatedTokens += Math.ceil((choiceContent2.length + choiceArgs2.length) / 4);
|
|
535403
|
+
const _bfImgPat = /\[IMAGE_BASE64:[^\]]+\]/g;
|
|
535443
535404
|
const bfEstCtx = Math.ceil(compactedMsgs.reduce((sum, m2) => {
|
|
535444
|
-
let chars =
|
|
535405
|
+
let chars = 0;
|
|
535406
|
+
let imgCount = 0;
|
|
535407
|
+
if (typeof m2.content === "string") {
|
|
535408
|
+
const imgMatches = m2.content.match(_bfImgPat);
|
|
535409
|
+
imgCount = imgMatches ? imgMatches.length : 0;
|
|
535410
|
+
chars = m2.content.replace(_bfImgPat, "").length;
|
|
535411
|
+
} else if (Array.isArray(m2.content)) {
|
|
535412
|
+
for (const p2 of m2.content) {
|
|
535413
|
+
if (p2.type === "text" && p2.text)
|
|
535414
|
+
chars += p2.text.length;
|
|
535415
|
+
else if (p2.type === "image_url")
|
|
535416
|
+
imgCount++;
|
|
535417
|
+
}
|
|
535418
|
+
} else {
|
|
535419
|
+
chars = 100;
|
|
535420
|
+
}
|
|
535445
535421
|
if (m2.tool_calls) {
|
|
535446
535422
|
for (const tc of m2.tool_calls)
|
|
535447
535423
|
chars += tc.function.arguments?.length ?? 0;
|
|
535448
535424
|
}
|
|
535449
|
-
return sum + chars;
|
|
535425
|
+
return sum + chars + imgCount * 1500 * 4;
|
|
535450
535426
|
}, 0) / 4);
|
|
535451
535427
|
this.emit({
|
|
535452
535428
|
type: "token_usage",
|
|
@@ -536874,18 +536850,187 @@ ${tail}`;
|
|
|
536874
536850
|
}
|
|
536875
536851
|
return folded;
|
|
536876
536852
|
}
|
|
536853
|
+
async appendInjectedUserMessage(userMsg, messages2, turn) {
|
|
536854
|
+
const imagePattern = /\[IMAGE_BASE64:([^:]+):([^\]]+)\]/;
|
|
536855
|
+
const imgMatch = userMsg.match(imagePattern);
|
|
536856
|
+
if (imgMatch) {
|
|
536857
|
+
const mime = imgMatch[1];
|
|
536858
|
+
const base642 = imgMatch[2];
|
|
536859
|
+
const textContent = userMsg.replace(imagePattern, "").trim();
|
|
536860
|
+
await this.appendOffloadedImageMessage(messages2, mime, base642, textContent, turn);
|
|
536861
|
+
} else {
|
|
536862
|
+
messages2.push({
|
|
536863
|
+
role: "user",
|
|
536864
|
+
content: `[User added context]: ${userMsg}
|
|
536865
|
+
|
|
536866
|
+
Integrate this guidance into your current approach. Continue working on the task.`
|
|
536867
|
+
});
|
|
536868
|
+
}
|
|
536869
|
+
this.emit({
|
|
536870
|
+
type: "user_interrupt",
|
|
536871
|
+
content: userMsg.replace(/\[IMAGE_BASE64:[^\]]+\]/, "[image]").slice(0, 200),
|
|
536872
|
+
turn,
|
|
536873
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
536874
|
+
});
|
|
536875
|
+
}
|
|
536876
|
+
async appendOffloadedImageMessage(messages2, mime, base642, textContent, turn) {
|
|
536877
|
+
const imageUrl = `data:${mime};base64,${base642}`;
|
|
536878
|
+
this.emit({
|
|
536879
|
+
type: "status",
|
|
536880
|
+
content: "Image received; offloading visual analysis outside main context",
|
|
536881
|
+
turn,
|
|
536882
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
536883
|
+
});
|
|
536884
|
+
const tmpImgPath = this.writeTempImageForOcr(mime, base642);
|
|
536885
|
+
const [visionOutcome, ocrOutcome] = await Promise.allSettled([
|
|
536886
|
+
this.describeImageViaVisionSubagent(imageUrl, textContent),
|
|
536887
|
+
tmpImgPath ? this.extractImageOcrText(tmpImgPath) : Promise.resolve("")
|
|
536888
|
+
]);
|
|
536889
|
+
const visionDesc = visionOutcome.status === "fulfilled" ? visionOutcome.value.trim() : "";
|
|
536890
|
+
const ocrText = ocrOutcome.status === "fulfilled" ? ocrOutcome.value.trim() : "";
|
|
536891
|
+
if (visionDesc || ocrText) {
|
|
536892
|
+
const sections = [];
|
|
536893
|
+
if (visionDesc)
|
|
536894
|
+
sections.push(`[Image analysis]: ${visionDesc}`);
|
|
536895
|
+
if (ocrText)
|
|
536896
|
+
sections.push(`[OCR extracted text]: ${ocrText}`);
|
|
536897
|
+
const userPrefix = textContent ? `[User added context]: ${textContent}
|
|
536898
|
+
|
|
536899
|
+
` : "[User shared an image]. ";
|
|
536900
|
+
messages2.push({
|
|
536901
|
+
role: "user",
|
|
536902
|
+
content: userPrefix + sections.join("\n\n") + "\n\nIntegrate this visual information into your current approach."
|
|
536903
|
+
});
|
|
536904
|
+
this.emit({
|
|
536905
|
+
type: "status",
|
|
536906
|
+
content: "Image analysis added as text; base64 excluded from main context",
|
|
536907
|
+
turn,
|
|
536908
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
536909
|
+
});
|
|
536910
|
+
return;
|
|
536911
|
+
}
|
|
536912
|
+
const reason = visionOutcome.status === "rejected" ? String(visionOutcome.reason?.message ?? visionOutcome.reason) : "vision and OCR returned no text";
|
|
536913
|
+
this.emit({
|
|
536914
|
+
type: "status",
|
|
536915
|
+
content: `Image offload unavailable (${reason}); falling back to inline image`,
|
|
536916
|
+
turn,
|
|
536917
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
536918
|
+
});
|
|
536919
|
+
this.appendInlineImageMessage(messages2, imageUrl, textContent);
|
|
536920
|
+
}
|
|
536921
|
+
async describeImageViaVisionSubagent(imageUrl, textContent) {
|
|
536922
|
+
const visionMessages = [
|
|
536923
|
+
{
|
|
536924
|
+
role: "system",
|
|
536925
|
+
content: "You are a visual analysis sub-agent. Describe the image in detail, including visible text, UI elements, code, diagrams, errors, and other task-relevant visual details. Be thorough but concise."
|
|
536926
|
+
},
|
|
536927
|
+
{
|
|
536928
|
+
role: "user",
|
|
536929
|
+
content: [
|
|
536930
|
+
{
|
|
536931
|
+
type: "text",
|
|
536932
|
+
text: textContent ? `Context from user: ${textContent}
|
|
536933
|
+
|
|
536934
|
+
Describe what you see in this image.` : "Describe what you see in this image in detail."
|
|
536935
|
+
},
|
|
536936
|
+
{ type: "image_url", image_url: { url: imageUrl } }
|
|
536937
|
+
]
|
|
536938
|
+
}
|
|
536939
|
+
];
|
|
536940
|
+
const result = await this.backend.chatCompletion({
|
|
536941
|
+
messages: visionMessages,
|
|
536942
|
+
tools: [],
|
|
536943
|
+
temperature: 0.3,
|
|
536944
|
+
maxTokens: 2048,
|
|
536945
|
+
timeoutMs: 3e4,
|
|
536946
|
+
think: false
|
|
536947
|
+
});
|
|
536948
|
+
return result.choices[0]?.message?.content ?? "";
|
|
536949
|
+
}
|
|
536950
|
+
appendInlineImageMessage(messages2, imageUrl, textContent) {
|
|
536951
|
+
const parts = [
|
|
536952
|
+
{
|
|
536953
|
+
type: "text",
|
|
536954
|
+
text: textContent ? `[User added context]: ${textContent}
|
|
536955
|
+
|
|
536956
|
+
Describe what you see and integrate this into your current approach.` : "[User shared an image]. Describe what you see and integrate this into your current approach."
|
|
536957
|
+
},
|
|
536958
|
+
{ type: "image_url", image_url: { url: imageUrl } }
|
|
536959
|
+
];
|
|
536960
|
+
messages2.push({ role: "user", content: parts });
|
|
536961
|
+
}
|
|
536962
|
+
writeTempImageForOcr(mime, base642) {
|
|
536963
|
+
try {
|
|
536964
|
+
const ext = this.imageExtensionForMime(mime);
|
|
536965
|
+
const id = _createHash("sha256").update(`${process.pid}:${Date.now()}:`).update(base642.slice(0, 4096)).digest("hex").slice(0, 16);
|
|
536966
|
+
const tmpImgPath = _pathJoin(_osTmpdir(), `oa-img-${id}.${ext}`);
|
|
536967
|
+
_fsWriteFileSync(tmpImgPath, Buffer.from(base642, "base64"));
|
|
536968
|
+
return tmpImgPath;
|
|
536969
|
+
} catch {
|
|
536970
|
+
return null;
|
|
536971
|
+
}
|
|
536972
|
+
}
|
|
536973
|
+
imageExtensionForMime(mime) {
|
|
536974
|
+
const normalized = mime.toLowerCase();
|
|
536975
|
+
if (normalized.includes("jpeg") || normalized.includes("jpg"))
|
|
536976
|
+
return "jpg";
|
|
536977
|
+
if (normalized.includes("webp"))
|
|
536978
|
+
return "webp";
|
|
536979
|
+
if (normalized.includes("gif"))
|
|
536980
|
+
return "gif";
|
|
536981
|
+
if (normalized.includes("bmp"))
|
|
536982
|
+
return "bmp";
|
|
536983
|
+
if (normalized.includes("tiff"))
|
|
536984
|
+
return "tif";
|
|
536985
|
+
return "png";
|
|
536986
|
+
}
|
|
536987
|
+
async extractImageOcrText(tmpImgPath) {
|
|
536988
|
+
try {
|
|
536989
|
+
const stdout = await new Promise((resolve44, reject) => {
|
|
536990
|
+
_execFile("tesseract", [tmpImgPath, "stdout"], {
|
|
536991
|
+
encoding: "utf8",
|
|
536992
|
+
timeout: 15e3,
|
|
536993
|
+
maxBuffer: 2 * 1024 * 1024
|
|
536994
|
+
}, (err, out) => {
|
|
536995
|
+
if (err) {
|
|
536996
|
+
reject(err);
|
|
536997
|
+
return;
|
|
536998
|
+
}
|
|
536999
|
+
resolve44(out);
|
|
537000
|
+
});
|
|
537001
|
+
});
|
|
537002
|
+
return stdout.trim();
|
|
537003
|
+
} catch {
|
|
537004
|
+
return "";
|
|
537005
|
+
} finally {
|
|
537006
|
+
try {
|
|
537007
|
+
_fsUnlinkSync(tmpImgPath);
|
|
537008
|
+
} catch {
|
|
537009
|
+
}
|
|
537010
|
+
}
|
|
537011
|
+
}
|
|
536877
537012
|
// -------------------------------------------------------------------------
|
|
536878
537013
|
// Context compaction
|
|
536879
537014
|
// -------------------------------------------------------------------------
|
|
536880
537015
|
async compactMessages(messages2, strategy = "default", force = false) {
|
|
536881
537016
|
if (messages2.length < 3)
|
|
536882
537017
|
return messages2;
|
|
537018
|
+
const _compImgPat = /\[IMAGE_BASE64:[^\]]+\]/g;
|
|
536883
537019
|
const totalChars = messages2.reduce((sum, m2) => {
|
|
536884
537020
|
let chars = 0;
|
|
536885
|
-
if (typeof m2.content === "string")
|
|
536886
|
-
|
|
536887
|
-
|
|
536888
|
-
chars += m2.content.
|
|
537021
|
+
if (typeof m2.content === "string") {
|
|
537022
|
+
const imgMatches = m2.content.match(_compImgPat);
|
|
537023
|
+
const imgCount = imgMatches ? imgMatches.length : 0;
|
|
537024
|
+
chars += m2.content.replace(_compImgPat, "").length + imgCount * 1500 * 4;
|
|
537025
|
+
} else if (Array.isArray(m2.content)) {
|
|
537026
|
+
chars += m2.content.reduce((s2, p2) => {
|
|
537027
|
+
if (p2.type === "text" && p2.text)
|
|
537028
|
+
return s2 + p2.text.length;
|
|
537029
|
+
if (p2.type === "image_url" && p2.image_url?.url) {
|
|
537030
|
+
return s2 + 1500 * 4;
|
|
537031
|
+
}
|
|
537032
|
+
return s2;
|
|
537033
|
+
}, 0);
|
|
536889
537034
|
}
|
|
536890
537035
|
if (m2.tool_calls) {
|
|
536891
537036
|
for (const tc of m2.tool_calls) {
|
|
@@ -536923,7 +537068,22 @@ ${tail}`;
|
|
|
536923
537068
|
let budgetCut = messages2.length;
|
|
536924
537069
|
for (let i2 = messages2.length - 1; i2 >= headEndIdx; i2--) {
|
|
536925
537070
|
const msg = messages2[i2];
|
|
536926
|
-
|
|
537071
|
+
let msgChars = 0;
|
|
537072
|
+
if (typeof msg.content === "string") {
|
|
537073
|
+
const _mImgPat = /\[IMAGE_BASE64:[^\]]+\]/g;
|
|
537074
|
+
const imgMatches = msg.content.match(_mImgPat);
|
|
537075
|
+
const imgCount = imgMatches ? imgMatches.length : 0;
|
|
537076
|
+
msgChars = msg.content.replace(_mImgPat, "").length + imgCount * 1500 * 4;
|
|
537077
|
+
} else if (Array.isArray(msg.content)) {
|
|
537078
|
+
for (const p2 of msg.content) {
|
|
537079
|
+
if (p2.type === "text" && p2.text)
|
|
537080
|
+
msgChars += p2.text.length;
|
|
537081
|
+
else if (p2.type === "image_url")
|
|
537082
|
+
msgChars += 1500 * 4;
|
|
537083
|
+
}
|
|
537084
|
+
} else {
|
|
537085
|
+
msgChars = 100;
|
|
537086
|
+
}
|
|
536927
537087
|
const toolCallChars = (msg.tool_calls || []).reduce((s2, tc) => s2 + (tc.function?.arguments?.length || 0) + (tc.function?.name?.length || 0), 0);
|
|
536928
537088
|
const msgTokens = Math.ceil((msgChars + toolCallChars) / 4) + 10;
|
|
536929
537089
|
if (accumulated + msgTokens > tailTokenBudget && messages2.length - i2 >= 4) {
|
|
@@ -537032,7 +537192,25 @@ ${tail}`;
|
|
|
537032
537192
|
const strategyLabel = strategy !== "default" ? ` (${strategy})` : "";
|
|
537033
537193
|
const forceLabel = force ? " [manual]" : "";
|
|
537034
537194
|
const preTokens = Math.ceil(totalChars / 4);
|
|
537035
|
-
const
|
|
537195
|
+
const _postImgPat = /\[IMAGE_BASE64:[^\]]+\]/g;
|
|
537196
|
+
const _estimateMsgChars = (m2) => {
|
|
537197
|
+
if (typeof m2.content === "string") {
|
|
537198
|
+
const imgMatches = m2.content.match(_postImgPat);
|
|
537199
|
+
const imgCount = imgMatches ? imgMatches.length : 0;
|
|
537200
|
+
return m2.content.replace(_postImgPat, "").length + imgCount * 1500 * 4;
|
|
537201
|
+
} else if (Array.isArray(m2.content)) {
|
|
537202
|
+
let c9 = 0;
|
|
537203
|
+
for (const p2 of m2.content) {
|
|
537204
|
+
if (p2.type === "text" && p2.text)
|
|
537205
|
+
c9 += p2.text.length;
|
|
537206
|
+
else if (p2.type === "image_url")
|
|
537207
|
+
c9 += 1500 * 4;
|
|
537208
|
+
}
|
|
537209
|
+
return c9;
|
|
537210
|
+
}
|
|
537211
|
+
return 100;
|
|
537212
|
+
};
|
|
537213
|
+
const postChars = combinedSummary.length + recent.reduce((s2, m2) => s2 + _estimateMsgChars(m2), 0) + head.reduce((s2, m2) => s2 + _estimateMsgChars(m2), 0);
|
|
537036
537214
|
const postTokens = Math.ceil(postChars / 4);
|
|
537037
537215
|
const savedTokens = preTokens - postTokens;
|
|
537038
537216
|
this.emit({
|
|
@@ -537220,13 +537398,29 @@ ${content.slice(0, 8e3)}
|
|
|
537220
537398
|
}
|
|
537221
537399
|
const ctxWindow = this.options.contextWindowSize;
|
|
537222
537400
|
if (ctxWindow > 0) {
|
|
537401
|
+
const _safetyImgPat = /\[IMAGE_BASE64:[^\]]+\]/g;
|
|
537223
537402
|
const estimateResult = (msgs) => msgs.reduce((sum, m2) => {
|
|
537224
|
-
let chars =
|
|
537403
|
+
let chars = 0;
|
|
537404
|
+
let imgCount = 0;
|
|
537405
|
+
if (typeof m2.content === "string") {
|
|
537406
|
+
const imgMatches = m2.content.match(_safetyImgPat);
|
|
537407
|
+
imgCount = imgMatches ? imgMatches.length : 0;
|
|
537408
|
+
chars = m2.content.replace(_safetyImgPat, "").length;
|
|
537409
|
+
} else if (Array.isArray(m2.content)) {
|
|
537410
|
+
for (const p2 of m2.content) {
|
|
537411
|
+
if (p2.type === "text" && p2.text)
|
|
537412
|
+
chars += p2.text.length;
|
|
537413
|
+
else if (p2.type === "image_url")
|
|
537414
|
+
imgCount++;
|
|
537415
|
+
}
|
|
537416
|
+
} else {
|
|
537417
|
+
chars = 100;
|
|
537418
|
+
}
|
|
537225
537419
|
if (m2.tool_calls) {
|
|
537226
537420
|
for (const tc of m2.tool_calls)
|
|
537227
537421
|
chars += tc.function.arguments?.length ?? 0;
|
|
537228
537422
|
}
|
|
537229
|
-
return sum + chars;
|
|
537423
|
+
return sum + chars + imgCount * 1500 * 4;
|
|
537230
537424
|
}, 0) / 4;
|
|
537231
537425
|
const safetyTarget = Math.floor(ctxWindow * 0.65);
|
|
537232
537426
|
let trimmedRecent = [...filteredRecent];
|
|
@@ -538340,7 +538534,49 @@ ${transcript}`
|
|
|
538340
538534
|
"pascal_case",
|
|
538341
538535
|
"screaming_snake_case",
|
|
538342
538536
|
"dot_notation",
|
|
538343
|
-
"title_case"
|
|
538537
|
+
"title_case",
|
|
538538
|
+
// Conditionally-registered tools documented in the base system prompt
|
|
538539
|
+
// as available but only registered in TUI/desktop mode, NOT telegram:
|
|
538540
|
+
"background_run",
|
|
538541
|
+
// TUI-only: background shell execution
|
|
538542
|
+
"task_status",
|
|
538543
|
+
// TUI-only: check background task status
|
|
538544
|
+
"task_output",
|
|
538545
|
+
// TUI-only: read background task output
|
|
538546
|
+
"task_stop",
|
|
538547
|
+
// TUI-only: kill background task
|
|
538548
|
+
"skill_list",
|
|
538549
|
+
// TUI-only: discover available skills
|
|
538550
|
+
"skill_execute",
|
|
538551
|
+
// TUI-only: load and run a skill
|
|
538552
|
+
"skill_build",
|
|
538553
|
+
// TUI-only: generate a new skill
|
|
538554
|
+
"desktop_click",
|
|
538555
|
+
// TUI-only: click UI element by description
|
|
538556
|
+
"desktop_describe",
|
|
538557
|
+
// TUI-only: screenshot + describe desktop
|
|
538558
|
+
"repl_exec",
|
|
538559
|
+
// TUI-only: persistent Python REPL
|
|
538560
|
+
"cron_agent",
|
|
538561
|
+
// TUI-only: scheduled agent tasks
|
|
538562
|
+
"scheduler",
|
|
538563
|
+
// TUI-only: OS-level cron scheduling
|
|
538564
|
+
"reminder",
|
|
538565
|
+
// TUI-only: cross-session reminders
|
|
538566
|
+
"agenda",
|
|
538567
|
+
// TUI-only: attention directives
|
|
538568
|
+
"priority_classify",
|
|
538569
|
+
// TUI-only: task priority classification
|
|
538570
|
+
"priority_delegate",
|
|
538571
|
+
// TUI-only: delegate to sub-agent by priority
|
|
538572
|
+
"create_tool",
|
|
538573
|
+
// TUI-only: create custom tool
|
|
538574
|
+
"manage_tools",
|
|
538575
|
+
// TUI-only: list/inspect/delete custom tools
|
|
538576
|
+
"sub_agent",
|
|
538577
|
+
// TUI-only: delegate sub-task (telegram uses full_sub_agent)
|
|
538578
|
+
"nexus"
|
|
538579
|
+
// TUI-only: P2P networking
|
|
538344
538580
|
]);
|
|
538345
538581
|
for (const tool of this.tools.values()) {
|
|
538346
538582
|
const props = tool.parameters?.properties;
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-agents-ai",
|
|
3
|
-
"version": "0.187.
|
|
3
|
+
"version": "0.187.593",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "open-agents-ai",
|
|
9
|
-
"version": "0.187.
|
|
9
|
+
"version": "0.187.593",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "CC-BY-NC-4.0",
|
|
12
12
|
"dependencies": {
|
|
@@ -2049,9 +2049,9 @@
|
|
|
2049
2049
|
}
|
|
2050
2050
|
},
|
|
2051
2051
|
"node_modules/aiwg": {
|
|
2052
|
-
"version": "2026.5.
|
|
2053
|
-
"resolved": "https://registry.npmjs.org/aiwg/-/aiwg-2026.5.
|
|
2054
|
-
"integrity": "sha512
|
|
2052
|
+
"version": "2026.5.5",
|
|
2053
|
+
"resolved": "https://registry.npmjs.org/aiwg/-/aiwg-2026.5.5.tgz",
|
|
2054
|
+
"integrity": "sha512-bRMCp3qOAgZycb1Pyahmx3CgrMVtKU5gQhYpyY23r6B/LhNOP/+t0SHRuvPN4bOVOVsec/qKpma9OvQnlqrp0w==",
|
|
2055
2055
|
"license": "MIT",
|
|
2056
2056
|
"dependencies": {
|
|
2057
2057
|
"@modelcontextprotocol/sdk": "^1.24.0",
|
package/package.json
CHANGED