File size: 3,452 Bytes
76289e7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | /** Resolves ACP request metadata into OpenClaw Gateway session keys and reset behavior. */
import { readBool, readMetadataString } from "@openclaw/acp-core/meta";
import type { AcpServerOptions } from "@openclaw/acp-core/types";
import type { GatewayClient } from "../gateway/client.js";
type AcpSessionMeta = {
sessionKey?: string;
sessionLabel?: string;
resetSession?: boolean;
requireExisting?: boolean;
prefixCwd?: boolean;
};
/** Parses ACP request metadata into OpenClaw session routing hints. */
export function parseSessionMeta(meta: unknown): AcpSessionMeta {
if (!meta || typeof meta !== "object") {
return {};
}
const record = meta as Record<string, unknown>;
return {
sessionKey: readMetadataString(record, ["sessionKey", "session", "key"]),
sessionLabel: readMetadataString(record, ["sessionLabel", "label"]),
resetSession: readBool(record, ["resetSession", "reset"]),
requireExisting: readBool(record, ["requireExistingSession", "requireExisting"]),
prefixCwd: readBool(record, ["prefixCwd"]),
};
}
/** Resolves the Gateway session key for an ACP request using metadata, defaults, or fallback. */
export async function resolveAcpSessionKey(params: {
meta: AcpSessionMeta;
fallbackKey: string;
gateway: GatewayClient;
opts: AcpServerOptions;
}): Promise<string> {
const requestedLabel = params.meta.sessionLabel ?? params.opts.defaultSessionLabel;
const requestedKey = params.meta.sessionKey ?? params.opts.defaultSessionKey;
const requireExisting =
params.meta.requireExisting ?? params.opts.requireExistingSession ?? false;
if (params.meta.sessionLabel) {
const resolved = await params.gateway.request<{ ok: true; key: string }>("sessions.resolve", {
label: params.meta.sessionLabel,
});
if (!resolved?.key) {
throw new Error(`Unable to resolve session label: ${params.meta.sessionLabel}`);
}
return resolved.key;
}
if (params.meta.sessionKey) {
if (!requireExisting) {
return params.meta.sessionKey;
}
const resolved = await params.gateway.request<{ ok: true; key: string }>("sessions.resolve", {
key: params.meta.sessionKey,
});
if (!resolved?.key) {
throw new Error(`Session key not found: ${params.meta.sessionKey}`);
}
return resolved.key;
}
if (requestedLabel) {
const resolved = await params.gateway.request<{ ok: true; key: string }>("sessions.resolve", {
label: requestedLabel,
});
if (!resolved?.key) {
throw new Error(`Unable to resolve session label: ${requestedLabel}`);
}
return resolved.key;
}
if (requestedKey) {
if (!requireExisting) {
return requestedKey;
}
const resolved = await params.gateway.request<{ ok: true; key: string }>("sessions.resolve", {
key: requestedKey,
});
if (!resolved?.key) {
throw new Error(`Session key not found: ${requestedKey}`);
}
return resolved.key;
}
return params.fallbackKey;
}
/** Sends a Gateway session reset when ACP metadata or server defaults request it. */
export async function resetSessionIfNeeded(params: {
meta: AcpSessionMeta;
sessionKey: string;
gateway: GatewayClient;
opts: AcpServerOptions;
}): Promise<void> {
const resetSession = params.meta.resetSession ?? params.opts.resetSession ?? false;
if (!resetSession) {
return;
}
await params.gateway.request("sessions.reset", { key: params.sessionKey });
}
|