

























@@ -159,9 +159,7 @@ export function createCodexDynamicToolBridge(params: {
159159 startedAt,
160160});
161161return {
162-contentItems: result.content.flatMap((content) =>
163-convertToolContent(content, toolResultMaxChars),
164-),
162+contentItems: convertToolContents(result.content, toolResultMaxChars),
165163success: !resultIsError,
166164};
167165} catch (error) {
@@ -262,23 +260,6 @@ function resolveAgentContextLimitValue(params: {
262260return agentValue ?? defaultValue;
263261}
264262265-function truncateCodexDynamicToolText(text: string, maxChars: number): string {
266-const limit =
267-typeof maxChars === "number" && Number.isFinite(maxChars) && maxChars > 0
268- ? Math.floor(maxChars)
269- : DEFAULT_CODEX_DYNAMIC_TOOL_RESULT_MAX_CHARS;
270-if (text.length <= limit) {
271-return text;
272-}
273-const noticeText = `...(OpenClaw truncated dynamic tool result: original ${text.length} chars, showing ${limit}; rerun with narrower args.)`;
274-const notice = `\n${noticeText}`;
275-if (notice.length >= limit) {
276-return noticeText.slice(0, limit);
277-}
278-const sliceLength = Math.max(0, limit - notice.length);
279-return `${text.slice(0, sliceLength).trimEnd()}${notice}`.slice(0, limit);
280-}
281-282263function composeAbortSignals(...signals: Array<AbortSignal | undefined>): AbortSignal {
283264const activeSignals = signals.filter((signal): signal is AbortSignal => Boolean(signal));
284265if (activeSignals.length === 0) {
@@ -435,14 +416,68 @@ function isToolResultError(result: AgentToolResult<unknown>): boolean {
435416);
436417}
437418419+function normalizeToolResultMaxChars(maxChars: number): number {
420+return typeof maxChars === "number" && Number.isFinite(maxChars) && maxChars > 0
421+ ? Math.floor(maxChars)
422+ : DEFAULT_CODEX_DYNAMIC_TOOL_RESULT_MAX_CHARS;
423+}
424+425+function convertToolContents(
426+content: Array<TextContent | ImageContent>,
427+toolResultMaxChars = DEFAULT_CODEX_DYNAMIC_TOOL_RESULT_MAX_CHARS,
428+): CodexDynamicToolCallOutputContentItem[] {
429+const maxChars = normalizeToolResultMaxChars(toolResultMaxChars);
430+const totalTextChars = content.reduce(
431+(total, item) => total + (item.type === "text" ? item.text.length : 0),
432+0,
433+);
434+if (totalTextChars <= maxChars) {
435+return content.flatMap(convertToolContent);
436+}
437+438+const noticeText = `...(OpenClaw truncated dynamic tool result: original ${totalTextChars} chars, showing ${maxChars}; rerun with narrower args.)`;
439+const notice = `\n${noticeText}`;
440+const textBudget = Math.max(0, maxChars - notice.length);
441+let remainingTextBudget = textBudget;
442+let appendedNotice = false;
443+const output: CodexDynamicToolCallOutputContentItem[] = [];
444+445+for (const item of content) {
446+if (item.type !== "text") {
447+output.push(...convertToolContent(item));
448+continue;
449+}
450+if (appendedNotice) {
451+continue;
452+}
453+if (notice.length >= maxChars) {
454+output.push({ type: "inputText", text: noticeText.slice(0, maxChars) });
455+appendedNotice = true;
456+continue;
457+}
458+const sliceLength = Math.min(item.text.length, remainingTextBudget);
459+remainingTextBudget -= sliceLength;
460+const shouldAppendNotice = remainingTextBudget <= 0;
461+const text = item.text.slice(0, sliceLength);
462+if (shouldAppendNotice) {
463+output.push({ type: "inputText", text: `${text.trimEnd()}${notice}`.slice(0, maxChars) });
464+appendedNotice = true;
465+} else if (text.length > 0) {
466+output.push({ type: "inputText", text });
467+}
468+}
469+470+if (!appendedNotice) {
471+output.push({ type: "inputText", text: noticeText.slice(0, maxChars) });
472+}
473+return output;
474+}
475+438476function convertToolContent(
439477content: TextContent | ImageContent,
440-toolResultMaxChars = DEFAULT_CODEX_DYNAMIC_TOOL_RESULT_MAX_CHARS,
441478): CodexDynamicToolCallOutputContentItem[] {
442479if (content.type === "text") {
443-return [
444-{ type: "inputText", text: truncateCodexDynamicToolText(content.text, toolResultMaxChars) },
445-];
480+return [{ type: "inputText", text: content.text }];
446481}
447482const imageUrl = sanitizeInlineImageDataUrl(`data:${content.mimeType};base64,${content.data}`);
448483if (!imageUrl) {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。