Files
cobble/src/harness/text/prepare-messages-for-model.test.ts
T
tbenandClaude Opus 5.5 6a2665dae9 Add the harness, envs, per-bot models and chat attachments
- Harness: providers, model catalog synced hourly, automatic free picks,
  cooldowns, tool loop with context trimming, MCP computer tools
- Bots queue runs replies and tasks through the harness; jobs wait
  (attempt refunded) while every model is resting
- Envs: Settings > Environment, scoped general/workspace/computer,
  written to computers and redacted from tool output
- Models: Settings > Models, per-harness provider select defaulting to
  OpenRouter, and a models modal on each bot's chat (the coordinator's
  edits the defaults)
- Chat: thinking row while a reply runs, file attachments (upload,
  paste, drop) that replies read as images, audio and document text
- Fix media uploads failing after a user's first file, and private
  files being served from the public media path

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 03:38:38 +01:00

92 lines
2.9 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import { MediaReadNote } from "@/src/data/harness-prompts";
import type { HarnessMessage } from "../types";
import prepareMessagesForModel from "./prepare-messages-for-model";
const messages: HarnessMessage[] = [
{ role: "system", content: "You are a bot." },
{
role: "user",
content: [
{ type: "text", text: "What's this?" },
{ type: "image", url: "data:image/png;base64,AAAA", name: "a.png" },
{ type: "audio", data: "AAAA", format: "mp3" },
],
},
];
const signal = new AbortController().signal;
describe("prepareMessagesForModel", () => {
test("keeps media the model can take", async () => {
const fitted = await prepareMessagesForModel({
messages,
model: { input_modalities: ["text", "image", "audio"] },
cache: new Map(),
signal,
read_image: async () => {
throw new Error("should not read");
},
});
expect(fitted).toEqual(messages);
});
test("reads media the model can't take, once, and notes it", async () => {
const cache = new Map<string, string>();
let reads = 0;
const run = () =>
prepareMessagesForModel({
messages,
model: { input_modalities: ["text"] },
cache,
signal,
read_image: async () => {
reads++;
return "A red square.";
},
transcribe: async () => "hello there",
});
const fitted = await run();
await run();
expect(reads).toBe(1);
expect(fitted[0]).toEqual({
role: "system",
content: `You are a bot.\n\n${MediaReadNote}`,
});
expect(fitted[1]).toEqual({
role: "user",
content: [
{ type: "text", text: "What's this?" },
{ type: "text", text: `[Image "a.png": A red square.]` },
{ type: "text", text: "[Audio, transcribed: hello there]" },
],
});
});
test("says when a part can't be read instead of failing", async () => {
const fitted = await prepareMessagesForModel({
messages: [messages[1]!],
model: { input_modalities: ["text", "audio"] },
cache: new Map(),
signal,
read_image: async () => {
throw new Error("No media reading model is set up.");
},
});
expect(fitted[0]).toMatchObject({
content: [
{},
{
type: "text",
text: `[Image "a.png": couldn't be read. No media reading model is set up.]`,
},
{ type: "audio" },
],
});
});
});