mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 11:30:43 +00:00
fix(cli-session): only hash static extraSystemPrompt for session reuse
The extraSystemPrompt includes per-message dynamic content from buildInboundMetaSystemPrompt() (timestamps, message IDs, sender metadata) that changes on every inbound message. This causes the extraSystemPromptHash to differ every turn, triggering a session reset with reason='system-prompt' and discarding all CLI session context. Fix: split extraSystemPrompt into dynamic (inbound meta) and static (group context, group intro, group system prompt, exec override hints) portions. Only hash the static portion for session reuse validation. The full extraSystemPrompt (dynamic + static) is still sent to the CLI as before — only the session stability hash uses the static subset. Fixes #70100
This commit is contained in:
committed by
Peter Steinberger
parent
d48763caf9
commit
d1c414305b
@@ -107,7 +107,11 @@ export async function prepareCliRunContext(
|
||||
authCredential = authStore.profiles[effectiveAuthProfileId];
|
||||
}
|
||||
const extraSystemPrompt = params.extraSystemPrompt?.trim() ?? "";
|
||||
const extraSystemPromptHash = hashCliSessionText(extraSystemPrompt);
|
||||
// Use the static portion (excluding per-message inbound metadata) for session reuse hashing.
|
||||
// Per-message metadata (timestamps, message IDs) changes every turn and must not trigger session resets.
|
||||
const extraSystemPromptHash = hashCliSessionText(params.extraSystemPromptStatic?.trim() || undefined) ?? hashCliSessionText(extraSystemPrompt);
|
||||
|
||||
|
||||
const modelId = (params.model ?? "default").trim() || "default";
|
||||
const normalizedModel = normalizeCliModel(modelId, backendResolved.config);
|
||||
const modelDisplay = `${params.provider}/${modelId}`;
|
||||
|
||||
@@ -23,6 +23,8 @@ export type RunCliAgentParams = {
|
||||
timeoutMs: number;
|
||||
runId: string;
|
||||
extraSystemPrompt?: string;
|
||||
/** Static portion of extraSystemPrompt (excluding per-message inbound metadata) for session reuse hashing. */
|
||||
extraSystemPromptStatic?: string;
|
||||
streamParams?: import("../command/types.js").AgentStreamParams;
|
||||
ownerNumbers?: string[];
|
||||
cliSessionId?: string;
|
||||
|
||||
@@ -305,6 +305,18 @@ export async function runPreparedReply(
|
||||
fullAccessBlockedReason: fullAccessState.blockedReason,
|
||||
}),
|
||||
].filter(Boolean);
|
||||
// Static parts only (no per-message inbound metadata) for CLI session reuse hashing.
|
||||
const extraSystemPromptStaticParts = [
|
||||
groupChatContext,
|
||||
groupIntro,
|
||||
groupSystemPrompt,
|
||||
buildExecOverridePromptHint({
|
||||
execOverrides,
|
||||
elevatedLevel: resolvedElevatedLevel,
|
||||
fullAccessAvailable: fullAccessState.available,
|
||||
fullAccessBlockedReason: fullAccessState.blockedReason,
|
||||
}),
|
||||
].filter(Boolean);
|
||||
const baseBody = sessionCtx.BodyStripped ?? sessionCtx.Body ?? "";
|
||||
// Use CommandBody/RawBody for bare reset detection (clean message without structural context).
|
||||
const rawBodyTrimmed = (ctx.CommandBody ?? ctx.RawBody ?? ctx.Body ?? "").trim();
|
||||
@@ -734,6 +746,7 @@ export async function runPreparedReply(
|
||||
ownerNumbers: command.ownerList.length > 0 ? command.ownerList : undefined,
|
||||
inputProvenance: ctx.InputProvenance ?? sessionCtx.InputProvenance,
|
||||
extraSystemPrompt: extraSystemPromptParts.join("\n\n") || undefined,
|
||||
extraSystemPromptStatic: extraSystemPromptStaticParts.join("\n\n") || undefined,
|
||||
skipProviderRuntimeHints: useFastReplyRuntime,
|
||||
...(!useFastReplyRuntime &&
|
||||
isReasoningTagProvider(provider, {
|
||||
|
||||
Reference in New Issue
Block a user