Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion ops/agent-phone.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,12 @@ export function noteSaid(pin, agent, text) {
});
} catch {}
}
/**
* How far back a joined leg reads the room's record as its own memory: long
* enough to rejoin a call it dropped out of, short enough that the last episode
* recorded in the same room is not mistaken for this one.
*/
export const ROOM_MEMORY_MS = 30 * 60_000;
/** Where a joined leg asks the room who is on the line and what was said. */
export function statusUrlFor(base, pin) {
return `${String(base).replace(/\/+$/, '')}/api/v1/agent-queue/rooms/${pin}`;
Expand Down Expand Up @@ -817,7 +823,18 @@ async function main() {
const r = await fetch(process.env.GROUPCALL_STATUS_URL, { headers: roomHeaders }).then((x) => (x.ok ? x.json() : null)).catch(() => null);
const all = await fetch(`${process.env.GROUPCALL_STATUS_URL}/lines?after=0&wait=0`, { headers: roomHeaders }).then((x) => (x.ok ? x.json() : null)).catch(() => null);
afterId = all?.lines?.at(-1)?.id || 0;
if (r) r.history = (all?.lines || r.history || []).slice(-80);
/**
* Recent lines only. The room's record is our memory so that a drop, a crash
* or a deploy picks the conversation up instead of starting over - and a
* redial takes seconds, a restart a minute. But a room keeps its transcript
* between calls, and Off The Record records every episode in the same room:
* unbounded, a new episode opened with eighty lines of the LAST one, so the
* hosts started the show holding things the guest had said weeks earlier.
* That is also the one thing their brief forbids - never say "you mentioned"
* about something that is not in this call.
*/
const since = Date.now() - ROOM_MEMORY_MS;
if (r) r.history = (all?.lines || r.history || []).filter((l) => Number(l?.at) >= since).slice(-80);
for (const l of r?.history || []) {
const at = new Date(l.at).toISOString();
if (l.kind === 'agent' && l.who === agent) transcript.push({ who: agent, text: l.text, at, history: true });
Expand Down
19 changes: 19 additions & 0 deletions test/agent-phone.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,25 @@ test('a joined leg can work out where the room status lives', () => {
assert.equal(worker.statusUrlFor('https://group.call.pit.world/', '8625'), 'https://group.call.pit.world/api/v1/agent-queue/rooms/8625');
});

test("the room's record is memory of this call, not of the last episode", () => {
// A room keeps its transcript between calls and Off The Record records every
// episode in room 8625, so loading the last 80 lines unbounded opened a new
// episode with the previous one in the hosts' heads: "[memory] 80 earlier lines
// loaded" followed by questions about a Bitcoin loss from weeks before. Their
// brief forbids exactly that - never say "you mentioned" about something that
// is not in this call.
const lines = [
{ id: 1, who: 'Anthony', kind: 'person', text: 'from the last episode', at: now - 60 * minute },
{ id: 2, who: 'riotcoder', kind: 'agent', text: 'also last episode', at: now - 31 * minute },
{ id: 3, who: 'Anthony', kind: 'person', text: 'this call, after a drop', at: now - 2 * minute },
];
const since = now - worker.ROOM_MEMORY_MS;
const kept = lines.filter((l) => Number(l.at) >= since).slice(-80);
assert.deepEqual(kept.map((l) => l.id), [3]);
// Long enough to rejoin a call that dropped a few minutes ago.
assert.ok(worker.ROOM_MEMORY_MS >= 10 * minute);
});

test('a model that says PASS is saying nothing, not reading the word out', () => {
assert.deepEqual(worker.parseTurn('SAY: PASS'), { kind: 'pass', text: '' });
assert.deepEqual(worker.parseTurn('PASS'), { kind: 'pass', text: '' });
Expand Down
Loading