Tell every bot its own id, in every run

The bot's id never reached its prompt: `composeBotPrompt` only took its
instructions, the appendix, its memory and its workspace, and
`grabBotPrompt` never passed `bot.id` or `bot.name` on. A bot could only
learn its id by accident, from a tool description that named it, so
"which bot am I" was unanswerable in most contexts.

- Open the prompt with who the bot is (`composeIdentity`): its name,
  whether it's the coordinator or a worker, its role, and its id, said
  to be how tools and refs point back at it. `grabBotPrompt` now passes
  the bot, which covers chat replies, tasks, routines and delegated
  tasks, since both runners build their prompt there.
- Turn the notes' example refs into functions bound to the running bot:
  `chatReplyNote`, `botFilesNote` and `coordinatorReplyNote` take its id,
  so the folder-ref example no longer points at a hardcoded `owner_id: 5`
  (another bot's folder) nor `[bot:3]`. ComputerFilesNote keeps the
  computer it's given.
- Stop `create_task` from hiding the worker's own id in its own chat.

Tests: four new `composeBotPrompt` cases pin the identity block (worker,
coordinator, unnamed, no bot at all), and a new `harness-prompts.test.ts`
checks each note's own-folder and self refs point at exactly the running
bot, for three ids.
This commit is contained in:
2026-10-23 17:40:28 +01:00
parent 0166f31cfc
commit 4261535741
8 changed files with 187 additions and 23 deletions
+57
View File
@@ -0,0 +1,57 @@
import { describe, expect, test } from "bun:test";
import {
botFilesNote,
chatReplyNote,
ComputerFilesNote,
coordinatorReplyNote,
TasksNote,
} from "./harness-prompts";
/**
* Every note a bot reads names it by its own id, so a bot copying an
* example never points at another bot's folder, conversation or task.
*/
const bot_ids = [1, 5, 42] as const;
/**
* The bot ids a note's own-folder examples point at, in order.
*/
function folderOwners(note: string) {
return [...note.matchAll(/\[folder:bot:(\d+):/g)].map((match) => match[1]);
}
describe("harness prompts", () => {
for (const bot_id of bot_ids) {
test(`chat reply note names bot ${bot_id}'s own folder`, () => {
const owners = folderOwners(chatReplyNote({ bot_id }));
expect(owners).toEqual([String(bot_id)]);
});
test(`files note names bot ${bot_id}'s own folder`, () => {
const owners = folderOwners(botFilesNote({ bot_id }));
expect(owners).toEqual([String(bot_id)]);
});
test(`coordinator note names itself as bot ${bot_id}`, () => {
const note = coordinatorReplyNote({ bot_id });
expect(note).toContain(`[bot:${bot_id}]`);
expect(note).not.toContain("[bot:3]");
});
}
test("a note that already names the running bot is unchanged by its id", () => {
expect(botFilesNote({ bot_id: 5 })).toContain("[folder:bot:5:reports]");
});
test("the computer files note keeps naming the computer it was given", () => {
expect(ComputerFilesNote({ computer_id: 8 })).toContain("[folder:computer:8:seo/coderank/raw]");
});
test("notes with nothing bot-specific carry no ref example", () => {
expect(TasksNote).not.toContain("[folder:bot:");
expect(TasksNote).not.toContain("[bot:");
});
});