Add computer switching, crew reporting, job steps and markdown chat
- Bots have a current computer (bots.computer_id), switched from the chat header beside the model button or by clicking a computer the bot names ([computer:ID]); tasks run on it by default - search_computers runs one read-only command on all of a bot's computers; chat replies know their computers (compose-computers-note) - The coordinator can use every computer and grants or revokes crew access with assign_computer - Delegated jobs record requested_by_bot_id; the worker's result or failure is reported back in the coordinator's conversation - bots_queue_updates records each model turn of a job, pushed live and shown in the working-on panel - Live relay: every process pushes new messages, job steps and bot changes from the database to its own sockets, so work done elsewhere shows live - Bot messages render as markdown (react-markdown + remark-gfm, no raw HTML) with twui components; rail previews are plain text - Fix header button overflow in the model and computer selects - Bump @moduletrace/twui to 0.1.2 Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import type { HarnessCandidate } from "@/src/harness/types";
|
||||
import describeJobStep from "./describe-job-step";
|
||||
|
||||
const candidate = { model: { slug: "deepseek/deepseek-chat:free" } } as HarnessCandidate;
|
||||
|
||||
describe("describeJobStep", () => {
|
||||
test("names each tool once, never its arguments", () => {
|
||||
expect(
|
||||
describeJobStep({
|
||||
index: 2,
|
||||
text: "Let me look.",
|
||||
candidate,
|
||||
tool_calls: [
|
||||
{ id: "a", name: "sandbox_execute_bash", arguments: '{"command":"cat secret"}' },
|
||||
{ id: "b", name: "sandbox_execute_bash", arguments: "{}" },
|
||||
{ id: "c", name: "update_memory", arguments: "{}" },
|
||||
],
|
||||
}),
|
||||
).toEqual({
|
||||
kind: "tool",
|
||||
text: "Using sandbox_execute_bash, update_memory",
|
||||
metadata: {
|
||||
step: 2,
|
||||
model: "deepseek/deepseek-chat:free",
|
||||
tools: ["sandbox_execute_bash", "update_memory"],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test("keeps the first line of a text-only turn, cut to one line", () => {
|
||||
const step = describeJobStep({
|
||||
index: 0,
|
||||
text: `\n ${"a".repeat(250)}\nSecond line`,
|
||||
candidate,
|
||||
tool_calls: [],
|
||||
});
|
||||
|
||||
expect(step?.kind).toBe("note");
|
||||
expect(step?.text).toHaveLength(200);
|
||||
expect(step?.text.endsWith("…")).toBe(true);
|
||||
});
|
||||
|
||||
test("skips an empty turn", () => {
|
||||
expect(describeJobStep({ index: 0, text: " ", candidate, tool_calls: [] })).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user