logancyang_obsidian-copilot/src/agentMode/ui/permissionPrompter.ts
2026-05-30 10:41:38 -07:00

43 lines
1.7 KiB
TypeScript

import type { AgentSession } from "@/agentMode/session/AgentSession";
import type {
AskUserQuestionPrompter,
PermissionPrompter,
} from "@/agentMode/session/AgentSessionManager";
import type { SessionId } from "@/agentMode/session/types";
/**
* Permission prompts route into the owning session so the user sees an inline
* card in the chat instead of a modal. Plan proposals flow through
* `handlePlanProposalPermission` (which also publishes the plan body); every
* other tool call flows through `handleToolPermission`. Returns `cancelled`
* when no session owns the request — without that the SDK turn would hang.
*/
export function createDefaultPermissionPrompter(
resolveSession: (backendSessionId: SessionId) => AgentSession | null
): PermissionPrompter {
return (req) => {
const session = resolveSession(req.sessionId);
if (!session) return Promise.resolve({ outcome: { outcome: "cancelled" } });
if (req.toolCall.isPlanProposal) {
return session.handlePlanProposalPermission(req);
}
return session.handleToolPermission(req);
};
}
/**
* AskUserQuestion requests route into the owning session so the user answers
* via an inline card in the chat instead of a modal — the sibling of
* `createDefaultPermissionPrompter`. Returns `{}` (the cancellation signal)
* when no session owns the request, so the SDK turn unblocks with the standard
* cancellation deny instead of hanging on a dangling promise.
*/
export function createDefaultAskUserQuestionPrompter(
resolveSession: (backendSessionId: SessionId) => AgentSession | null
): AskUserQuestionPrompter {
return (req) => {
const session = resolveSession(req.sessionId);
if (!session) return Promise.resolve({});
return session.handleAskUserQuestion(req);
};
}