Let bots manage their hooks, with the user confirming what widens them
Bots get list_hooks, pause_hook and delete_hook, which act directly since they only take away. A new hook, or a new name, brief or filter, or switching a paused one back on, goes through propose_hook: it stores a hook_proposals row and puts a [hook-proposal:ID] card in the reply, which the user it was proposed to confirms or rejects. The card is read from what Confirm saves, with the bot's reason labelled as its own; confirming checks everything again and saves through the Hooks modal's helpers. A new hook's URL is shown on the card once, to the user only, never in the outcome the bot is told. What calls a hook, its computers and its signing are never proposed. Only chat replies propose, and a hook call's own run gets no hook tools, so a caller's payload can't reach them. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
import type { HookProposalAction } from "@/src/dict/bot-hook-dict";
|
||||
import type { HookProposalData } from "@/src/schemas/bot-hook-schema";
|
||||
import type { BotHookWithNames, ExtensionProposalDetail } from "@/src/types";
|
||||
|
||||
type Params = {
|
||||
action: HookProposalAction;
|
||||
data: HookProposalData;
|
||||
/**
|
||||
* The hook it changes, as it is now.
|
||||
*/
|
||||
current?: BotHookWithNames | null;
|
||||
/**
|
||||
* Where a new hook runs: the workspace's name, none for the bot's own
|
||||
* chat.
|
||||
*/
|
||||
workspace_name?: string | null;
|
||||
/**
|
||||
* Computer names by id.
|
||||
*/
|
||||
computers: Map<number, string>;
|
||||
};
|
||||
|
||||
/**
|
||||
* What a hook proposal would save, line by line for its card, read from
|
||||
* the data Confirm saves (never from what the bot said): for a new hook
|
||||
* what calls it, where it runs, on which computer and its whole brief;
|
||||
* for a change each field as it is and as it would be.
|
||||
*/
|
||||
export default function describeHookProposalDetails({
|
||||
action,
|
||||
data,
|
||||
current,
|
||||
workspace_name,
|
||||
computers,
|
||||
}: Params): ExtensionProposalDetail[] {
|
||||
const computer = (id?: number | null) => (id ? `${computers.get(Number(id)) || "Computer"} (#${id})` : "");
|
||||
|
||||
if (action == "create") {
|
||||
const watching = data.source == "browser_notifications";
|
||||
|
||||
return [
|
||||
{ label: "Name", value: data.title || "" },
|
||||
{
|
||||
label: "Called by",
|
||||
value: watching
|
||||
? `Browser notifications on ${computer(data.watch_computer_id)}`
|
||||
: "Anyone with its URL (shown to you once, when you confirm)",
|
||||
},
|
||||
...(watching ? [{ label: "Takes", value: data.watch_filter ? `Only notifications containing "${data.watch_filter}"` : "Every notification" }] : []),
|
||||
{ label: "Runs in", value: workspace_name ? `The workspace ${workspace_name}` : "The bot's own chat with you" },
|
||||
{
|
||||
label: "Runs on",
|
||||
value: computer(data.computer_id || (watching ? data.watch_computer_id : null)) || "The bot's current computer",
|
||||
},
|
||||
{ label: "Brief", value: data.instructions || "", block: true },
|
||||
];
|
||||
}
|
||||
|
||||
const lines: ExtensionProposalDetail[] = [
|
||||
{ label: "Hook", value: `#${current?.id} ${current?.title || ""}`.trim() },
|
||||
];
|
||||
|
||||
if (data.title !== undefined) {
|
||||
lines.push({ label: "Name now", value: current?.title || "" }, { label: "New name", value: data.title });
|
||||
}
|
||||
|
||||
if (data.instructions !== undefined) {
|
||||
lines.push(
|
||||
{ label: "Brief now", value: current?.instructions || "", block: true },
|
||||
{ label: "New brief", value: data.instructions, block: true },
|
||||
);
|
||||
}
|
||||
|
||||
if (data.watch_filter !== undefined) {
|
||||
lines.push(
|
||||
{ label: "Filter now", value: current?.watch_filter || "None: every notification" },
|
||||
{ label: "New filter", value: data.watch_filter || "None: every notification" },
|
||||
);
|
||||
}
|
||||
|
||||
if (data.enabled) lines.push({ label: "Switch on", value: "It's paused now; calls would run again" });
|
||||
|
||||
return lines;
|
||||
}
|
||||
Reference in New Issue
Block a user