bermudis-pi-goodies 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/index.ts +3 -0
- package/package.json +1 -1
- package/tps.ts +47 -0
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# bermudis-pi-goodies
|
|
2
2
|
|
|
3
3
|
A bundle of small, frequently-used [Pi](https://github.com/earendil-works/pi)
|
|
4
|
-
extensions. One entry point,
|
|
4
|
+
extensions. One entry point, nine independent features.
|
|
5
5
|
|
|
6
6
|
| Feature | Command / hook | What it does |
|
|
7
7
|
|---------|----------------|--------------|
|
|
@@ -13,13 +13,14 @@ extensions. One entry point, eight independent features.
|
|
|
13
13
|
| `fixed-defaults` | hook + `/fixed-defaults` | Keep the global startup provider, model, and thinking defaults fixed while allowing in-session model changes; `/fixed-defaults set` pins the current model and thinking level. |
|
|
14
14
|
| `kilo` | provider | Access Kilo Gateway models via `/login kilo` or `KILO_API_KEY`. |
|
|
15
15
|
| `provider-balance` | footer (no command) | Show remaining Kilo or OpenRouter credits, z.ai token-plan quota, or OpenAI Codex quota on the right side of the working-directory footer line. |
|
|
16
|
+
| `tps` | hook (no command) | Notify tokens/sec and in/out/cache token usage at the end of each agent turn. |
|
|
16
17
|
|
|
17
18
|
## Install
|
|
18
19
|
|
|
19
20
|
After publishing the package to npm:
|
|
20
21
|
|
|
21
22
|
```bash
|
|
22
|
-
pi install npm:bermudis-pi-goodies@0.
|
|
23
|
+
pi install npm:bermudis-pi-goodies@0.2.0
|
|
23
24
|
```
|
|
24
25
|
|
|
25
26
|
Remove any old `bermudis-pi-goodies.ts` symlink before reloading Pi. Each
|
package/index.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* - fixed-defaults hook + command keep startup defaults stable; /fixed-defaults set pins the current model
|
|
12
12
|
* - kilo provider access Kilo Gateway models
|
|
13
13
|
* - provider-balance footer show Kilo credits or Codex quota in the footer
|
|
14
|
+
* - tps hook notify tokens/sec and usage at each agent turn end
|
|
14
15
|
*/
|
|
15
16
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
16
17
|
import copyWithModel from "./copy-with-model.ts";
|
|
@@ -18,6 +19,7 @@ import fixedDefaults from "./fixed-defaults.ts";
|
|
|
18
19
|
import kilo from "./kilo.ts";
|
|
19
20
|
import modelThinking from "./model-thinking.ts";
|
|
20
21
|
import providerBalance from "./provider-balance.ts";
|
|
22
|
+
import tps from "./tps.ts";
|
|
21
23
|
import nameWithAi from "./name-with-ai.ts";
|
|
22
24
|
import zed from "./zed.ts";
|
|
23
25
|
import preferTools from "./prefer-tools.ts";
|
|
@@ -31,4 +33,5 @@ export default function bermudisPiGoodies(pi: ExtensionAPI): void {
|
|
|
31
33
|
fixedDefaults(pi);
|
|
32
34
|
providerBalance(pi);
|
|
33
35
|
kilo(pi);
|
|
36
|
+
tps(pi);
|
|
34
37
|
}
|
package/package.json
CHANGED
package/tps.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { AssistantMessage } from "@earendil-works/pi-ai";
|
|
2
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
|
|
4
|
+
function isAssistantMessage(message: unknown): message is AssistantMessage {
|
|
5
|
+
if (!message || typeof message !== "object") return false;
|
|
6
|
+
const role = (message as { role?: unknown }).role;
|
|
7
|
+
return role === "assistant";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default function (pi: ExtensionAPI) {
|
|
11
|
+
let agentStartMs: number | null = null;
|
|
12
|
+
|
|
13
|
+
pi.on("agent_start", () => {
|
|
14
|
+
agentStartMs = Date.now();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
pi.on("agent_end", (event, ctx) => {
|
|
18
|
+
if (!ctx.hasUI) return;
|
|
19
|
+
if (agentStartMs === null) return;
|
|
20
|
+
|
|
21
|
+
const elapsedMs = Date.now() - agentStartMs;
|
|
22
|
+
agentStartMs = null;
|
|
23
|
+
if (elapsedMs <= 0) return;
|
|
24
|
+
|
|
25
|
+
let input = 0;
|
|
26
|
+
let output = 0;
|
|
27
|
+
let cacheRead = 0;
|
|
28
|
+
let cacheWrite = 0;
|
|
29
|
+
let totalTokens = 0;
|
|
30
|
+
|
|
31
|
+
for (const message of event.messages) {
|
|
32
|
+
if (!isAssistantMessage(message)) continue;
|
|
33
|
+
input += message.usage.input || 0;
|
|
34
|
+
output += message.usage.output || 0;
|
|
35
|
+
cacheRead += message.usage.cacheRead || 0;
|
|
36
|
+
cacheWrite += message.usage.cacheWrite || 0;
|
|
37
|
+
totalTokens += message.usage.totalTokens || 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (output <= 0) return;
|
|
41
|
+
|
|
42
|
+
const elapsedSeconds = elapsedMs / 1000;
|
|
43
|
+
const tokensPerSecond = output / elapsedSeconds;
|
|
44
|
+
const message = `TPS ${tokensPerSecond.toFixed(1)} tok/s. out ${output.toLocaleString()}, in ${input.toLocaleString()}, cache r/w ${cacheRead.toLocaleString()}/${cacheWrite.toLocaleString()}, total ${totalTokens.toLocaleString()}, ${elapsedSeconds.toFixed(1)}s`;
|
|
45
|
+
ctx.ui.notify(message, "info");
|
|
46
|
+
});
|
|
47
|
+
}
|