mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-18 11:17:27 +00:00
refactor: centralize acp session resolution guards
This commit is contained in:
@@ -49,7 +49,9 @@ import {
|
||||
normalizeAcpErrorCode,
|
||||
normalizeActorKey,
|
||||
normalizeSessionKey,
|
||||
requireReadySessionMeta,
|
||||
resolveAcpAgentFromSessionKey,
|
||||
resolveAcpSessionResolutionError,
|
||||
resolveMissingMetaError,
|
||||
resolveRuntimeIdleTtlMs,
|
||||
} from "./manager.utils.js";
|
||||
@@ -332,15 +334,7 @@ export class AcpSessionManager {
|
||||
cfg: params.cfg,
|
||||
sessionKey,
|
||||
});
|
||||
if (resolution.kind === "none") {
|
||||
throw new AcpRuntimeError(
|
||||
"ACP_SESSION_INIT_FAILED",
|
||||
`Session is not ACP-enabled: ${sessionKey}`,
|
||||
);
|
||||
}
|
||||
if (resolution.kind === "stale") {
|
||||
throw resolution.error;
|
||||
}
|
||||
const resolvedMeta = requireReadySessionMeta(resolution);
|
||||
const {
|
||||
runtime,
|
||||
handle: ensuredHandle,
|
||||
@@ -348,7 +342,7 @@ export class AcpSessionManager {
|
||||
} = await this.ensureRuntimeHandle({
|
||||
cfg: params.cfg,
|
||||
sessionKey,
|
||||
meta: resolution.meta,
|
||||
meta: resolvedMeta,
|
||||
});
|
||||
let handle = ensuredHandle;
|
||||
let meta = ensuredMeta;
|
||||
@@ -414,19 +408,11 @@ export class AcpSessionManager {
|
||||
cfg: params.cfg,
|
||||
sessionKey,
|
||||
});
|
||||
if (resolution.kind === "none") {
|
||||
throw new AcpRuntimeError(
|
||||
"ACP_SESSION_INIT_FAILED",
|
||||
`Session is not ACP-enabled: ${sessionKey}`,
|
||||
);
|
||||
}
|
||||
if (resolution.kind === "stale") {
|
||||
throw resolution.error;
|
||||
}
|
||||
const resolvedMeta = requireReadySessionMeta(resolution);
|
||||
const { runtime, handle, meta } = await this.ensureRuntimeHandle({
|
||||
cfg: params.cfg,
|
||||
sessionKey,
|
||||
meta: resolution.meta,
|
||||
meta: resolvedMeta,
|
||||
});
|
||||
const capabilities = await this.resolveRuntimeCapabilities({ runtime, handle });
|
||||
if (!capabilities.controls.includes("session/set_mode") || !runtime.setMode) {
|
||||
@@ -479,19 +465,11 @@ export class AcpSessionManager {
|
||||
cfg: params.cfg,
|
||||
sessionKey,
|
||||
});
|
||||
if (resolution.kind === "none") {
|
||||
throw new AcpRuntimeError(
|
||||
"ACP_SESSION_INIT_FAILED",
|
||||
`Session is not ACP-enabled: ${sessionKey}`,
|
||||
);
|
||||
}
|
||||
if (resolution.kind === "stale") {
|
||||
throw resolution.error;
|
||||
}
|
||||
const resolvedMeta = requireReadySessionMeta(resolution);
|
||||
const { runtime, handle, meta } = await this.ensureRuntimeHandle({
|
||||
cfg: params.cfg,
|
||||
sessionKey,
|
||||
meta: resolution.meta,
|
||||
meta: resolvedMeta,
|
||||
});
|
||||
const inferredPatch = inferRuntimeOptionPatchFromConfigOption(key, value);
|
||||
const capabilities = await this.resolveRuntimeCapabilities({ runtime, handle });
|
||||
@@ -558,17 +536,9 @@ export class AcpSessionManager {
|
||||
cfg: params.cfg,
|
||||
sessionKey,
|
||||
});
|
||||
if (resolution.kind === "none") {
|
||||
throw new AcpRuntimeError(
|
||||
"ACP_SESSION_INIT_FAILED",
|
||||
`Session is not ACP-enabled: ${sessionKey}`,
|
||||
);
|
||||
}
|
||||
if (resolution.kind === "stale") {
|
||||
throw resolution.error;
|
||||
}
|
||||
const resolvedMeta = requireReadySessionMeta(resolution);
|
||||
const nextOptions = mergeRuntimeOptions({
|
||||
current: resolveRuntimeOptionsFromMeta(resolution.meta),
|
||||
current: resolveRuntimeOptionsFromMeta(resolvedMeta),
|
||||
patch: validatedPatch,
|
||||
});
|
||||
await this.persistRuntimeOptions({
|
||||
@@ -594,19 +564,11 @@ export class AcpSessionManager {
|
||||
cfg: params.cfg,
|
||||
sessionKey,
|
||||
});
|
||||
if (resolution.kind === "none") {
|
||||
throw new AcpRuntimeError(
|
||||
"ACP_SESSION_INIT_FAILED",
|
||||
`Session is not ACP-enabled: ${sessionKey}`,
|
||||
);
|
||||
}
|
||||
if (resolution.kind === "stale") {
|
||||
throw resolution.error;
|
||||
}
|
||||
const resolvedMeta = requireReadySessionMeta(resolution);
|
||||
const { runtime, handle } = await this.ensureRuntimeHandle({
|
||||
cfg: params.cfg,
|
||||
sessionKey,
|
||||
meta: resolution.meta,
|
||||
meta: resolvedMeta,
|
||||
});
|
||||
await withAcpRuntimeErrorBoundary({
|
||||
run: async () =>
|
||||
@@ -638,15 +600,7 @@ export class AcpSessionManager {
|
||||
cfg: input.cfg,
|
||||
sessionKey,
|
||||
});
|
||||
if (resolution.kind === "none") {
|
||||
throw new AcpRuntimeError(
|
||||
"ACP_SESSION_INIT_FAILED",
|
||||
`Session is not ACP-enabled: ${sessionKey}`,
|
||||
);
|
||||
}
|
||||
if (resolution.kind === "stale") {
|
||||
throw resolution.error;
|
||||
}
|
||||
const resolvedMeta = requireReadySessionMeta(resolution);
|
||||
|
||||
const {
|
||||
runtime,
|
||||
@@ -655,7 +609,7 @@ export class AcpSessionManager {
|
||||
} = await this.ensureRuntimeHandle({
|
||||
cfg: input.cfg,
|
||||
sessionKey,
|
||||
meta: resolution.meta,
|
||||
meta: resolvedMeta,
|
||||
});
|
||||
let handle = ensuredHandle;
|
||||
const meta = ensuredMeta;
|
||||
@@ -810,19 +764,11 @@ export class AcpSessionManager {
|
||||
cfg: params.cfg,
|
||||
sessionKey,
|
||||
});
|
||||
if (resolution.kind === "none") {
|
||||
throw new AcpRuntimeError(
|
||||
"ACP_SESSION_INIT_FAILED",
|
||||
`Session is not ACP-enabled: ${sessionKey}`,
|
||||
);
|
||||
}
|
||||
if (resolution.kind === "stale") {
|
||||
throw resolution.error;
|
||||
}
|
||||
const resolvedMeta = requireReadySessionMeta(resolution);
|
||||
const { runtime, handle } = await this.ensureRuntimeHandle({
|
||||
cfg: params.cfg,
|
||||
sessionKey,
|
||||
meta: resolution.meta,
|
||||
meta: resolvedMeta,
|
||||
});
|
||||
try {
|
||||
await withAcpRuntimeErrorBoundary({
|
||||
@@ -868,27 +814,17 @@ export class AcpSessionManager {
|
||||
cfg: input.cfg,
|
||||
sessionKey,
|
||||
});
|
||||
if (resolution.kind === "none") {
|
||||
const resolutionError = resolveAcpSessionResolutionError(resolution);
|
||||
if (resolutionError) {
|
||||
if (input.requireAcpSession ?? true) {
|
||||
throw new AcpRuntimeError(
|
||||
"ACP_SESSION_INIT_FAILED",
|
||||
`Session is not ACP-enabled: ${sessionKey}`,
|
||||
);
|
||||
}
|
||||
return {
|
||||
runtimeClosed: false,
|
||||
metaCleared: false,
|
||||
};
|
||||
}
|
||||
if (resolution.kind === "stale") {
|
||||
if (input.requireAcpSession ?? true) {
|
||||
throw resolution.error;
|
||||
throw resolutionError;
|
||||
}
|
||||
return {
|
||||
runtimeClosed: false,
|
||||
metaCleared: false,
|
||||
};
|
||||
}
|
||||
const meta = resolution.meta;
|
||||
|
||||
let runtimeClosed = false;
|
||||
let runtimeNotice: string | undefined;
|
||||
@@ -896,7 +832,7 @@ export class AcpSessionManager {
|
||||
const { runtime, handle } = await this.ensureRuntimeHandle({
|
||||
cfg: input.cfg,
|
||||
sessionKey,
|
||||
meta: resolution.meta,
|
||||
meta,
|
||||
});
|
||||
await withAcpRuntimeErrorBoundary({
|
||||
run: async () =>
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { OpenClawConfig } from "../../config/config.js";
|
||||
import type { SessionAcpMeta } from "../../config/sessions/types.js";
|
||||
import { normalizeAgentId, parseAgentSessionKey } from "../../routing/session-key.js";
|
||||
import { ACP_ERROR_CODES, AcpRuntimeError } from "../runtime/errors.js";
|
||||
import type { AcpSessionResolution } from "./manager.types.js";
|
||||
|
||||
export function resolveAcpAgentFromSessionKey(sessionKey: string, fallback = "main"): string {
|
||||
const parsed = parseAgentSessionKey(sessionKey);
|
||||
@@ -15,6 +16,29 @@ export function resolveMissingMetaError(sessionKey: string): AcpRuntimeError {
|
||||
);
|
||||
}
|
||||
|
||||
export function resolveAcpSessionResolutionError(
|
||||
resolution: AcpSessionResolution,
|
||||
): AcpRuntimeError | null {
|
||||
if (resolution.kind === "ready") {
|
||||
return null;
|
||||
}
|
||||
if (resolution.kind === "stale") {
|
||||
return resolution.error;
|
||||
}
|
||||
return new AcpRuntimeError(
|
||||
"ACP_SESSION_INIT_FAILED",
|
||||
`Session is not ACP-enabled: ${resolution.sessionKey}`,
|
||||
);
|
||||
}
|
||||
|
||||
export function requireReadySessionMeta(resolution: AcpSessionResolution): SessionAcpMeta {
|
||||
const error = resolveAcpSessionResolutionError(resolution);
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
return resolution.meta;
|
||||
}
|
||||
|
||||
export function normalizeSessionKey(sessionKey: string): string {
|
||||
return sessionKey.trim();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { getAcpSessionManager } from "../../../acp/control-plane/manager.js";
|
||||
import { resolveAcpSessionResolutionError } from "../../../acp/control-plane/manager.utils.js";
|
||||
import {
|
||||
cleanupFailedAcpSpawn,
|
||||
type AcpSpawnRuntimeCloseHandle,
|
||||
@@ -10,7 +11,6 @@ import {
|
||||
resolveAcpDispatchPolicyError,
|
||||
resolveAcpDispatchPolicyMessage,
|
||||
} from "../../../acp/policy.js";
|
||||
import { AcpRuntimeError } from "../../../acp/runtime/errors.js";
|
||||
import {
|
||||
resolveAcpSessionCwd,
|
||||
resolveAcpThreadSessionDetailLines,
|
||||
@@ -390,24 +390,13 @@ function resolveAcpSessionForCommandOrStop(params: {
|
||||
cfg: params.cfg,
|
||||
sessionKey: params.sessionKey,
|
||||
});
|
||||
if (resolved.kind === "none") {
|
||||
const error = resolveAcpSessionResolutionError(resolved);
|
||||
if (error) {
|
||||
return stopWithText(
|
||||
collectAcpErrorText({
|
||||
error: new AcpRuntimeError(
|
||||
"ACP_SESSION_INIT_FAILED",
|
||||
`Session is not ACP-enabled: ${params.sessionKey}`,
|
||||
),
|
||||
error,
|
||||
fallbackCode: "ACP_SESSION_INIT_FAILED",
|
||||
fallbackMessage: "Session is not ACP-enabled.",
|
||||
}),
|
||||
);
|
||||
}
|
||||
if (resolved.kind === "stale") {
|
||||
return stopWithText(
|
||||
collectAcpErrorText({
|
||||
error: resolved.error,
|
||||
fallbackCode: "ACP_SESSION_INIT_FAILED",
|
||||
fallbackMessage: resolved.error.message,
|
||||
fallbackMessage: error.message,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user