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,37 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import grabBotHookTools from "./grab-bot-hook-tools";
|
||||
|
||||
const names = (params: Partial<Parameters<typeof grabBotHookTools>[0]>) =>
|
||||
grabBotHookTools({ user_id: 1, bot_id: 2, computers: [], ...params }).map((tool) => tool.name);
|
||||
|
||||
describe("grabBotHookTools", () => {
|
||||
test("a hook call's own run gets no hook tools", () => {
|
||||
expect(names({ hooked: true, session_id: 3, onPropose: () => {} })).toEqual([]);
|
||||
});
|
||||
|
||||
test("a run without a chat to confirm in can't propose", () => {
|
||||
expect(names({ session_id: 3 })).toEqual(["list_hooks", "pause_hook", "delete_hook"]);
|
||||
});
|
||||
|
||||
test("a chat reply can propose", () => {
|
||||
expect(names({ session_id: 3, onPropose: () => {} })).toContain("propose_hook");
|
||||
});
|
||||
|
||||
test("a proposal never takes a signing secret", () => {
|
||||
const propose = grabBotHookTools({
|
||||
user_id: 1,
|
||||
bot_id: 2,
|
||||
computers: [],
|
||||
session_id: 3,
|
||||
onPropose: () => {},
|
||||
}).find((tool) => tool.name == "propose_hook")!;
|
||||
const parsed = propose.schema!.parse({
|
||||
title: "GitHub pushes",
|
||||
instructions: "Summarise each push.",
|
||||
signing_secret: "abcdefgh",
|
||||
reason: "The user asked for push summaries.",
|
||||
});
|
||||
|
||||
expect(parsed).not.toHaveProperty("signing_secret");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user