


















11import {
22createIdentityFromEnsure,
33identityHasStableSessionId,
4-identityEquals,
54isSessionIdentityPending,
65mergeSessionIdentity,
7-resolveRuntimeResumeSessionId,
8-resolveRuntimeHandleIdentifiersFromIdentity,
96resolveSessionIdentityFromMeta,
107} from "@openclaw/acp-core/runtime/session-identity";
118import type {
@@ -49,6 +46,7 @@ import {
4946resolveManagerRuntimeCapabilities,
5047} from "./manager.runtime-controls.js";
5148import { ManagerRuntimeHandleCache } from "./manager.runtime-handle-cache.js";
49+import { ensureManagerRuntimeHandle } from "./manager.runtime-handle-ensure.js";
5250import { consumeAcpTurnStream } from "./manager.turn-stream.js";
5351import {
5452awaitTurnWithTimeout,
@@ -75,11 +73,9 @@ import {
7573import {
7674canonicalizeAcpSessionKey,
7775createUnsupportedControlError,
78-hasLegacyAcpIdentityProjection,
7976normalizeAcpErrorCode,
8077normalizeActorKey,
8178requireReadySessionMeta,
82-resolveAcpAgentFromSessionKey,
8379resolveAcpSessionResolutionError,
8480resolveMissingMetaError,
8581} from "./manager.utils.js";
@@ -90,7 +86,6 @@ import {
9086normalizeText,
9187resolveRuntimeConfigOptionKey,
9288resolveRuntimeOptionsFromMeta,
93-runtimeOptionsEqual,
9489validateRuntimeConfigOptionInput,
9590validateRuntimeModeInput,
9691validateRuntimeOptionPatch,
@@ -1218,194 +1213,14 @@ export class AcpSessionManager {
12181213sessionKey: string;
12191214meta: SessionAcpMeta;
12201215}): Promise<{ runtime: AcpRuntime; handle: AcpRuntimeHandle; meta: SessionAcpMeta }> {
1221-const agent =
1222-normalizeText(params.meta.agent) || resolveAcpAgentFromSessionKey(params.sessionKey, "main");
1223-const mode = params.meta.mode;
1224-const runtimeOptions = resolveRuntimeOptionsFromMeta(params.meta);
1225-const cwd = runtimeOptions.cwd ?? normalizeText(params.meta.cwd);
1226-const model = normalizeText(runtimeOptions.model);
1227-const thinking = normalizeText(runtimeOptions.thinking);
1228-const configuredBackend = (params.meta.backend || params.cfg.acp?.backend || "").trim();
1229-const configSignature = resolveRuntimeConfigCacheKey(params.cfg);
1230-const cached = this.runtimeHandles.get(params.sessionKey);
1231-if (cached) {
1232-const backendMatches = !configuredBackend || cached.backend === configuredBackend;
1233-const agentMatches = cached.agent === agent;
1234-const modeMatches = cached.mode === mode;
1235-const cwdMatches = (cached.cwd ?? "") === (cwd ?? "");
1236-const configMatches = cached.configSignature === configSignature;
1237-const handleMatchesMeta = this.runtimeHandles.handleMatchesMeta({
1238-handle: cached.handle,
1239-meta: params.meta,
1240-});
1241-if (
1242-backendMatches &&
1243-agentMatches &&
1244-modeMatches &&
1245-cwdMatches &&
1246-configMatches &&
1247-handleMatchesMeta &&
1248-(await this.runtimeHandles.isReusable({
1249-sessionKey: params.sessionKey,
1250-runtime: cached.runtime,
1251-handle: cached.handle,
1252-}))
1253-) {
1254-return {
1255-runtime: cached.runtime,
1256-handle: cached.handle,
1257-meta: params.meta,
1258-};
1259-}
1260-await this.runtimeHandles.close({
1261-sessionKey: params.sessionKey,
1262-reason: "runtime-handle-replaced",
1263-});
1264-}
1265-1266-this.enforceConcurrentSessionLimit({
1267-cfg: params.cfg,
1268-sessionKey: params.sessionKey,
1269-});
1270-1271-const backend = this.deps.requireRuntimeBackend(configuredBackend || undefined);
1272-const runtime = backend.runtime;
1273-const previousMeta = params.meta;
1274-const previousIdentity = resolveSessionIdentityFromMeta(previousMeta);
1275-let identityForEnsure = previousIdentity;
1276-const persistedResumeSessionId =
1277-mode === "persistent" ? resolveRuntimeResumeSessionId(previousIdentity) : undefined;
1278-const shouldPrepareFreshPersistentSession =
1279-mode === "persistent" &&
1280-previousIdentity != null &&
1281-!identityHasStableSessionId(previousIdentity);
1282-const ensureSession = async (resumeSessionId?: string) =>
1283-await withAcpRuntimeErrorBoundary({
1284-run: async () =>
1285-await runtime.ensureSession({
1286-sessionKey: params.sessionKey,
1287- agent,
1288- mode,
1289- ...(resumeSessionId ? { resumeSessionId } : {}),
1290- ...(model ? { model } : {}),
1291- ...(thinking ? { thinking } : {}),
1292- cwd,
1293-}),
1294-fallbackCode: "ACP_SESSION_INIT_FAILED",
1295-fallbackMessage: "Could not initialize ACP session runtime.",
1296-});
1297-let ensured: AcpRuntimeHandle;
1298-if (shouldPrepareFreshPersistentSession) {
1299-await runtime.prepareFreshSession?.({
1300-sessionKey: params.sessionKey,
1301-});
1302-}
1303-if (persistedResumeSessionId) {
1304-try {
1305-ensured = await ensureSession(persistedResumeSessionId);
1306-} catch (error) {
1307-const acpError = toAcpRuntimeError({
1308- error,
1309-fallbackCode: "ACP_SESSION_INIT_FAILED",
1310-fallbackMessage: "Could not initialize ACP session runtime.",
1311-});
1312-if (acpError.code !== "ACP_SESSION_INIT_FAILED") {
1313-throw acpError;
1314-}
1315-logVerbose(
1316-`acp-manager: resume init failed for ${params.sessionKey}; retrying without persisted ACP session id: ${acpError.message}`,
1317-);
1318-if (identityForEnsure) {
1319-const {
1320-acpxSessionId: _staleAcpxSessionId,
1321-agentSessionId: _staleAgentSessionId,
1322- ...retryIdentity
1323-} = identityForEnsure;
1324-// The persisted resume identifiers already failed, so do not merge them back into the
1325-// fresh named-session handle returned by the retry path.
1326-identityForEnsure = {
1327- ...retryIdentity,
1328-state: "pending",
1329-};
1330-}
1331-ensured = await ensureSession();
1332-}
1333-} else {
1334-ensured = await ensureSession();
1335-}
1336-1337-const now = Date.now();
1338-const effectiveCwd = normalizeText(ensured.cwd) ?? cwd;
1339-const nextRuntimeOptions = normalizeRuntimeOptions({
1340- ...runtimeOptions,
1341- ...(effectiveCwd ? { cwd: effectiveCwd } : {}),
1342-});
1343-const nextIdentity =
1344-mergeSessionIdentity({
1345-current: identityForEnsure,
1346-incoming: createIdentityFromEnsure({
1347-handle: ensured,
1348- now,
1349-}),
1350- now,
1351-}) ?? identityForEnsure;
1352-const nextHandleIdentifiers = resolveRuntimeHandleIdentifiersFromIdentity(nextIdentity);
1353-const nextHandle: AcpRuntimeHandle = {
1354- ...ensured,
1355- ...(nextHandleIdentifiers.backendSessionId
1356- ? { backendSessionId: nextHandleIdentifiers.backendSessionId }
1357- : {}),
1358- ...(nextHandleIdentifiers.agentSessionId
1359- ? { agentSessionId: nextHandleIdentifiers.agentSessionId }
1360- : {}),
1361-};
1362-const nextMeta: SessionAcpMeta = {
1363-backend: ensured.backend || backend.id,
1364- agent,
1365-runtimeSessionName: ensured.runtimeSessionName,
1366- ...(nextIdentity ? { identity: nextIdentity } : {}),
1367-mode: params.meta.mode,
1368- ...(Object.keys(nextRuntimeOptions).length > 0 ? { runtimeOptions: nextRuntimeOptions } : {}),
1369- ...(effectiveCwd ? { cwd: effectiveCwd } : {}),
1370-state: previousMeta.state,
1371-lastActivityAt: now,
1372- ...(previousMeta.lastError ? { lastError: previousMeta.lastError } : {}),
1373-};
1374-const shouldPersistMeta =
1375-previousMeta.backend !== nextMeta.backend ||
1376-previousMeta.runtimeSessionName !== nextMeta.runtimeSessionName ||
1377-!identityEquals(previousIdentity, nextIdentity) ||
1378-previousMeta.agent !== nextMeta.agent ||
1379-previousMeta.cwd !== nextMeta.cwd ||
1380-!runtimeOptionsEqual(previousMeta.runtimeOptions, nextMeta.runtimeOptions) ||
1381-hasLegacyAcpIdentityProjection(previousMeta);
1382-if (shouldPersistMeta) {
1383-await this.writeSessionMeta({
1384-cfg: params.cfg,
1385-sessionKey: params.sessionKey,
1386-mutate: (_current, entry) => {
1387-if (!entry) {
1388-return null;
1389-}
1390-return nextMeta;
1391-},
1392-});
1393-}
1394-this.runtimeHandles.set(params.sessionKey, {
1395- runtime,
1396-handle: nextHandle,
1397-backend: ensured.backend || backend.id,
1398- agent,
1399- mode,
1400-cwd: effectiveCwd,
1401- configSignature,
1402-appliedControlSignature: undefined,
1216+return await ensureManagerRuntimeHandle({
1217+ ...params,
1218+deps: this.deps,
1219+runtimeHandles: this.runtimeHandles,
1220+enforceConcurrentSessionLimit: (limitParams) =>
1221+this.enforceConcurrentSessionLimit(limitParams),
1222+writeSessionMeta: async (writeParams) => await this.writeSessionMeta(writeParams),
14031223});
1404-return {
1405- runtime,
1406-handle: nextHandle,
1407-meta: nextMeta,
1408-};
14091224}
1410122514111226private async persistRuntimeOptions(params: {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。