Files
nanoclaw/src/channels/ask-question.ts
Koshkoshinsk d92d75e173 feat(v2/approvals): per-card titles and structured options
Approval cards now carry a required title (Add MCP Request, Install
Packages Request, Rebuild Request, Credentials Request) and structured
options with distinct pre-click label, post-click selectedLabel (e.g.
" Approved" / " Rejected"), and value used for click routing. The
title and normalized options are persisted in pending_questions so the
post-click card edit can render the correct per-type title and selected
label on both chat-sdk channels and Discord interactions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 15:31:44 +00:00

47 lines
1.1 KiB
TypeScript

/**
* Shared ask_question payload schema + normalization.
*
* Producers (host-side approvals, container-side ask_user_question MCP tool)
* emit an `ask_question` payload. Options may be bare strings for ergonomics,
* but are normalized here into a consistent shape before delivery, persistence,
* and rendering.
*/
export interface OptionInput {
label: string;
selectedLabel?: string;
value?: string;
}
export type RawOption = string | OptionInput;
export interface NormalizedOption {
label: string;
selectedLabel: string;
value: string;
}
export function normalizeOption(raw: RawOption): NormalizedOption {
if (typeof raw === 'string') {
return { label: raw, selectedLabel: raw, value: raw };
}
const label = raw.label;
return {
label,
selectedLabel: raw.selectedLabel ?? label,
value: raw.value ?? label,
};
}
export function normalizeOptions(raws: RawOption[]): NormalizedOption[] {
return raws.map(normalizeOption);
}
export interface AskQuestionPayload {
type: 'ask_question';
questionId: string;
title: string;
question: string;
options: NormalizedOption[];
}