Show turn summaries only in the transcript, not as inbox reports

This commit is contained in:
Ian Gulliver
2026-10-15 20:01:53 -07:00
parent 4ea79a0c61
commit ccd55afe13
24 changed files with 269 additions and 385 deletions
+1 -57
View File
@@ -72,11 +72,9 @@ type Ctx = {
run: Run | undefined;
root: () => string;
taskId: string | undefined;
lastMessage: HTMLElement | undefined;
held: HTMLElement | undefined;
quiet: boolean;
handoff: { summary: HTMLElement; body: HTMLElement } | undefined;
watchReport: (el: HTMLElement, itemId: string) => void;
};
const taskSource: ChatSource = {
@@ -210,60 +208,17 @@ export function mountChat(root: HTMLElement, src: ChatSource, makeHead: (rerende
const mutations = new MutationObserver(pin);
mutations.observe(transcript, { childList: true, subtree: true, characterData: true });
const visibleReports = new Map<Element, string>();
const acked = new Set<string>();
const ackVisible = () => {
if (document.visibilityState !== "visible") {
return;
}
const ids = [...new Set(visibleReports.values())].filter((id) => !acked.has(id) && state.inbox.some((i) => i.id === id));
if (ids.length === 0) {
return;
}
for (const id of ids) {
acked.add(id);
}
post("/api/inbox/responses", { body: { responses: ids.map((id) => ({ item_id: id, type: "dismiss" as const })) } }).catch((err) => {
for (const id of ids) {
acked.delete(id);
}
console.error("acknowledge reports", err);
});
};
const observer = new IntersectionObserver(
(entries) => {
for (const e of entries) {
const id = (e.target as HTMLElement).dataset["inboxItem"];
if (!id) {
continue;
}
if (e.isIntersecting) {
visibleReports.set(e.target, id);
} else {
visibleReports.delete(e.target);
}
}
ackVisible();
},
{ root: transcript, threshold: 0.5 },
);
const newCtx = (): Ctx => ({
tools: new Map(),
subagents: new Map(),
reviewers: new Set(),
reviewButtons: new Map(),
run: undefined,
lastMessage: undefined,
held: undefined,
quiet: false,
handoff: undefined,
root: src.root,
taskId: src.taskId(),
watchReport: (el, itemId) => {
el.dataset["inboxItem"] = itemId;
observer.observe(el);
},
});
let ctx = newCtx();
let context = new Map<string, Usage>();
@@ -543,8 +498,6 @@ export function mountChat(root: HTMLElement, src: ChatSource, makeHead: (rerende
const renderAll = () => {
stuck = true;
observer.disconnect();
visibleReports.clear();
dropStream();
pending = [];
ctx = newCtx();
@@ -570,9 +523,7 @@ export function mountChat(root: HTMLElement, src: ChatSource, makeHead: (rerende
}),
onEach([src.transcriptTopic], (fresh) => appendEvents(fresh as ByreEvent[])),
onEach([src.streamTopic], (ev) => appendDelta(ev as ByreEvent)),
onEach(["inbox"], ackVisible),
];
document.addEventListener("visibilitychange", ackVisible);
replace(root, h("div", { class: "transcript-view" }, head, transcript, composer));
renderAll();
@@ -580,9 +531,7 @@ export function mountChat(root: HTMLElement, src: ChatSource, makeHead: (rerende
for (const off of offs) {
off();
}
document.removeEventListener("visibilitychange", ackVisible);
headImpl.dispose?.();
observer.disconnect();
resizes.disconnect();
mutations.disconnect();
dropStream();
@@ -963,7 +912,6 @@ function renderEvent(ev: ByreEvent, ctx: Ctx): HTMLElement | null {
switch (ev.kind) {
case "user.message":
ctx.lastMessage = undefined;
ctx.quiet = false;
if (ev.actor === "byre") {
const text = String(p["text"]);
@@ -993,8 +941,7 @@ function renderEvent(ev: ByreEvent, ctx: Ctx): HTMLElement | null {
return null;
}
ctx.quiet = false;
ctx.lastMessage = h("div", { class: "msg agent" }, markdown(String(p["text"]), "text md", md));
return ctx.lastMessage;
return h("div", { class: "msg agent" }, markdown(String(p["text"]), "text md", md));
case "agent.thinking":
return h("details", { class: "thinking" }, h("summary", {}, subagentTag(parentOf(p), ctx), "thinking"), markdown(String(p["text"]), "text md", md));
@@ -1011,9 +958,6 @@ function renderEvent(ev: ByreEvent, ctx: Ctx): HTMLElement | null {
}
case "turn.ended":
if (typeof p["inbox_item_id"] === "string" && p["inbox_item_id"] && ctx.lastMessage) {
ctx.watchReport(ctx.lastMessage, p["inbox_item_id"]);
}
if (p["handoff"] === true) {
return h("div", { class: "note" }, "handoff written; continuing in a new session with a fresh context ", when);
}