mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-28 17:41:13 +00:00
* fix(gateway): recover channel turns safely after restart * refactor(gateway): keep recovery identity internal * refactor(gateway): keep recovery metadata private * fix(gateway): preserve recovery action authority * fix(gateway): close recovery lifecycle gaps * fix(gateway): fail closed on missing delivery receipts * fix(gateway): fail closed on unmirrorable replies * fix(gateway): persist terminal delivery intent * fix(gateway): align recovery lifecycle types * fix(gateway): require exact terminal thread receipt * fix(gateway): close recovered terminal tool calls * test(gateway): type terminal tool correlation * fix(gateway): satisfy restart recovery CI contracts * fix(gateway): require terminal tool correlation * fix(agents): scope recovery receipts to source turns * fix(gateway): fail closed without restart correlation * fix(gateway): dedupe terminal source redelivery * fix(agents): keep recovery tool results causal * test(auto-reply): clean recovery fixture directories * fix(gateway): allow live terminal sends without recovery claims * fix(agents): reconcile delivered sends through restart aborts * fix(agents): keep recovery continuations in source turns * fix(agents): keep source-less sends non-terminal * fix(auto-reply): dedupe active source redelivery * fix(agents): harden recovery receipt contracts * fix(agents): admit terminal recovery successors * docs(recovery): document canonical receipt ownership * fix(agents): fail closed on stale turn authority * test(auto-reply): assert rebound session state * fix(plugins): keep restart recovery hook list internal
155 lines
5.2 KiB
TypeScript
155 lines
5.2 KiB
TypeScript
// User-turn transcript type contracts shared by runtime and queue option types.
|
|
import type { AgentMessage } from "../../packages/agent-core/src/types.js";
|
|
import type {
|
|
SessionTranscriptTurnExpectedState,
|
|
SessionTranscriptTurnLifecyclePatch,
|
|
} from "../config/sessions/session-transcript-turn-lifecycle.types.js";
|
|
import type { InputProvenance } from "./input-provenance.js";
|
|
|
|
type UserTurnSessionEntry = {
|
|
sessionId: string;
|
|
updatedAt: number;
|
|
sessionFile?: string;
|
|
threadId?: string | number;
|
|
} & Record<string, unknown>;
|
|
|
|
export type PersistedUserTurnMediaInput = {
|
|
path?: string | null;
|
|
url?: string | null;
|
|
contentType?: string | null;
|
|
kind?: string | null;
|
|
};
|
|
|
|
export type PersistedUserTurnMessage = Extract<AgentMessage, { role: "user" }>;
|
|
|
|
export type UserTurnInput = {
|
|
text?: string | null;
|
|
media?: readonly PersistedUserTurnMediaInput[] | null;
|
|
timestamp?: number;
|
|
idempotencyKey?: string;
|
|
senderIsOwner?: boolean;
|
|
provenance?: InputProvenance;
|
|
mediaOnlyText?: string;
|
|
/** Durable participant attribution. Callers must opt in at the product boundary. */
|
|
sender?: { id?: string | null; name?: string | null; username?: string | null } | null;
|
|
};
|
|
|
|
export type UserTurnTranscriptUpdateMode = "inline" | "none";
|
|
|
|
export type UserTurnMessagePersistenceParams = {
|
|
input?: UserTurnInput;
|
|
message?: PersistedUserTurnMessage;
|
|
sessionId?: string;
|
|
agentId?: string;
|
|
sessionKey?: string;
|
|
cwd?: string;
|
|
config?: unknown;
|
|
updateMode?: UserTurnTranscriptUpdateMode;
|
|
beforeMessageWrite?: UserTurnBeforeMessageWrite;
|
|
};
|
|
|
|
type UserTurnBeforeMessageWrite = (params: {
|
|
message: PersistedUserTurnMessage;
|
|
agentId?: string;
|
|
sessionKey?: string;
|
|
}) => AgentMessage | null;
|
|
|
|
type UserTurnTranscriptPersistenceTarget = {
|
|
sessionId: string;
|
|
expectedSessionId?: string;
|
|
sessionKey: string;
|
|
sessionEntry: UserTurnSessionEntry | undefined;
|
|
sessionStore?: Record<string, UserTurnSessionEntry>;
|
|
storePath?: string;
|
|
agentId: string;
|
|
threadId?: string | number;
|
|
cwd?: string;
|
|
config?: unknown;
|
|
beforeMessageWrite?: UserTurnBeforeMessageWrite;
|
|
};
|
|
|
|
export type UserTurnTranscriptTarget = UserTurnTranscriptPersistenceTarget;
|
|
|
|
export type UserTurnTranscriptPersistResult = {
|
|
/** True only when this call inserted the transcript message. */
|
|
appended?: boolean;
|
|
sessionFile: string;
|
|
sessionEntry: UserTurnSessionEntry | undefined;
|
|
messageId: string;
|
|
message: PersistedUserTurnMessage;
|
|
};
|
|
|
|
export type UserTurnTranscriptTargetResolver =
|
|
| UserTurnTranscriptTarget
|
|
| (() => UserTurnTranscriptTarget | undefined | Promise<UserTurnTranscriptTarget | undefined>);
|
|
|
|
export type PersistUserTurnTranscriptParams = {
|
|
input?: UserTurnInput;
|
|
message?: PersistedUserTurnMessage;
|
|
sessionId: string;
|
|
expectedSessionId?: string;
|
|
sessionKey: string;
|
|
sessionEntry: UserTurnSessionEntry | undefined;
|
|
sessionStore?: Record<string, UserTurnSessionEntry>;
|
|
storePath?: string;
|
|
agentId: string;
|
|
threadId?: string | number;
|
|
cwd?: string;
|
|
config?: unknown;
|
|
updateMode?: UserTurnTranscriptUpdateMode;
|
|
beforeMessageWrite?: UserTurnBeforeMessageWrite;
|
|
expectedSessionState?: SessionTranscriptTurnExpectedState;
|
|
sessionLifecyclePatch?: SessionTranscriptTurnLifecyclePatch;
|
|
};
|
|
|
|
type UserTurnInputResolver = () => UserTurnInput | undefined | Promise<UserTurnInput | undefined>;
|
|
|
|
export type CreateUserTurnTranscriptRecorderParams = {
|
|
input?: UserTurnInput;
|
|
message?: PersistedUserTurnMessage;
|
|
resolveInput?: UserTurnInputResolver;
|
|
target: UserTurnTranscriptTargetResolver;
|
|
updateMode?: UserTurnTranscriptUpdateMode;
|
|
beforeMessageWrite?: UserTurnBeforeMessageWrite;
|
|
errorContext?: string;
|
|
onPersistenceError?: (error: unknown) => void;
|
|
onMessagePersisted?: (message: PersistedUserTurnMessage) => void | Promise<void>;
|
|
expectedSessionState?: SessionTranscriptTurnExpectedState;
|
|
sessionLifecyclePatch?: SessionTranscriptTurnLifecyclePatch;
|
|
};
|
|
|
|
export type UserTurnTranscriptRecorder = {
|
|
readonly message: PersistedUserTurnMessage | undefined;
|
|
resolveMessage: () => Promise<PersistedUserTurnMessage | undefined>;
|
|
getPersistedMessage?: () => PersistedUserTurnMessage | undefined;
|
|
markSentToProvider?: () => void;
|
|
markRuntimePersistencePending: (pending: Promise<void>) => void;
|
|
markRuntimePersisted: (message?: PersistedUserTurnMessage) => void;
|
|
markBlocked: () => void;
|
|
hasPersisted: () => boolean;
|
|
isBlocked: () => boolean;
|
|
hasRuntimePersistencePending: () => boolean;
|
|
waitForRuntimePersistence: () => Promise<void>;
|
|
persistApproved: (params?: {
|
|
target?: UserTurnTranscriptTargetResolver;
|
|
updateMode?: UserTurnTranscriptUpdateMode;
|
|
cwd?: string;
|
|
expectedSessionId?: string;
|
|
expectedSessionState?: SessionTranscriptTurnExpectedState;
|
|
sessionLifecyclePatch?: SessionTranscriptTurnLifecyclePatch;
|
|
}) => Promise<UserTurnTranscriptPersistResult | undefined>;
|
|
persistBlocked: (
|
|
message: PersistedUserTurnMessage,
|
|
params?: {
|
|
target?: UserTurnTranscriptTargetResolver;
|
|
updateMode?: UserTurnTranscriptUpdateMode;
|
|
cwd?: string;
|
|
},
|
|
) => Promise<UserTurnTranscriptPersistResult | undefined>;
|
|
persistFallback: (params?: {
|
|
target?: UserTurnTranscriptTargetResolver;
|
|
updateMode?: UserTurnTranscriptUpdateMode;
|
|
cwd?: string;
|
|
}) => Promise<UserTurnTranscriptPersistResult | undefined>;
|
|
};
|