Workshop outcome
This commit is contained in:
commit
b9ea424f4e
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
.idea
|
||||
44
.pi/extensions/test-status.ts
Normal file
44
.pi/extensions/test-status.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { isBashToolResult, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
||||
|
||||
export default function testStatusExtension(pi: ExtensionAPI) {
|
||||
// After every tool execution, check if tests just ran
|
||||
pi.on("tool_result", async (event, ctx) => {
|
||||
// Only care about bash commands
|
||||
if (!isBashToolResult(event)) return;
|
||||
|
||||
const command: string = event.input.command;
|
||||
|
||||
// Only care about test commands
|
||||
if (!command.includes("npm test") && !command.includes("vitest") && !command.includes("npx vitest")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const output = event.content[0]?.text ?? "";
|
||||
const theme = ctx.ui.theme;
|
||||
|
||||
// Detect pass/fail from vitest summary output
|
||||
const testsPassed = /Tests\s+.+passed/.test(output) && !/Tests\s+.+failed/.test(output);
|
||||
const testsFailed = /Tests\s+.+failed/.test(output) || event.details?.exitCode !== 0;
|
||||
|
||||
if (testsPassed) {
|
||||
// Extract summary line for inline detail (e.g., "1 passed (242ms)")
|
||||
const summaryLine = output
|
||||
.split("\n")
|
||||
.find((line: string) => /Test Files\s+.+passed/.test(line));
|
||||
const summary = summaryLine?.trim() ?? "All tests passed";
|
||||
|
||||
ctx.ui.setWidget("test-status", [
|
||||
`${theme.fg("success", "●")} ${theme.fg("text", summary)}`,
|
||||
]);
|
||||
} else if (testsFailed) {
|
||||
const summaryLine = output
|
||||
.split("\n")
|
||||
.find((line: string) => /Tests\s+.+failed/.test(line));
|
||||
const summary = summaryLine?.trim() ?? "Tests failed";
|
||||
|
||||
ctx.ui.setWidget("test-status", [
|
||||
`${theme.fg("error", "●")} ${theme.fg("text", summary)}`,
|
||||
]);
|
||||
}
|
||||
});
|
||||
}
|
||||
15
.pi/llm-metrics.log
Normal file
15
.pi/llm-metrics.log
Normal file
@ -0,0 +1,15 @@
|
||||
{"timestamp":"2026-06-20T11:03:05.568Z","provider":"openrouter","model":"deepseek/deepseek-v4-flash","turnCount":1,"inputTokens":1038,"outputTokens":60,"totalTokens":1098,"prefillTokensPerSec":351.03,"generationTokensPerSec":189.87,"combinedTokensPerSec":335.47,"totalDurationMs":3273,"timeToFirstTokenMs":2957,"rawTimestamps":{"ttftMs":2957,"allTtftMs":[2957],"generationDurationMs":316,"turns":[{"turnId":"turn-0","durationMs":3273,"ttftMs":2957}]}}
|
||||
{"timestamp":"2026-06-20T11:08:53.529Z","provider":"openrouter","model":"deepseek/deepseek-v4-flash","turnCount":3,"inputTokens":2915,"outputTokens":510,"totalTokens":3425,"prefillTokensPerSec":887.91,"generationTokensPerSec":56.86,"combinedTokensPerSec":279.52,"totalDurationMs":12253,"timeToFirstTokenMs":3283,"rawTimestamps":{"ttftMs":3283,"allTtftMs":[3283],"generationDurationMs":8970,"turns":[{"turnId":"turn-0","durationMs":3866},{"turnId":"turn-1","durationMs":3909},{"turnId":"turn-2","durationMs":4478,"ttftMs":3283}]}}
|
||||
{"timestamp":"2026-06-20T11:12:12.819Z","provider":"openrouter","model":"deepseek/deepseek-v4-flash","turnCount":3,"inputTokens":21584,"outputTokens":1172,"totalTokens":22756,"prefillTokensPerSec":2383.66,"generationTokensPerSec":77.02,"combinedTokensPerSec":937.58,"totalDurationMs":24271,"timeToFirstTokenMs":9055,"rawTimestamps":{"ttftMs":9055,"allTtftMs":[9055],"generationDurationMs":15216,"turns":[{"turnId":"turn-0","durationMs":3053},{"turnId":"turn-1","durationMs":8673},{"turnId":"turn-2","durationMs":12545,"ttftMs":9055}]}}
|
||||
{"timestamp":"2026-06-20T11:16:46.039Z","provider":"openrouter","model":"deepseek/deepseek-v4-flash","turnCount":2,"inputTokens":20185,"outputTokens":788,"totalTokens":20973,"prefillTokensPerSec":8734.31,"generationTokensPerSec":70.01,"combinedTokensPerSec":1545.88,"totalDurationMs":13567,"timeToFirstTokenMs":2311,"rawTimestamps":{"ttftMs":2311,"allTtftMs":[2311],"generationDurationMs":11256,"turns":[{"turnId":"turn-0","durationMs":9944},{"turnId":"turn-1","durationMs":3623,"ttftMs":2311}]}}
|
||||
{"timestamp":"2026-06-20T11:17:45.757Z","provider":"openrouter","model":"deepseek/deepseek-v4-flash","turnCount":2,"inputTokens":21490,"outputTokens":157,"totalTokens":21647,"prefillTokensPerSec":6002.79,"generationTokensPerSec":20.34,"combinedTokensPerSec":1916,"totalDurationMs":11298,"timeToFirstTokenMs":3580,"rawTimestamps":{"ttftMs":3580,"allTtftMs":[3580],"generationDurationMs":7718,"turns":[{"turnId":"turn-0","durationMs":7166},{"turnId":"turn-1","durationMs":4132,"ttftMs":3580}]}}
|
||||
{"timestamp":"2026-06-20T11:19:06.241Z","provider":"openrouter","model":"deepseek/deepseek-v4-flash","turnCount":2,"inputTokens":10578,"outputTokens":1189,"totalTokens":11767,"prefillTokensPerSec":1126.76,"generationTokensPerSec":106.47,"combinedTokensPerSec":572.46,"totalDurationMs":20555,"timeToFirstTokenMs":9388,"rawTimestamps":{"ttftMs":9388,"allTtftMs":[9388],"generationDurationMs":11167,"turns":[{"turnId":"turn-0","durationMs":6211},{"turnId":"turn-1","durationMs":14344,"ttftMs":9388}]}}
|
||||
{"timestamp":"2026-06-20T11:23:18.506Z","provider":"openrouter","model":"deepseek/deepseek-v4-flash","turnCount":4,"inputTokens":77692,"outputTokens":3607,"totalTokens":81299,"prefillTokensPerSec":21695.62,"generationTokensPerSec":68.5,"combinedTokensPerSec":1445.68,"totalDurationMs":56236,"timeToFirstTokenMs":3581,"rawTimestamps":{"ttftMs":3581,"allTtftMs":[3581,17325,3277],"generationDurationMs":52655,"turns":[{"turnId":"turn-0","durationMs":6524},{"turnId":"turn-1","durationMs":4884,"ttftMs":3581},{"turnId":"turn-2","durationMs":32914,"ttftMs":17325},{"turnId":"turn-3","durationMs":11914,"ttftMs":3277}]}}
|
||||
{"timestamp":"2026-06-20T11:24:47.584Z","provider":"openrouter","model":"deepseek/deepseek-v4-flash","turnCount":1,"inputTokens":38092,"outputTokens":198,"totalTokens":38290,"prefillTokensPerSec":7511.73,"generationTokensPerSec":224.74,"combinedTokensPerSec":6433.13,"totalDurationMs":5952,"timeToFirstTokenMs":5071,"rawTimestamps":{"ttftMs":5071,"allTtftMs":[5071],"generationDurationMs":881,"turns":[{"turnId":"turn-0","durationMs":5952,"ttftMs":5071}]}}
|
||||
{"timestamp":"2026-06-20T11:26:19.496Z","provider":"openrouter","model":"deepseek/deepseek-v4-flash","turnCount":3,"inputTokens":21740,"outputTokens":720,"totalTokens":22460,"prefillTokensPerSec":4758.15,"generationTokensPerSec":34.98,"combinedTokensPerSec":893.01,"totalDurationMs":25151,"timeToFirstTokenMs":4569,"rawTimestamps":{"ttftMs":4569,"allTtftMs":[4569,8170,8094],"generationDurationMs":20582,"turns":[{"turnId":"turn-0","durationMs":5604,"ttftMs":4569},{"turnId":"turn-1","durationMs":9459,"ttftMs":8170},{"turnId":"turn-2","durationMs":10088,"ttftMs":8094}]}}
|
||||
{"timestamp":"2026-06-20T11:28:23.807Z","provider":"openrouter","model":"deepseek/deepseek-v4-flash","turnCount":1,"inputTokens":114,"outputTokens":31,"totalTokens":145,"prefillTokensPerSec":20.5,"generationTokensPerSec":156.57,"combinedTokensPerSec":25.18,"totalDurationMs":5759,"timeToFirstTokenMs":5561,"rawTimestamps":{"ttftMs":5561,"allTtftMs":[5561],"generationDurationMs":198,"turns":[{"turnId":"turn-0","durationMs":5759,"ttftMs":5561}]}}
|
||||
{"timestamp":"2026-06-20T11:29:28.327Z","provider":"openrouter","model":"deepseek/deepseek-v4-flash","turnCount":2,"inputTokens":79835,"outputTokens":216,"totalTokens":80051,"prefillTokensPerSec":15568.45,"generationTokensPerSec":33.59,"combinedTokensPerSec":6926.03,"totalDurationMs":11558,"timeToFirstTokenMs":5128,"rawTimestamps":{"ttftMs":5128,"allTtftMs":[5128],"generationDurationMs":6430,"turns":[{"turnId":"turn-0","durationMs":5985},{"turnId":"turn-1","durationMs":5573,"ttftMs":5128}]}}
|
||||
{"timestamp":"2026-06-20T11:30:00.138Z","provider":"openrouter","model":"deepseek/deepseek-v4-flash","turnCount":4,"inputTokens":4564,"outputTokens":411,"totalTokens":4975,"prefillTokensPerSec":813.4,"generationTokensPerSec":25.37,"combinedTokensPerSec":228.06,"totalDurationMs":21814,"timeToFirstTokenMs":5611,"rawTimestamps":{"ttftMs":5611,"allTtftMs":[5611],"generationDurationMs":16203,"turns":[{"turnId":"turn-0","durationMs":4208},{"turnId":"turn-1","durationMs":3337},{"turnId":"turn-2","durationMs":7936},{"turnId":"turn-3","durationMs":6333,"ttftMs":5611}]}}
|
||||
{"timestamp":"2026-06-20T11:30:48.044Z","provider":"openrouter","model":"deepseek/deepseek-v4-flash","turnCount":3,"inputTokens":4491,"outputTokens":917,"totalTokens":5408,"prefillTokensPerSec":666.62,"generationTokensPerSec":90.94,"combinedTokensPerSec":321.5,"totalDurationMs":16821,"timeToFirstTokenMs":6737,"rawTimestamps":{"ttftMs":6737,"allTtftMs":[6737,2505,3913],"generationDurationMs":10084,"turns":[{"turnId":"turn-0","durationMs":8498,"ttftMs":6737},{"turnId":"turn-1","durationMs":3187,"ttftMs":2505},{"turnId":"turn-2","durationMs":5136,"ttftMs":3913}]}}
|
||||
{"timestamp":"2026-06-20T11:32:53.704Z","provider":"openrouter","model":"deepseek/deepseek-v4-flash","turnCount":2,"inputTokens":2255,"outputTokens":149,"totalTokens":2404,"prefillTokensPerSec":245.64,"generationTokensPerSec":23.34,"combinedTokensPerSec":154.47,"totalDurationMs":15563,"timeToFirstTokenMs":9180,"rawTimestamps":{"ttftMs":9180,"allTtftMs":[9180],"generationDurationMs":6383,"turns":[{"turnId":"turn-0","durationMs":5664},{"turnId":"turn-1","durationMs":9899,"ttftMs":9180}]}}
|
||||
{"timestamp":"2026-06-20T11:33:29.044Z","provider":"openrouter","model":"deepseek/deepseek-v4-flash","turnCount":3,"inputTokens":1321,"outputTokens":305,"totalTokens":1626,"prefillTokensPerSec":215.08,"generationTokensPerSec":15.8,"combinedTokensPerSec":63.91,"totalDurationMs":25441,"timeToFirstTokenMs":6142,"rawTimestamps":{"ttftMs":6142,"allTtftMs":[6142],"generationDurationMs":19299,"turns":[{"turnId":"turn-0","durationMs":11526},{"turnId":"turn-1","durationMs":7061},{"turnId":"turn-2","durationMs":6854,"ttftMs":6142}]}}
|
||||
1639
package-lock.json
generated
Normal file
1639
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
13
package.json
Normal file
13
package.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "red-green-refactor-cycle-socrates-uk",
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.0",
|
||||
"vitest": "^3.0.0"
|
||||
}
|
||||
}
|
||||
8
src/greet.test.ts
Normal file
8
src/greet.test.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { greet } from "./greet.js";
|
||||
|
||||
describe("greet", () => {
|
||||
it("returns a greeting for a given name", () => {
|
||||
expect(greet("World")).toBe("Hello, World!");
|
||||
});
|
||||
});
|
||||
3
src/greet.ts
Normal file
3
src/greet.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export function greet(name: string): string {
|
||||
return `Hello, ${name}!`;
|
||||
}
|
||||
12
tsconfig.json
Normal file
12
tsconfig.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"outDir": "dist"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user