




















@@ -16,8 +16,9 @@ import { clearCliSession, getCliSessionBinding, setCliSessionBinding } from "../
1616import { FailoverError } from "../failover-error.js";
1717import { isCliProvider } from "../model-selection.js";
1818import { prepareSessionManagerForRun } from "../pi-embedded-runner/session-manager-init.js";
19-import { runEmbeddedPiAgent } from "../pi-embedded.js";
19+import { runEmbeddedPiAgent, type EmbeddedPiRunResult } from "../pi-embedded.js";
2020import { buildWorkspaceSkillSnapshot } from "../skills.js";
21+import { buildUsageWithNoCost } from "../stream-message-shared.js";
2122import { resolveFallbackRetryPrompt } from "./attempt-execution.helpers.js";
2223import { persistSessionEntry } from "./attempt-execution.shared.js";
2324import { resolveAgentRunContext } from "./run-context.js";
@@ -46,7 +47,15 @@ const ACP_TRANSCRIPT_USAGE = {
4647},
4748} as const;
484949-export async function persistAcpTurnTranscript(params: {
50+type TranscriptUsage = {
51+input?: number;
52+output?: number;
53+cacheRead?: number;
54+cacheWrite?: number;
55+total?: number;
56+};
57+58+type PersistTextTurnTranscriptParams = {
5059body: string;
5160finalText: string;
5261sessionId: string;
@@ -57,7 +66,30 @@ export async function persistAcpTurnTranscript(params: {
5766sessionAgentId: string;
5867threadId?: string | number;
5968sessionCwd: string;
60-}): Promise<SessionEntry | undefined> {
69+assistant: {
70+api: string;
71+provider: string;
72+model: string;
73+usage?: TranscriptUsage;
74+};
75+};
76+77+function resolveTranscriptUsage(usage: PersistTextTurnTranscriptParams["assistant"]["usage"]) {
78+if (!usage) {
79+return ACP_TRANSCRIPT_USAGE;
80+}
81+return buildUsageWithNoCost({
82+input: usage.input,
83+output: usage.output,
84+cacheRead: usage.cacheRead,
85+cacheWrite: usage.cacheWrite,
86+totalTokens: usage.total,
87+});
88+}
89+90+async function persistTextTurnTranscript(
91+params: PersistTextTurnTranscriptParams,
92+): Promise<SessionEntry | undefined> {
6193const promptText = params.body;
6294const replyText = params.finalText;
6395if (!promptText && !replyText) {
@@ -98,10 +130,10 @@ export async function persistAcpTurnTranscript(params: {
98130sessionManager.appendMessage({
99131role: "assistant",
100132content: [{ type: "text", text: replyText }],
101-api: "openai-responses",
102-provider: "openclaw",
103-model: "acp-runtime",
104-usage: ACP_TRANSCRIPT_USAGE,
133+api: params.assistant.api,
134+provider: params.assistant.provider,
135+model: params.assistant.model,
136+usage: resolveTranscriptUsage(params.assistant.usage),
105137stopReason: "stop",
106138timestamp: Date.now(),
107139});
@@ -111,6 +143,77 @@ export async function persistAcpTurnTranscript(params: {
111143return sessionEntry;
112144}
113145146+function resolveCliTranscriptReplyText(result: EmbeddedPiRunResult): string {
147+const visibleText = result.meta.finalAssistantVisibleText?.trim();
148+if (visibleText) {
149+return visibleText;
150+}
151+152+return (result.payloads ?? [])
153+.filter((payload) => !payload.isError && !payload.isReasoning)
154+.map((payload) => payload.text?.trim() ?? "")
155+.filter(Boolean)
156+.join("\n\n");
157+}
158+159+export async function persistAcpTurnTranscript(params: {
160+body: string;
161+finalText: string;
162+sessionId: string;
163+sessionKey: string;
164+sessionEntry: SessionEntry | undefined;
165+sessionStore?: Record<string, SessionEntry>;
166+storePath?: string;
167+sessionAgentId: string;
168+threadId?: string | number;
169+sessionCwd: string;
170+}): Promise<SessionEntry | undefined> {
171+return await persistTextTurnTranscript({
172+ ...params,
173+assistant: {
174+api: "openai-responses",
175+provider: "openclaw",
176+model: "acp-runtime",
177+},
178+});
179+}
180+181+export async function persistCliTurnTranscript(params: {
182+body: string;
183+result: EmbeddedPiRunResult;
184+sessionId: string;
185+sessionKey: string;
186+sessionEntry: SessionEntry | undefined;
187+sessionStore?: Record<string, SessionEntry>;
188+storePath?: string;
189+sessionAgentId: string;
190+threadId?: string | number;
191+sessionCwd: string;
192+}): Promise<SessionEntry | undefined> {
193+const replyText = resolveCliTranscriptReplyText(params.result);
194+const provider = params.result.meta.agentMeta?.provider?.trim() ?? "cli";
195+const model = params.result.meta.agentMeta?.model?.trim() ?? "default";
196+197+return await persistTextTurnTranscript({
198+body: params.body,
199+finalText: replyText,
200+sessionId: params.sessionId,
201+sessionKey: params.sessionKey,
202+sessionEntry: params.sessionEntry,
203+sessionStore: params.sessionStore,
204+storePath: params.storePath,
205+sessionAgentId: params.sessionAgentId,
206+threadId: params.threadId,
207+sessionCwd: params.sessionCwd,
208+assistant: {
209+api: provider,
210+ provider,
211+ model,
212+usage: params.result.meta.agentMeta?.usage,
213+},
214+});
215+}
216+114217export function runAgentAttempt(params: {
115218providerOverride: string;
116219modelOverride: string;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。