Fix pending permission MCP listing (#1561)
* Fix pending permission MCP responses * Tighten MCP permission sanitizer typing
This commit is contained in:
@@ -17,6 +17,7 @@ import type { AgentMode, AgentProvider, ProviderSnapshotEntry } from "./agent-sd
|
|||||||
import { createProviderSnapshotManagerStub } from "../test-utils/session-stubs.js";
|
import { createProviderSnapshotManagerStub } from "../test-utils/session-stubs.js";
|
||||||
import {
|
import {
|
||||||
AgentListItemPayloadSchema,
|
AgentListItemPayloadSchema,
|
||||||
|
AgentPermissionRequestPayloadSchema,
|
||||||
AgentSnapshotPayloadSchema,
|
AgentSnapshotPayloadSchema,
|
||||||
} from "@getpaseo/protocol/messages";
|
} from "@getpaseo/protocol/messages";
|
||||||
import type { PersistedProjectRecord, PersistedWorkspaceRecord } from "../workspace-registry.js";
|
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 () => {
|
it("loads archived agents before reading get_agent_activity", async () => {
|
||||||
const { agentManager, agentStorage, spies } = createTestDeps();
|
const { agentManager, agentStorage, spies } = createTestDeps();
|
||||||
const record = createStoredRecord({ id: "archived-activity-agent" });
|
const record = createStoredRecord({ id: "archived-activity-agent" });
|
||||||
|
|||||||
@@ -2371,7 +2371,7 @@ export async function createAgentMcpServer(options: AgentMcpServerOptions): Prom
|
|||||||
return payload.pendingPermissions.map((request) => ({
|
return payload.pendingPermissions.map((request) => ({
|
||||||
agentId: agent.id,
|
agentId: agent.id,
|
||||||
status: payload.status,
|
status: payload.status,
|
||||||
request,
|
request: sanitizePermissionRequest(request),
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -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(
|
export function sanitizePermissionRequest(
|
||||||
permission: AgentPermissionRequest | null | undefined,
|
permission: AgentPermissionRequest | null | undefined,
|
||||||
): AgentPermissionRequest | null {
|
): AgentPermissionRequest | null {
|
||||||
@@ -174,6 +181,9 @@ export function sanitizePermissionRequest(
|
|||||||
if (sanitized.input === undefined) {
|
if (sanitized.input === undefined) {
|
||||||
delete sanitized.input;
|
delete sanitized.input;
|
||||||
}
|
}
|
||||||
|
if (sanitized.detail === undefined) {
|
||||||
|
delete sanitized.detail;
|
||||||
|
}
|
||||||
if (sanitized.suggestions === undefined) {
|
if (sanitized.suggestions === undefined) {
|
||||||
delete sanitized.suggestions;
|
delete sanitized.suggestions;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user