Fix pending permission MCP listing (#1561)

* Fix pending permission MCP responses

* Tighten MCP permission sanitizer typing
This commit is contained in:
Mohamed Boudra
2026-06-16 20:53:23 +08:00
committed by GitHub
parent 37de9ea796
commit 0fef66283a
3 changed files with 72 additions and 1 deletions

View File

@@ -17,6 +17,7 @@ import type { AgentMode, AgentProvider, ProviderSnapshotEntry } from "./agent-sd
import { createProviderSnapshotManagerStub } from "../test-utils/session-stubs.js";
import {
AgentListItemPayloadSchema,
AgentPermissionRequestPayloadSchema,
AgentSnapshotPayloadSchema,
} from "@getpaseo/protocol/messages";
import type { PersistedProjectRecord, PersistedWorkspaceRecord } from "../workspace-registry.js";
@@ -3739,6 +3740,66 @@ describe("agent snapshot MCP serialization", () => {
}
});
it("emits list_pending_permissions payloads that satisfy the declared output schema", async () => {
const { agentManager, agentStorage, spies } = createTestDeps();
spies.agentManager.listAgents.mockReturnValue([
createManagedAgent({
id: "agent-with-permission",
provider: "codex",
pendingPermissions: new Map([
[
"perm-minimal",
{
id: "perm-minimal",
provider: "codex",
name: "request_user_input",
kind: "question",
title: "Need input",
input: { prompt: "Pick one" },
detail: undefined,
metadata: { source: "test" },
},
],
]),
}),
]);
const server = await createAgentMcpServer({
agentManager,
agentStorage,
logger,
providerSnapshotManager: createClaudeOnlyManager(),
});
const tool = registeredTool(server, "list_pending_permissions");
const response = await tool.handler({});
const permissions = z
.array(
z.object({
agentId: z.string(),
status: z.string(),
request: AgentPermissionRequestPayloadSchema,
}),
)
.parse(response.structuredContent.permissions);
expect(permissions).toEqual([
{
agentId: "agent-with-permission",
status: "idle",
request: {
id: "perm-minimal",
provider: "codex",
name: "request_user_input",
kind: "question",
title: "Need input",
input: { prompt: "Pick one" },
metadata: { source: "test" },
},
},
]);
expectOutputSchemaAccepts(tool, response.structuredContent);
});
it("loads archived agents before reading get_agent_activity", async () => {
const { agentManager, agentStorage, spies } = createTestDeps();
const record = createStoredRecord({ id: "archived-activity-agent" });

View File

@@ -2371,7 +2371,7 @@ export async function createAgentMcpServer(options: AgentMcpServerOptions): Prom
return payload.pendingPermissions.map((request) => ({
agentId: agent.id,
status: payload.status,
request,
request: sanitizePermissionRequest(request),
}));
});

View File

@@ -158,6 +158,13 @@ export async function waitForAgentWithTimeout(
}
}
export function sanitizePermissionRequest(
permission: AgentPermissionRequest,
): AgentPermissionRequest;
export function sanitizePermissionRequest(permission: null | undefined): null;
export function sanitizePermissionRequest(
permission: AgentPermissionRequest | null | undefined,
): AgentPermissionRequest | null;
export function sanitizePermissionRequest(
permission: AgentPermissionRequest | null | undefined,
): AgentPermissionRequest | null {
@@ -174,6 +181,9 @@ export function sanitizePermissionRequest(
if (sanitized.input === undefined) {
delete sanitized.input;
}
if (sanitized.detail === undefined) {
delete sanitized.detail;
}
if (sanitized.suggestions === undefined) {
delete sanitized.suggestions;
}