mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-24 13:34:27 +00:00
refactor: dedupe runtime and helper flows
This commit is contained in:
@@ -344,6 +344,40 @@ async function moveToTrashBestEffort(pathname: string): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
function respondWorkspaceFileInvalid(respond: RespondFn, name: string, reason: string): void {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.INVALID_REQUEST, `unsafe workspace file "${name}" (${reason})`),
|
||||
);
|
||||
}
|
||||
|
||||
function respondWorkspaceFileUnsafe(respond: RespondFn, name: string): void {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.INVALID_REQUEST, `unsafe workspace file "${name}"`),
|
||||
);
|
||||
}
|
||||
|
||||
function respondWorkspaceFileMissing(params: {
|
||||
respond: RespondFn;
|
||||
agentId: string;
|
||||
workspaceDir: string;
|
||||
name: string;
|
||||
filePath: string;
|
||||
}): void {
|
||||
params.respond(
|
||||
true,
|
||||
{
|
||||
agentId: params.agentId,
|
||||
workspace: params.workspaceDir,
|
||||
file: { name: params.name, path: params.filePath, missing: true },
|
||||
},
|
||||
undefined,
|
||||
);
|
||||
}
|
||||
|
||||
export const agentsHandlers: GatewayRequestHandlers = {
|
||||
"agents.list": ({ params, respond }) => {
|
||||
if (!validateAgentsListParams(params)) {
|
||||
@@ -601,26 +635,11 @@ export const agentsHandlers: GatewayRequestHandlers = {
|
||||
allowMissing: true,
|
||||
});
|
||||
if (resolvedPath.kind === "invalid") {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(
|
||||
ErrorCodes.INVALID_REQUEST,
|
||||
`unsafe workspace file "${name}" (${resolvedPath.reason})`,
|
||||
),
|
||||
);
|
||||
respondWorkspaceFileInvalid(respond, name, resolvedPath.reason);
|
||||
return;
|
||||
}
|
||||
if (resolvedPath.kind === "missing") {
|
||||
respond(
|
||||
true,
|
||||
{
|
||||
agentId,
|
||||
workspace: workspaceDir,
|
||||
file: { name, path: filePath, missing: true },
|
||||
},
|
||||
undefined,
|
||||
);
|
||||
respondWorkspaceFileMissing({ respond, agentId, workspaceDir, name, filePath });
|
||||
return;
|
||||
}
|
||||
let safeRead: Awaited<ReturnType<typeof readLocalFileSafely>>;
|
||||
@@ -628,22 +647,10 @@ export const agentsHandlers: GatewayRequestHandlers = {
|
||||
safeRead = await readLocalFileSafely({ filePath: resolvedPath.ioPath });
|
||||
} catch (err) {
|
||||
if (err instanceof SafeOpenError && err.code === "not-found") {
|
||||
respond(
|
||||
true,
|
||||
{
|
||||
agentId,
|
||||
workspace: workspaceDir,
|
||||
file: { name, path: filePath, missing: true },
|
||||
},
|
||||
undefined,
|
||||
);
|
||||
respondWorkspaceFileMissing({ respond, agentId, workspaceDir, name, filePath });
|
||||
return;
|
||||
}
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.INVALID_REQUEST, `unsafe workspace file "${name}"`),
|
||||
);
|
||||
respondWorkspaceFileUnsafe(respond, name);
|
||||
return;
|
||||
}
|
||||
respond(
|
||||
@@ -690,14 +697,7 @@ export const agentsHandlers: GatewayRequestHandlers = {
|
||||
allowMissing: true,
|
||||
});
|
||||
if (resolvedPath.kind === "invalid") {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(
|
||||
ErrorCodes.INVALID_REQUEST,
|
||||
`unsafe workspace file "${name}" (${resolvedPath.reason})`,
|
||||
),
|
||||
);
|
||||
respondWorkspaceFileInvalid(respond, name, resolvedPath.reason);
|
||||
return;
|
||||
}
|
||||
const content = String(params.content ?? "");
|
||||
@@ -709,11 +709,7 @@ export const agentsHandlers: GatewayRequestHandlers = {
|
||||
encoding: "utf8",
|
||||
});
|
||||
} catch {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.INVALID_REQUEST, `unsafe workspace file "${name}"`),
|
||||
);
|
||||
respondWorkspaceFileUnsafe(respond, name);
|
||||
return;
|
||||
}
|
||||
const meta = await statFileSafely(resolvedPath.ioPath);
|
||||
|
||||
@@ -284,6 +284,32 @@ async function closeAcpRuntimeForSession(params: {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async function cleanupSessionBeforeMutation(params: {
|
||||
cfg: ReturnType<typeof loadConfig>;
|
||||
key: string;
|
||||
target: ReturnType<typeof resolveGatewaySessionStoreTarget>;
|
||||
entry: SessionEntry | undefined;
|
||||
legacyKey?: string;
|
||||
canonicalKey?: string;
|
||||
reason: "session-reset" | "session-delete";
|
||||
}) {
|
||||
const cleanupError = await ensureSessionRuntimeCleanup({
|
||||
cfg: params.cfg,
|
||||
key: params.key,
|
||||
target: params.target,
|
||||
sessionId: params.entry?.sessionId,
|
||||
});
|
||||
if (cleanupError) {
|
||||
return cleanupError;
|
||||
}
|
||||
return await closeAcpRuntimeForSession({
|
||||
cfg: params.cfg,
|
||||
sessionKey: params.legacyKey ?? params.canonicalKey ?? params.target.canonicalKey ?? params.key,
|
||||
entry: params.entry,
|
||||
reason: params.reason,
|
||||
});
|
||||
}
|
||||
|
||||
export const sessionsHandlers: GatewayRequestHandlers = {
|
||||
"sessions.list": ({ params, respond }) => {
|
||||
if (!assertValidParams(params, validateSessionsListParams, "sessions.list", respond)) {
|
||||
@@ -445,20 +471,17 @@ export const sessionsHandlers: GatewayRequestHandlers = {
|
||||
},
|
||||
);
|
||||
await triggerInternalHook(hookEvent);
|
||||
const sessionId = entry?.sessionId;
|
||||
const cleanupError = await ensureSessionRuntimeCleanup({ cfg, key, target, sessionId });
|
||||
if (cleanupError) {
|
||||
respond(false, undefined, cleanupError);
|
||||
return;
|
||||
}
|
||||
const acpCleanupError = await closeAcpRuntimeForSession({
|
||||
const mutationCleanupError = await cleanupSessionBeforeMutation({
|
||||
cfg,
|
||||
sessionKey: legacyKey ?? canonicalKey ?? target.canonicalKey ?? key,
|
||||
key,
|
||||
target,
|
||||
entry,
|
||||
legacyKey,
|
||||
canonicalKey,
|
||||
reason: "session-reset",
|
||||
});
|
||||
if (acpCleanupError) {
|
||||
respond(false, undefined, acpCleanupError);
|
||||
if (mutationCleanupError) {
|
||||
respond(false, undefined, mutationCleanupError);
|
||||
return;
|
||||
}
|
||||
let oldSessionId: string | undefined;
|
||||
@@ -542,22 +565,20 @@ export const sessionsHandlers: GatewayRequestHandlers = {
|
||||
const deleteTranscript = typeof p.deleteTranscript === "boolean" ? p.deleteTranscript : true;
|
||||
|
||||
const { entry, legacyKey, canonicalKey } = loadSessionEntry(key);
|
||||
const sessionId = entry?.sessionId;
|
||||
const cleanupError = await ensureSessionRuntimeCleanup({ cfg, key, target, sessionId });
|
||||
if (cleanupError) {
|
||||
respond(false, undefined, cleanupError);
|
||||
return;
|
||||
}
|
||||
const acpCleanupError = await closeAcpRuntimeForSession({
|
||||
const mutationCleanupError = await cleanupSessionBeforeMutation({
|
||||
cfg,
|
||||
sessionKey: legacyKey ?? canonicalKey ?? target.canonicalKey ?? key,
|
||||
key,
|
||||
target,
|
||||
entry,
|
||||
legacyKey,
|
||||
canonicalKey,
|
||||
reason: "session-delete",
|
||||
});
|
||||
if (acpCleanupError) {
|
||||
respond(false, undefined, acpCleanupError);
|
||||
if (mutationCleanupError) {
|
||||
respond(false, undefined, mutationCleanupError);
|
||||
return;
|
||||
}
|
||||
const sessionId = entry?.sessionId;
|
||||
const deleted = await updateSessionStore(storePath, (store) => {
|
||||
const { primaryKey } = migrateAndPruneSessionStoreKey({ cfg, key, store });
|
||||
const hadEntry = Boolean(store[primaryKey]);
|
||||
|
||||
Reference in New Issue
Block a user