refactor(gateway): dedupe agents server-method handlers

This commit is contained in:
Peter Steinberger
2026-03-03 02:38:11 +00:00
parent 7a8232187b
commit b8181e5944

View File

@@ -120,6 +120,43 @@ type ResolvedAgentWorkspaceFilePath =
reason: string;
};
type ResolvedWorkspaceFilePath = Exclude<ResolvedAgentWorkspaceFilePath, { kind: "invalid" }>;
function resolveNotFoundWorkspaceFilePathResult(params: {
error: unknown;
allowMissing: boolean;
requestPath: string;
ioPath: string;
workspaceReal: string;
}): Extract<ResolvedAgentWorkspaceFilePath, { kind: "missing" | "invalid" }> | undefined {
if (!isNotFoundPathError(params.error)) {
return undefined;
}
if (params.allowMissing) {
return {
kind: "missing",
requestPath: params.requestPath,
ioPath: params.ioPath,
workspaceReal: params.workspaceReal,
};
}
return { kind: "invalid", requestPath: params.requestPath, reason: "file not found" };
}
function resolveWorkspaceFilePathResultOrThrow(params: {
error: unknown;
allowMissing: boolean;
requestPath: string;
ioPath: string;
workspaceReal: string;
}): Extract<ResolvedAgentWorkspaceFilePath, { kind: "missing" | "invalid" }> {
const notFoundResult = resolveNotFoundWorkspaceFilePathResult(params);
if (notFoundResult) {
return notFoundResult;
}
throw params.error;
}
async function resolveWorkspaceRealPath(workspaceDir: string): Promise<string> {
try {
return await fs.realpath(workspaceDir);
@@ -151,17 +188,21 @@ async function resolveAgentWorkspaceFilePath(params: {
};
}
const notFoundContext = {
allowMissing: params.allowMissing,
requestPath,
workspaceReal,
} as const;
let candidateLstat: Awaited<ReturnType<typeof fs.lstat>>;
try {
candidateLstat = await fs.lstat(candidatePath);
} catch (err) {
if (isNotFoundPathError(err)) {
if (params.allowMissing) {
return { kind: "missing", requestPath, ioPath: candidatePath, workspaceReal };
}
return { kind: "invalid", requestPath, reason: "file not found" };
}
throw err;
return resolveWorkspaceFilePathResultOrThrow({
error: err,
...notFoundContext,
ioPath: candidatePath,
});
}
if (candidateLstat.isSymbolicLink()) {
@@ -169,25 +210,21 @@ async function resolveAgentWorkspaceFilePath(params: {
try {
targetReal = await fs.realpath(candidatePath);
} catch (err) {
if (isNotFoundPathError(err)) {
if (params.allowMissing) {
return { kind: "missing", requestPath, ioPath: candidatePath, workspaceReal };
}
return { kind: "invalid", requestPath, reason: "file not found" };
}
throw err;
return resolveWorkspaceFilePathResultOrThrow({
error: err,
...notFoundContext,
ioPath: candidatePath,
});
}
let targetStat: Awaited<ReturnType<typeof fs.stat>>;
try {
targetStat = await fs.stat(targetReal);
} catch (err) {
if (isNotFoundPathError(err)) {
if (params.allowMissing) {
return { kind: "missing", requestPath, ioPath: targetReal, workspaceReal };
}
return { kind: "invalid", requestPath, reason: "file not found" };
}
throw err;
return resolveWorkspaceFilePathResultOrThrow({
error: err,
...notFoundContext,
ioPath: targetReal,
});
}
if (!targetStat.isFile()) {
return { kind: "invalid", requestPath, reason: "path is not a regular file" };
@@ -328,6 +365,25 @@ function resolveOptionalStringParam(value: unknown): string | undefined {
return typeof value === "string" && value.trim() ? value.trim() : undefined;
}
function respondInvalidMethodParams(respond: RespondFn, method: string, errors: unknown): void {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`invalid ${method} params: ${formatValidationErrors(errors)}`,
),
);
}
function isConfiguredAgent(cfg: ReturnType<typeof loadConfig>, agentId: string): boolean {
return findAgentEntryIndex(listAgentEntries(cfg), agentId) >= 0;
}
function respondAgentNotFound(respond: RespondFn, agentId: string): void {
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `agent "${agentId}" not found`));
}
async function moveToTrashBestEffort(pathname: string): Promise<void> {
if (!pathname) {
return;
@@ -356,10 +412,7 @@ async function resolveWorkspaceFilePathOrRespond(params: {
respond: RespondFn;
workspaceDir: string;
name: string;
}): Promise<
| Exclude<Awaited<ReturnType<typeof resolveAgentWorkspaceFilePath>>, { kind: "invalid" }>
| undefined
> {
}): Promise<ResolvedWorkspaceFilePath | undefined> {
const resolvedPath = await resolveAgentWorkspaceFilePath({
workspaceDir: params.workspaceDir,
name: params.name,
@@ -490,27 +543,14 @@ export const agentsHandlers: GatewayRequestHandlers = {
},
"agents.update": async ({ params, respond }) => {
if (!validateAgentsUpdateParams(params)) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`invalid agents.update params: ${formatValidationErrors(
validateAgentsUpdateParams.errors,
)}`,
),
);
respondInvalidMethodParams(respond, "agents.update", validateAgentsUpdateParams.errors);
return;
}
const cfg = loadConfig();
const agentId = normalizeAgentId(String(params.agentId ?? ""));
if (findAgentEntryIndex(listAgentEntries(cfg), agentId) < 0) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, `agent "${agentId}" not found`),
);
if (!isConfiguredAgent(cfg, agentId)) {
respondAgentNotFound(respond, agentId);
return;
}
@@ -549,16 +589,7 @@ export const agentsHandlers: GatewayRequestHandlers = {
},
"agents.delete": async ({ params, respond }) => {
if (!validateAgentsDeleteParams(params)) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`invalid agents.delete params: ${formatValidationErrors(
validateAgentsDeleteParams.errors,
)}`,
),
);
respondInvalidMethodParams(respond, "agents.delete", validateAgentsDeleteParams.errors);
return;
}
@@ -572,12 +603,8 @@ export const agentsHandlers: GatewayRequestHandlers = {
);
return;
}
if (findAgentEntryIndex(listAgentEntries(cfg), agentId) < 0) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, `agent "${agentId}" not found`),
);
if (!isConfiguredAgent(cfg, agentId)) {
respondAgentNotFound(respond, agentId);
return;
}
@@ -631,16 +658,7 @@ export const agentsHandlers: GatewayRequestHandlers = {
},
"agents.files.get": async ({ params, respond }) => {
if (!validateAgentsFilesGetParams(params)) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`invalid agents.files.get params: ${formatValidationErrors(
validateAgentsFilesGetParams.errors,
)}`,
),
);
respondInvalidMethodParams(respond, "agents.files.get", validateAgentsFilesGetParams.errors);
return;
}
const resolved = resolveAgentWorkspaceFileOrRespondError(params, respond);
@@ -691,16 +709,7 @@ export const agentsHandlers: GatewayRequestHandlers = {
},
"agents.files.set": async ({ params, respond }) => {
if (!validateAgentsFilesSetParams(params)) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`invalid agents.files.set params: ${formatValidationErrors(
validateAgentsFilesSetParams.errors,
)}`,
),
);
respondInvalidMethodParams(respond, "agents.files.set", validateAgentsFilesSetParams.errors);
return;
}
const resolved = resolveAgentWorkspaceFileOrRespondError(params, respond);