Files
openclaw/extensions/anthropic/session-catalog-runtime.ts
Peter Steinberger 7b71d5608e perf(gateway): reuse session catalog entry snapshots per request (#114358)
* perf(gateway): reuse session catalog entry snapshots

* chore(gateway): satisfy knip and typed-test lanes for catalog snapshot
2026-07-27 02:14:11 -04:00

120 lines
4.2 KiB
TypeScript

import {
resolveAllowedModelRef,
resolveDefaultAgentId,
resolveDefaultModelForAgent,
} from "openclaw/plugin-sdk/agent-runtime";
import { resolveEffectiveAgentRuntime } from "openclaw/plugin-sdk/command-auth-native";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
import {
listSessionCatalogEntries,
type SessionCatalogEntrySnapshot,
} from "openclaw/plugin-sdk/session-catalog";
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
import { CLAUDE_CLI_BACKEND_ID, CLAUDE_CLI_ROUTE_PROBE_MODEL_IDS } from "./cli-constants.js";
import { adoptedSourceKey, CLAUDE_LOCAL_SESSION_HOST_ID } from "./session-catalog-adoption.js";
export function currentClaudeSessionCatalogConfig(api: OpenClawPluginApi): OpenClawConfig {
return (api.runtime.config?.current?.() ?? api.config ?? {}) as OpenClawConfig;
}
function boundClaudeSource(
pluginId: string,
entry: {
cliSessionBindings?: unknown;
execHost?: string;
execNode?: string;
pluginOwnerId?: string;
modelSelectionLocked?: boolean;
pluginExtensions?: unknown;
},
): { hostId: string; threadId: string } | undefined {
const anthropic = isRecord(entry.pluginExtensions) ? entry.pluginExtensions.anthropic : undefined;
const marker = isRecord(anthropic) ? anthropic.sessionCatalog : undefined;
const hostId =
isRecord(marker) && typeof marker.sourceHostId === "string"
? marker.sourceHostId
: entry.execHost === "node" && typeof entry.execNode === "string" && entry.execNode.trim()
? `node:${entry.execNode.trim()}`
: CLAUDE_LOCAL_SESSION_HOST_ID;
const bindings = isRecord(entry.cliSessionBindings) ? entry.cliSessionBindings : undefined;
const binding = bindings?.[CLAUDE_CLI_BACKEND_ID];
if (isRecord(binding) && typeof binding.sessionId === "string" && binding.sessionId) {
return { hostId, threadId: binding.sessionId };
}
if (entry.pluginOwnerId !== pluginId || entry.modelSelectionLocked !== true) {
return undefined;
}
return isRecord(marker) && typeof marker.sourceThreadId === "string"
? { hostId, threadId: marker.sourceThreadId }
: undefined;
}
export function listBoundClaudeSessions(
api: OpenClawPluginApi,
sessionEntries?: SessionCatalogEntrySnapshot,
): Map<string, string> {
const config = currentClaudeSessionCatalogConfig(api);
const bound = new Map<string, string>();
for (const { sessionKey, entry } of listSessionCatalogEntries({
config,
runtime: api.runtime,
sessionEntries,
})) {
const source = boundClaudeSource(api.id, entry);
if (source) {
bound.set(adoptedSourceKey(source.hostId, source.threadId), sessionKey);
}
}
return bound;
}
/**
* Resolve the Claude model an agent actually routes to the Claude CLI backend.
* Callers must not assume the current default is routed: existing configs pin
* older Claude models, and stamping the default onto their sessions would
* select a model the operator never routed or allowed.
*/
export function resolveClaudeCliRoutedModelId(
config: OpenClawConfig,
agentId: string,
): string | undefined {
return CLAUDE_CLI_ROUTE_PROBE_MODEL_IDS.find(
(modelId) =>
resolveEffectiveAgentRuntime({
cfg: config,
provider: "anthropic",
modelId,
agentId,
}) === CLAUDE_CLI_BACKEND_ID,
);
}
export function resolveClaudeCatalogCreateSession(
api: OpenClawPluginApi,
requestedAgentId?: string,
): { model: string; agentRuntime: string } | undefined {
const config = currentClaudeSessionCatalogConfig(api);
const agentId = requestedAgentId ?? resolveDefaultAgentId(config);
const routedModelId = resolveClaudeCliRoutedModelId(config, agentId);
if (!routedModelId) {
return undefined;
}
const routedModelRef = `anthropic/${routedModelId}`;
const defaultModel = resolveDefaultModelForAgent({ cfg: config, agentId });
const allowed = resolveAllowedModelRef({
cfg: config,
catalog: [],
raw: routedModelRef,
defaultProvider: defaultModel.provider,
defaultModel: defaultModel.model,
agentId,
});
return "error" in allowed
? undefined
: {
model: routedModelRef,
agentRuntime: CLAUDE_CLI_BACKEND_ID,
};
}