Skip to content

Commit a78a1cd

Browse files
authored
Merge pull request #85 from httpsphl/feat/tokens-reload
Count the conversation reloaded after a pause apart from a turn's tokens
2 parents d749144 + 673b6c2 commit a78a1cd

22 files changed

Lines changed: 386 additions & 45 deletions

File tree

‎app/src/features/account/TokensByBot.tsx‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import { useEffect, useState } from "react";
66
import { useT } from "../../i18n";
77
import { errorText } from "../../lib/api";
8-
import { tokens, usedTokens } from "../../lib/format";
8+
import { reloadedTokens, tokens, usedTokens } from "../../lib/format";
99
import type { BotTokens } from "../../lib/protocol.gen";
1010
import { useApi } from "../../store/context";
1111
import { Callout } from "../../ui/Callout";
@@ -99,7 +99,7 @@ function Row({ bot, most }: { bot: BotTokens; most: number }) {
9999
/>
100100
</div>
101101
<span className="text-muted text-xs">
102-
{u.detail(bot.turns, tokens(bot.tokens.cacheRead))}
102+
{u.detail(bot.turns, tokens(bot.tokens.cacheRead), reloadedTokens(bot.tokens.reloaded))}
103103
</span>
104104
</div>
105105
</li>
@@ -111,13 +111,16 @@ function Total({ bots }: { bots: BotTokens[] }) {
111111
const used = bots.reduce((sum, bot) => sum + usedTokens(bot.tokens), 0);
112112
const turns = bots.reduce((sum, bot) => sum + bot.turns, 0);
113113
const reread = bots.reduce((sum, bot) => sum + bot.tokens.cacheRead, 0);
114+
const reloaded = bots.reduce((sum, bot) => sum + bot.tokens.reloaded, 0);
114115
return (
115116
<li className="flex flex-col gap-1 border-line border-t pt-3">
116117
<div className="flex items-baseline justify-between gap-3 font-semibold">
117118
<span>{u.total}</span>
118119
<span className="tabular-nums">{tokens(used)}</span>
119120
</div>
120-
<span className="text-muted text-xs">{u.detail(turns, tokens(reread))}</span>
121+
<span className="text-muted text-xs">
122+
{u.detail(turns, tokens(reread), reloadedTokens(reloaded))}
123+
</span>
121124
</li>
122125
);
123126
}

‎app/src/features/account/tokens.test.tsx‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,28 @@ describe("tokens by bot", () => {
4545
expect(dialog.textContent).toContain("All bots9.8k");
4646
});
4747

48+
test("the conversation sent again after a pause counts apart", async () => {
49+
const fake = new FakeBotloft();
50+
const ops = fake.addCrew("Ops");
51+
const scout = fake.addBot(ops.id, "Scout", "Finds sources");
52+
fake.chat.turn(scout.id, null, {
53+
input: 2,
54+
cacheWrite: 72_636,
55+
reloaded: 72_000,
56+
cacheRead: 0,
57+
output: 983,
58+
});
59+
fake.chat.turn(scout.id);
60+
61+
const dialog = await openUsage(fake);
62+
const list = await within(dialog).findByRole("list", { name: "Tokens by bot" });
63+
expect(
64+
within(list)
65+
.getAllByRole("listitem")
66+
.map((row) => row.textContent),
67+
).toEqual(["Scout4.1kWorked 2 times · 24k reread · 72k reloaded"]);
68+
});
69+
4870
test("a period with no work says so", async () => {
4971
const dialog = await openUsage(new FakeBotloft());
5072
expect(await within(dialog).findByText("No bot worked in this period.")).toBeDefined();

‎app/src/features/chat/BotRun.tsx‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import { CircleAlert } from "lucide-react";
66
import { memo, type ReactNode } from "react";
77
import { useT } from "../../i18n";
8-
import { duration, tokens, usedTokens, when } from "../../lib/format";
8+
import { duration, reloadedTokens, tokens, usedTokens, when } from "../../lib/format";
99
import type { Bot, ChatItem, TurnItem } from "../../lib/protocol.gen";
1010
import { useArrival } from "../../ui/motion";
1111
import { BotAvatar, moodOf } from "../bots/BotAvatar";
@@ -33,14 +33,16 @@ function TurnEnd({ turn }: { turn: TurnItem }) {
3333
}
3434
const time = duration(turn.durationMs);
3535
const used = turn.tokens;
36+
const reloaded = used && reloadedTokens(used.reloaded);
3637
const detail = used && {
37-
read: tokens(used.input + used.cacheWrite),
38+
read: tokens(used.input + used.cacheWrite - used.reloaded),
3839
wrote: tokens(used.output),
3940
reread: tokens(used.cacheRead),
41+
reloaded,
4042
};
4143
return (
4244
<p className="text-muted text-xs" title={t.chat.run.took(time, detail)}>
43-
{t.chat.run.done(time, used && tokens(usedTokens(used)))}
45+
{t.chat.run.done(time, used && tokens(usedTokens(used)), reloaded)}
4446
</p>
4547
);
4648
}

‎app/src/features/chat/context.test.tsx‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,38 @@ function open() {
3939
}
4040

4141
describe("conversation space", () => {
42+
test("a turn after a pause tells the conversation it sent again apart", async () => {
43+
const { fake, scout } = await openScout();
44+
act(() => {
45+
// The turn seen in spec 19: almost all of it was the conversation again.
46+
fake.chat.turn(scout.id, null, {
47+
input: 2,
48+
cacheWrite: 72_636,
49+
reloaded: 72_000,
50+
cacheRead: 0,
51+
output: 983,
52+
});
53+
});
54+
const done = screen.getByText("Done in 4.2 s · 1.6k tokens · reloaded the conversation (72k)");
55+
expect(done.title).toBe(
56+
"Took 4.2 s. Read 638 new tokens and wrote 983; reread 0 of the conversation, which weighs much less. It also sent 72k of the conversation again, as the model no longer had it after a pause.",
57+
);
58+
});
59+
60+
test("a little sent again is not worth a mention", async () => {
61+
const { fake, scout } = await openScout();
62+
act(() => {
63+
fake.chat.turn(scout.id, null, {
64+
input: 2,
65+
cacheWrite: 1_400,
66+
reloaded: 300,
67+
cacheRead: 40_000,
68+
output: 100,
69+
});
70+
});
71+
expect(screen.getByText("Done in 4.2 s · 1.2k tokens")).toBeDefined();
72+
});
73+
4274
test("token counts read short", () => {
4375
expect(tokens(850)).toBe("850");
4476
expect(tokens(24_340)).toBe("24.3k");

‎app/src/i18n/en/account.ts‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,16 @@ export const account = {
3030
tokens: {
3131
title: "Tokens by bot",
3232
intro:
33-
"Tokens are the pieces of text a bot reads and writes. The count adds the new text read and the replies written; the conversation reread each time shows apart, as it weighs much less.",
33+
"Tokens are the pieces of text a bot reads and writes. The count adds the new text read and the replies written. The conversation reread each time shows apart, as it weighs much less, and so does the conversation sent again after a pause.",
3434
period: "Period",
3535
periods: { today: "Today", week: "7 days", month: "30 days", all: "All time" },
3636
empty: "No bot worked in this period.",
3737
failed: "Could not load the tokens",
3838
archived: "archived",
39-
detail: (times: number, reread: string) =>
40-
`Worked ${times === 1 ? "once" : `${times} times`} · ${reread} reread`,
39+
detail: (times: number, reread: string, reloaded: string | null) =>
40+
`Worked ${times === 1 ? "once" : `${times} times`} · ${reread} reread${
41+
reloaded === null ? "" : ` · ${reloaded} reloaded`
42+
}`,
4143
total: "All bots",
4244
},
4345
},

‎app/src/i18n/en/chat.ts‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ export interface TurnTokens {
77
read: string;
88
wrote: string;
99
reread: string;
10+
/** The conversation sent again after a pause, if it was worth telling. */
11+
reloaded: string | null;
1012
}
1113

1214
export const chat = {
@@ -54,13 +56,19 @@ export const chat = {
5456
},
5557
run: {
5658
working: "Working",
57-
done: (time: string, tokens: string | null) =>
58-
`Done in ${time}${tokens === null ? "" : ` · ${tokens} tokens`}`,
59+
done: (time: string, tokens: string | null, reloaded: string | null) =>
60+
`Done in ${time}${tokens === null ? "" : ` · ${tokens} tokens`}${
61+
reloaded === null ? "" : ` · reloaded the conversation (${reloaded})`
62+
}`,
5963
took: (time: string, tokens: TurnTokens | null) =>
6064
`Took ${time}${
6165
tokens === null
6266
? ""
63-
: `. Read ${tokens.read} new tokens and wrote ${tokens.wrote}; reread ${tokens.reread} of the conversation, which weighs much less.`
67+
: `. Read ${tokens.read} new tokens and wrote ${tokens.wrote}; reread ${tokens.reread} of the conversation, which weighs much less.${
68+
tokens.reloaded === null
69+
? ""
70+
: ` It also sent ${tokens.reloaded} of the conversation again, as the model no longer had it after a pause.`
71+
}`
6472
}`,
6573
stopped: (reason: string) => `The bot stopped working on this: ${reason}`,
6674
},

‎app/src/i18n/es/account.ts‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,16 @@ export const account: Messages["account"] = {
3030
tokens: {
3131
title: "Tokens por bot",
3232
intro:
33-
"Los tokens son los trozos de texto que un bot lee y escribe. La cuenta suma el texto nuevo leído y las respuestas escritas; la conversación releída cada vez aparece aparte, porque pesa mucho menos.",
33+
"Los tokens son los trozos de texto que un bot lee y escribe. La cuenta suma el texto nuevo leído y las respuestas escritas. La conversación releída cada vez aparece aparte, porque pesa mucho menos, y también la conversación enviada de nuevo tras una pausa.",
3434
period: "Período",
3535
periods: { today: "Hoy", week: "7 días", month: "30 días", all: "Todo" },
3636
empty: "Ningún bot trabajó en este período.",
3737
failed: "No se pudieron cargar los tokens",
3838
archived: "archivado",
39-
detail: (times: number, reread: string) =>
40-
`Trabajó ${times === 1 ? "1 vez" : `${times} veces`} · ${reread} releídos`,
39+
detail: (times: number, reread: string, reloaded: string | null) =>
40+
`Trabajó ${times === 1 ? "1 vez" : `${times} veces`} · ${reread} releídos${
41+
reloaded === null ? "" : ` · ${reloaded} recargados`
42+
}`,
4143
total: "Todos los bots",
4244
},
4345
},

‎app/src/i18n/es/chat.ts‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,19 @@ export const chat: Messages["chat"] = {
4949
},
5050
run: {
5151
working: "Trabajando",
52-
done: (time: string, tokens: string | null) =>
53-
`Terminado en ${time}${tokens === null ? "" : ` · ${tokens} tokens`}`,
52+
done: (time: string, tokens: string | null, reloaded: string | null) =>
53+
`Terminado en ${time}${tokens === null ? "" : ` · ${tokens} tokens`}${
54+
reloaded === null ? "" : ` · recargó la conversación (${reloaded})`
55+
}`,
5456
took: (time: string, tokens: TurnTokens | null) =>
5557
`Tardó ${time}${
5658
tokens === null
5759
? ""
58-
: `. Leyó ${tokens.read} tokens nuevos y escribió ${tokens.wrote}; releyó ${tokens.reread} de la conversación, que pesa mucho menos.`
60+
: `. Leyó ${tokens.read} tokens nuevos y escribió ${tokens.wrote}; releyó ${tokens.reread} de la conversación, que pesa mucho menos.${
61+
tokens.reloaded === null
62+
? ""
63+
: ` También volvió a enviar ${tokens.reloaded} de la conversación, que el modelo ya no tenía tras una pausa.`
64+
}`
5965
}`,
6066
stopped: (reason: string) => `El bot dejó de trabajar en esto: ${reason}`,
6167
},

‎app/src/i18n/pt-BR/account.ts‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,16 @@ export const account: Messages["account"] = {
3030
tokens: {
3131
title: "Tokens por bot",
3232
intro:
33-
"Tokens são os pedaços de texto que um bot lê e escreve. A conta soma o texto novo lido e as respostas escritas; a conversa relida a cada vez aparece à parte, porque pesa bem menos.",
33+
"Tokens são os pedaços de texto que um bot lê e escreve. A conta soma o texto novo lido e as respostas escritas. A conversa relida a cada vez aparece à parte, porque pesa bem menos, e a conversa mandada de novo depois de uma pausa também.",
3434
period: "Período",
3535
periods: { today: "Hoje", week: "7 dias", month: "30 dias", all: "Tudo" },
3636
empty: "Nenhum bot trabalhou nesse período.",
3737
failed: "Não deu para carregar os tokens",
3838
archived: "arquivado",
39-
detail: (times: number, reread: string) =>
40-
`Trabalhou ${times === 1 ? "1 vez" : `${times} vezes`} · ${reread} relidos`,
39+
detail: (times: number, reread: string, reloaded: string | null) =>
40+
`Trabalhou ${times === 1 ? "1 vez" : `${times} vezes`} · ${reread} relidos${
41+
reloaded === null ? "" : ` · ${reloaded} recarregados`
42+
}`,
4143
total: "Todos os bots",
4244
},
4345
},

‎app/src/i18n/pt-BR/chat.ts‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,19 @@ export const chat: Messages["chat"] = {
4949
},
5050
run: {
5151
working: "Trabalhando",
52-
done: (time: string, tokens: string | null) =>
53-
`Concluído em ${time}${tokens === null ? "" : ` · ${tokens} tokens`}`,
52+
done: (time: string, tokens: string | null, reloaded: string | null) =>
53+
`Concluído em ${time}${tokens === null ? "" : ` · ${tokens} tokens`}${
54+
reloaded === null ? "" : ` · recarregou a conversa (${reloaded})`
55+
}`,
5456
took: (time: string, tokens: TurnTokens | null) =>
5557
`Levou ${time}${
5658
tokens === null
5759
? ""
58-
: `. Leu ${tokens.read} tokens novos e escreveu ${tokens.wrote}; releu ${tokens.reread} da conversa, que pesa bem menos.`
60+
: `. Leu ${tokens.read} tokens novos e escreveu ${tokens.wrote}; releu ${tokens.reread} da conversa, que pesa bem menos.${
61+
tokens.reloaded === null
62+
? ""
63+
: ` Também mandou de novo ${tokens.reloaded} da conversa, que o modelo já não tinha depois de uma pausa.`
64+
}`
5965
}`,
6066
stopped: (reason: string) => `O bot parou de trabalhar nisto: ${reason}`,
6167
},

0 commit comments

Comments
 (0)