mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-31 11:51:22 +00:00
130 lines
4.7 KiB
TypeScript
130 lines
4.7 KiB
TypeScript
import type { ImageContent } from "@mariozechner/pi-ai";
|
|
import type { ThinkLevel } from "../auto-reply/thinking.js";
|
|
import type { OpenClawConfig } from "../config/config.js";
|
|
import { executePreparedCliRun } from "./cli-runner/execute.js";
|
|
import { prepareCliRunContext } from "./cli-runner/prepare.js";
|
|
import type { RunCliAgentParams } from "./cli-runner/types.js";
|
|
import { FailoverError, resolveFailoverStatus } from "./failover-error.js";
|
|
import { classifyFailoverReason, isFailoverErrorMessage } from "./pi-embedded-helpers.js";
|
|
import type { EmbeddedPiRunResult } from "./pi-embedded-runner.js";
|
|
|
|
export async function runCliAgent(params: RunCliAgentParams): Promise<EmbeddedPiRunResult> {
|
|
const context = await prepareCliRunContext(params);
|
|
|
|
const buildCliRunResult = (resultParams: {
|
|
output: Awaited<ReturnType<typeof executePreparedCliRun>>;
|
|
effectiveCliSessionId?: string;
|
|
}): EmbeddedPiRunResult => {
|
|
const text = resultParams.output.text?.trim();
|
|
const payloads = text ? [{ text }] : undefined;
|
|
|
|
return {
|
|
payloads,
|
|
meta: {
|
|
durationMs: Date.now() - context.started,
|
|
systemPromptReport: context.systemPromptReport,
|
|
agentMeta: {
|
|
sessionId: resultParams.effectiveCliSessionId ?? params.sessionId ?? "",
|
|
provider: params.provider,
|
|
model: context.modelId,
|
|
usage: resultParams.output.usage,
|
|
...(resultParams.effectiveCliSessionId
|
|
? {
|
|
cliSessionBinding: {
|
|
sessionId: resultParams.effectiveCliSessionId,
|
|
...(params.authProfileId ? { authProfileId: params.authProfileId } : {}),
|
|
...(context.extraSystemPromptHash
|
|
? { extraSystemPromptHash: context.extraSystemPromptHash }
|
|
: {}),
|
|
...(context.preparedBackend.mcpConfigHash
|
|
? { mcpConfigHash: context.preparedBackend.mcpConfigHash }
|
|
: {}),
|
|
},
|
|
}
|
|
: {}),
|
|
},
|
|
},
|
|
};
|
|
};
|
|
|
|
// Try with the provided CLI session ID first
|
|
try {
|
|
try {
|
|
const output = await executePreparedCliRun(context, context.reusableCliSession.sessionId);
|
|
const effectiveCliSessionId = output.sessionId ?? context.reusableCliSession.sessionId;
|
|
return buildCliRunResult({ output, effectiveCliSessionId });
|
|
} catch (err) {
|
|
if (err instanceof FailoverError) {
|
|
// Check if this is a session expired error and we have a session to clear
|
|
if (
|
|
err.reason === "session_expired" &&
|
|
context.reusableCliSession.sessionId &&
|
|
params.sessionKey
|
|
) {
|
|
// Clear the expired session ID from the session entry
|
|
// This requires access to the session store, which we don't have here
|
|
// We'll need to modify the caller to handle this case
|
|
|
|
// For now, retry without the session ID to create a new session
|
|
const output = await executePreparedCliRun(context, undefined);
|
|
const effectiveCliSessionId = output.sessionId;
|
|
return buildCliRunResult({ output, effectiveCliSessionId });
|
|
}
|
|
throw err;
|
|
}
|
|
const message = err instanceof Error ? err.message : String(err);
|
|
if (isFailoverErrorMessage(message)) {
|
|
const reason = classifyFailoverReason(message) ?? "unknown";
|
|
const status = resolveFailoverStatus(reason);
|
|
throw new FailoverError(message, {
|
|
reason,
|
|
provider: params.provider,
|
|
model: context.modelId,
|
|
status,
|
|
});
|
|
}
|
|
throw err;
|
|
}
|
|
} finally {
|
|
await context.preparedBackend.cleanup?.();
|
|
}
|
|
}
|
|
|
|
export async function runClaudeCliAgent(params: {
|
|
sessionId: string;
|
|
sessionKey?: string;
|
|
agentId?: string;
|
|
sessionFile: string;
|
|
workspaceDir: string;
|
|
config?: OpenClawConfig;
|
|
prompt: string;
|
|
provider?: string;
|
|
model?: string;
|
|
thinkLevel?: ThinkLevel;
|
|
timeoutMs: number;
|
|
runId: string;
|
|
extraSystemPrompt?: string;
|
|
ownerNumbers?: string[];
|
|
claudeSessionId?: string;
|
|
images?: ImageContent[];
|
|
}): Promise<EmbeddedPiRunResult> {
|
|
return runCliAgent({
|
|
sessionId: params.sessionId,
|
|
sessionKey: params.sessionKey,
|
|
agentId: params.agentId,
|
|
sessionFile: params.sessionFile,
|
|
workspaceDir: params.workspaceDir,
|
|
config: params.config,
|
|
prompt: params.prompt,
|
|
provider: params.provider ?? "claude-cli",
|
|
model: params.model ?? "opus",
|
|
thinkLevel: params.thinkLevel,
|
|
timeoutMs: params.timeoutMs,
|
|
runId: params.runId,
|
|
extraSystemPrompt: params.extraSystemPrompt,
|
|
ownerNumbers: params.ownerNumbers,
|
|
cliSessionId: params.claudeSessionId,
|
|
images: params.images,
|
|
});
|
|
}
|