mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-05 02:10:24 +00:00
perf(reply): split usage line helpers
This commit is contained in:
68
src/auto-reply/reply/agent-runner-usage-line.ts
Normal file
68
src/auto-reply/reply/agent-runner-usage-line.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { estimateUsageCost, formatTokenCount, formatUsd } from "../../utils/usage-format.js";
|
||||
import type { ReplyPayload } from "../types.js";
|
||||
|
||||
export const formatResponseUsageLine = (params: {
|
||||
usage?: {
|
||||
input?: number;
|
||||
output?: number;
|
||||
cacheRead?: number;
|
||||
cacheWrite?: number;
|
||||
};
|
||||
showCost: boolean;
|
||||
costConfig?: {
|
||||
input: number;
|
||||
output: number;
|
||||
cacheRead: number;
|
||||
cacheWrite: number;
|
||||
};
|
||||
}): string | null => {
|
||||
const usage = params.usage;
|
||||
if (!usage) {
|
||||
return null;
|
||||
}
|
||||
const input = usage.input;
|
||||
const output = usage.output;
|
||||
if (typeof input !== "number" && typeof output !== "number") {
|
||||
return null;
|
||||
}
|
||||
const inputLabel = typeof input === "number" ? formatTokenCount(input) : "?";
|
||||
const outputLabel = typeof output === "number" ? formatTokenCount(output) : "?";
|
||||
const cost =
|
||||
params.showCost && typeof input === "number" && typeof output === "number"
|
||||
? estimateUsageCost({
|
||||
usage: {
|
||||
input,
|
||||
output,
|
||||
cacheRead: usage.cacheRead,
|
||||
cacheWrite: usage.cacheWrite,
|
||||
},
|
||||
cost: params.costConfig,
|
||||
})
|
||||
: undefined;
|
||||
const costLabel = params.showCost ? formatUsd(cost) : undefined;
|
||||
const suffix = costLabel ? ` · est ${costLabel}` : "";
|
||||
return `Usage: ${inputLabel} in / ${outputLabel} out${suffix}`;
|
||||
};
|
||||
|
||||
export const appendUsageLine = (payloads: ReplyPayload[], line: string): ReplyPayload[] => {
|
||||
let index = -1;
|
||||
for (let i = payloads.length - 1; i >= 0; i -= 1) {
|
||||
if (payloads[i]?.text) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index === -1) {
|
||||
return [...payloads, { text: line }];
|
||||
}
|
||||
const existing = payloads[index];
|
||||
const existingText = existing.text ?? "";
|
||||
const separator = existingText.endsWith("\n") ? "" : "\n";
|
||||
const next = {
|
||||
...existing,
|
||||
text: `${existingText}${separator}${line}`,
|
||||
};
|
||||
const updated = payloads.slice();
|
||||
updated[index] = next;
|
||||
return updated;
|
||||
};
|
||||
@@ -5,9 +5,7 @@ import type { ChannelId, ChannelThreadingToolContext } from "../../channels/plug
|
||||
import { normalizeAnyChannelId, normalizeChannelId } from "../../channels/registry.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { isReasoningTagProvider } from "../../utils/provider-utils.js";
|
||||
import { estimateUsageCost, formatTokenCount, formatUsd } from "../../utils/usage-format.js";
|
||||
import type { TemplateContext } from "../templating.js";
|
||||
import type { ReplyPayload } from "../types.js";
|
||||
import {
|
||||
resolveProviderScopedAuthProfile,
|
||||
resolveRunAuthProfile,
|
||||
@@ -95,67 +93,6 @@ export const formatBunFetchSocketError = (message: string) => {
|
||||
].join("\n");
|
||||
};
|
||||
|
||||
export const formatResponseUsageLine = (params: {
|
||||
usage?: NormalizedUsage;
|
||||
showCost: boolean;
|
||||
costConfig?: {
|
||||
input: number;
|
||||
output: number;
|
||||
cacheRead: number;
|
||||
cacheWrite: number;
|
||||
};
|
||||
}): string | null => {
|
||||
const usage = params.usage;
|
||||
if (!usage) {
|
||||
return null;
|
||||
}
|
||||
const input = usage.input;
|
||||
const output = usage.output;
|
||||
if (typeof input !== "number" && typeof output !== "number") {
|
||||
return null;
|
||||
}
|
||||
const inputLabel = typeof input === "number" ? formatTokenCount(input) : "?";
|
||||
const outputLabel = typeof output === "number" ? formatTokenCount(output) : "?";
|
||||
const cost =
|
||||
params.showCost && typeof input === "number" && typeof output === "number"
|
||||
? estimateUsageCost({
|
||||
usage: {
|
||||
input,
|
||||
output,
|
||||
cacheRead: usage.cacheRead,
|
||||
cacheWrite: usage.cacheWrite,
|
||||
},
|
||||
cost: params.costConfig,
|
||||
})
|
||||
: undefined;
|
||||
const costLabel = params.showCost ? formatUsd(cost) : undefined;
|
||||
const suffix = costLabel ? ` · est ${costLabel}` : "";
|
||||
return `Usage: ${inputLabel} in / ${outputLabel} out${suffix}`;
|
||||
};
|
||||
|
||||
export const appendUsageLine = (payloads: ReplyPayload[], line: string): ReplyPayload[] => {
|
||||
let index = -1;
|
||||
for (let i = payloads.length - 1; i >= 0; i -= 1) {
|
||||
if (payloads[i]?.text) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index === -1) {
|
||||
return [...payloads, { text: line }];
|
||||
}
|
||||
const existing = payloads[index];
|
||||
const existingText = existing.text ?? "";
|
||||
const separator = existingText.endsWith("\n") ? "" : "\n";
|
||||
const next = {
|
||||
...existing,
|
||||
text: `${existingText}${separator}${line}`,
|
||||
};
|
||||
const updated = payloads.slice();
|
||||
updated[index] = next;
|
||||
return updated;
|
||||
};
|
||||
|
||||
export const resolveEnforceFinalTag = (run: FollowupRun["run"], provider: string) =>
|
||||
Boolean(run.enforceFinalTag || isReasoningTagProvider(provider));
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ import {
|
||||
hasSessionRelatedCronJobs,
|
||||
hasUnbackedReminderCommitment,
|
||||
} from "./agent-runner-reminder-guard.js";
|
||||
import { appendUsageLine, formatResponseUsageLine } from "./agent-runner-utils.js";
|
||||
import { appendUsageLine, formatResponseUsageLine } from "./agent-runner-usage-line.js";
|
||||
import { createAudioAsVoiceBuffer, createBlockReplyPipeline } from "./block-reply-pipeline.js";
|
||||
import { resolveEffectiveBlockStreamingConfig } from "./block-streaming.js";
|
||||
import { createFollowupRunner } from "./followup-runner.js";
|
||||
|
||||
Reference in New Issue
Block a user