@ilya-lesikov/pi-pi 0.3.0 → 0.4.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/extensions/orchestrator/agents/brainstorm-reviewer.ts +4 -1
- package/extensions/orchestrator/agents/code-reviewer.ts +4 -1
- package/extensions/orchestrator/agents/plan-reviewer.ts +4 -1
- package/extensions/orchestrator/agents/planner.ts +4 -1
- package/extensions/orchestrator/agents/task.ts +4 -2
- package/extensions/orchestrator/command-handlers.ts +1 -1
- package/extensions/orchestrator/event-handlers.ts +7 -4
- package/extensions/orchestrator/orchestrator.ts +3 -3
- package/extensions/orchestrator/phases/brainstorm.ts +18 -12
- package/extensions/orchestrator/phases/implementation.ts +5 -3
- package/extensions/orchestrator/phases/review-task.ts +5 -0
- package/extensions/orchestrator/pp-menu.ts +16 -23
- package/extensions/orchestrator/usage-tracker.ts +31 -4
- package/package.json +1 -1
|
@@ -51,7 +51,10 @@ export function createBrainstormReviewerAgent(
|
|
|
51
51
|
"- SUGGESTIONS: (improvements, not required)",
|
|
52
52
|
"- VERDICT: APPROVE or NEEDS_WORK (with reason)",
|
|
53
53
|
"",
|
|
54
|
-
|
|
54
|
+
"subagent_type is REQUIRED when spawning subagents — calls without it are rejected:",
|
|
55
|
+
'- Agent(subagent_type="Explore", ...) — codebase research. Prefer this for most lookups. Fast and cheap.',
|
|
56
|
+
'- Agent(subagent_type="Librarian", ...) — external docs, library APIs, web research.',
|
|
57
|
+
"Spawn multiple Explore agents in parallel for broad searches.",
|
|
55
58
|
"",
|
|
56
59
|
"# MANDATORY: Write your review to this exact file using the write tool:",
|
|
57
60
|
` ${outputPath}`,
|
|
@@ -65,7 +65,10 @@ export function createCodeReviewerAgent(
|
|
|
65
65
|
"- OPEN QUESTIONS: (low-confidence concerns, speculative follow-ups)",
|
|
66
66
|
"- VERDICT: APPROVE or NEEDS_CHANGES",
|
|
67
67
|
"",
|
|
68
|
-
|
|
68
|
+
"subagent_type is REQUIRED when spawning subagents — calls without it are rejected:",
|
|
69
|
+
'- Agent(subagent_type="Explore", ...) — codebase research. Prefer this for most lookups. Fast and cheap.',
|
|
70
|
+
'- Agent(subagent_type="Librarian", ...) — external docs, library APIs, web research.',
|
|
71
|
+
"Spawn multiple Explore agents in parallel for broad searches.",
|
|
69
72
|
"",
|
|
70
73
|
// --- dynamic suffix ---
|
|
71
74
|
"# MANDATORY: Write your review to this exact file using the write tool:",
|
|
@@ -51,7 +51,10 @@ export function createPlanReviewerAgent(
|
|
|
51
51
|
"- SUGGESTIONS: (improvements, not required)",
|
|
52
52
|
"- VERDICT: APPROVE or REJECT (with reason)",
|
|
53
53
|
"",
|
|
54
|
-
|
|
54
|
+
"subagent_type is REQUIRED when spawning subagents — calls without it are rejected:",
|
|
55
|
+
'- Agent(subagent_type="Explore", ...) — codebase research. Prefer this for most lookups. Fast and cheap.',
|
|
56
|
+
'- Agent(subagent_type="Librarian", ...) — external docs, library APIs, web research.',
|
|
57
|
+
"Spawn multiple Explore agents in parallel for broad searches.",
|
|
55
58
|
"",
|
|
56
59
|
// --- dynamic suffix ---
|
|
57
60
|
"# MANDATORY OUTPUT",
|
|
@@ -40,7 +40,10 @@ export function createPlannerAgent(
|
|
|
40
40
|
"- No other top-level sections allowed",
|
|
41
41
|
"- Describe outcomes, not code-level mechanics",
|
|
42
42
|
"",
|
|
43
|
-
|
|
43
|
+
"subagent_type is REQUIRED when spawning subagents — calls without it are rejected:",
|
|
44
|
+
'- Agent(subagent_type="Explore", ...) — codebase research. Prefer this for most lookups. Fast and cheap.',
|
|
45
|
+
'- Agent(subagent_type="Librarian", ...) — external docs, library APIs, web research.',
|
|
46
|
+
"Spawn multiple Explore agents in parallel for broad searches.",
|
|
44
47
|
"",
|
|
45
48
|
// --- dynamic suffix ---
|
|
46
49
|
"# MANDATORY OUTPUT",
|
|
@@ -28,8 +28,10 @@ export function createTaskAgent(
|
|
|
28
28
|
FAILURE_RECOVERY,
|
|
29
29
|
"",
|
|
30
30
|
"# Constraints",
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
"- Do NOT spawn task subagents (no recursion)",
|
|
32
|
+
"- subagent_type is REQUIRED when spawning subagents — calls without it are rejected:",
|
|
33
|
+
' Agent(subagent_type="Explore", ...) — codebase research. Prefer this for most lookups. Fast and cheap.',
|
|
34
|
+
' Agent(subagent_type="Librarian", ...) — external docs, library APIs, web research.',
|
|
33
35
|
"- Focus only on your subtask — do not modify unrelated code",
|
|
34
36
|
"- Before modifying a function, use lsp findReferences to understand all callers",
|
|
35
37
|
"- After editing files, run lsp diagnostics and fix errors before moving on",
|
|
@@ -109,7 +109,7 @@ export function registerCommandHandlers(orchestrator: Orchestrator): void {
|
|
|
109
109
|
const { showPpMenu } = await import("./pp-menu.js");
|
|
110
110
|
const text = await showPpMenu(orchestrator, ctx, "command");
|
|
111
111
|
if (text) {
|
|
112
|
-
pi.sendUserMessage(`[PI-PI] ${text}
|
|
112
|
+
pi.sendUserMessage(`[PI-PI] ${text}`, { deliverAs: "followUp" });
|
|
113
113
|
}
|
|
114
114
|
},
|
|
115
115
|
});
|
|
@@ -943,7 +943,10 @@ export function registerEventHandlers(orchestrator: Orchestrator): void {
|
|
|
943
943
|
if (event.toolName === "Agent" && orchestrator.active) {
|
|
944
944
|
const input = event.input as Record<string, unknown>;
|
|
945
945
|
const requestedType = ((input.subagent_type as string) || "").toLowerCase();
|
|
946
|
-
|
|
946
|
+
if (!requestedType) {
|
|
947
|
+
return { block: true, reason: "subagent_type is required. Use Explore for codebase research, Librarian for external docs, or Task for implementation subtasks." };
|
|
948
|
+
}
|
|
949
|
+
const isExplore = requestedType === "explore";
|
|
947
950
|
const isLibrarian = requestedType === "librarian";
|
|
948
951
|
|
|
949
952
|
if (isExplore) {
|
|
@@ -1183,7 +1186,7 @@ export function registerEventHandlers(orchestrator: Orchestrator): void {
|
|
|
1183
1186
|
orchestrator.pendingRetryTimer = setTimeout(() => {
|
|
1184
1187
|
orchestrator.pendingRetryTimer = null;
|
|
1185
1188
|
if (orchestrator.activeTaskToken !== taskToken || !orchestrator.active) return;
|
|
1186
|
-
pi.sendUserMessage(`[PI-PI] Previous request failed due to an API error. Continue working on the current phase (${phase})
|
|
1189
|
+
pi.sendUserMessage(`[PI-PI] Previous request failed due to an API error. Continue working on the current phase (${phase}).`, { deliverAs: "followUp" });
|
|
1187
1190
|
}, delay);
|
|
1188
1191
|
} else {
|
|
1189
1192
|
ctx.ui.notify(`API error persisted after 3 retries: ${errorMsg}. Stopping auto-retry.`, "error");
|
|
@@ -1218,7 +1221,7 @@ export function registerEventHandlers(orchestrator: Orchestrator): void {
|
|
|
1218
1221
|
orchestrator.pendingSubagentSpawns = 0;
|
|
1219
1222
|
orchestrator.active.state.step = "synthesize";
|
|
1220
1223
|
saveTask(orchestrator.active.dir, orchestrator.active.state);
|
|
1221
|
-
pi.sendUserMessage("[PI-PI] All planners completed. Read their outputs and synthesize the plan.");
|
|
1224
|
+
pi.sendUserMessage("[PI-PI] All planners completed. Read their outputs and synthesize the plan.", { deliverAs: "followUp" });
|
|
1222
1225
|
}
|
|
1223
1226
|
}
|
|
1224
1227
|
} else if (orchestrator.active.state.step === "await_reviewers" && orchestrator.active.state.reviewCycle) {
|
|
@@ -1249,7 +1252,7 @@ export function registerEventHandlers(orchestrator: Orchestrator): void {
|
|
|
1249
1252
|
{ customType: "pp-review-ready", content: `[PI-PI] Reviewer outputs are ready.\n\n${rendered}`, display: false },
|
|
1250
1253
|
{ deliverAs: "followUp" },
|
|
1251
1254
|
);
|
|
1252
|
-
pi.sendUserMessage("[PI-PI] Review cycle is ready for apply_feedback. Read reviewer outputs and proceed.");
|
|
1255
|
+
pi.sendUserMessage("[PI-PI] Review cycle is ready for apply_feedback. Read reviewer outputs and proceed.", { deliverAs: "followUp" });
|
|
1253
1256
|
}
|
|
1254
1257
|
} else {
|
|
1255
1258
|
clearInterval(orchestrator.awaitPollTimer!);
|
|
@@ -344,7 +344,7 @@ export class Orchestrator {
|
|
|
344
344
|
} else if (isWaitingForPlanners) {
|
|
345
345
|
ctx.ui.notify("Entered plan phase. Waiting for planners to complete before synthesis.", "info");
|
|
346
346
|
} else {
|
|
347
|
-
this.pi.sendUserMessage(`[PI-PI] Entered ${this.active.state.phase} phase. Begin working
|
|
347
|
+
this.pi.sendUserMessage(`[PI-PI] Entered ${this.active.state.phase} phase. Begin working.`, { deliverAs: "followUp" });
|
|
348
348
|
}
|
|
349
349
|
|
|
350
350
|
if (this.active.state.phase === "plan" && this.active.state.step === "await_planners") {
|
|
@@ -484,7 +484,7 @@ export class Orchestrator {
|
|
|
484
484
|
if (this.active?.state.phase === "plan" && this.active.state.step === "await_planners") {
|
|
485
485
|
ctx.ui.notify("Entered plan phase. Waiting for planners to complete before synthesis.", "info");
|
|
486
486
|
} else {
|
|
487
|
-
this.pi.sendUserMessage(`[PI-PI] Entered ${phase} phase. Begin working
|
|
487
|
+
this.pi.sendUserMessage(`[PI-PI] Entered ${phase} phase. Begin working.`, { deliverAs: "followUp" });
|
|
488
488
|
}
|
|
489
489
|
},
|
|
490
490
|
onError: (err) => {
|
|
@@ -503,7 +503,7 @@ export class Orchestrator {
|
|
|
503
503
|
if (this.active?.state.phase === "plan" && this.active.state.step === "await_planners") {
|
|
504
504
|
ctx.ui.notify("Entered plan phase. Waiting for planners to complete before synthesis.", "info");
|
|
505
505
|
} else {
|
|
506
|
-
this.pi.sendUserMessage(`[PI-PI] Entered ${phase} phase. Begin working
|
|
506
|
+
this.pi.sendUserMessage(`[PI-PI] Entered ${phase} phase. Begin working.`, { deliverAs: "followUp" });
|
|
507
507
|
}
|
|
508
508
|
},
|
|
509
509
|
});
|
|
@@ -22,7 +22,11 @@ export function brainstormSystemPrompt(taskType: TaskType, taskDescription: stri
|
|
|
22
22
|
"",
|
|
23
23
|
"# Your job:",
|
|
24
24
|
"1. Clarify the problem with the user if needed",
|
|
25
|
-
|
|
25
|
+
"2. Spawn subagents for research (subagent_type is REQUIRED — calls without it are rejected):",
|
|
26
|
+
' - Agent(subagent_type="Explore", ...) — codebase research. Prefer this for most lookups.',
|
|
27
|
+
' - Agent(subagent_type="Librarian", ...) — external docs, library APIs, web research.',
|
|
28
|
+
' - Agent(subagent_type="Task", ...) — only when you need a subtask that writes files or runs complex multi-step commands.',
|
|
29
|
+
" Explore is fast and cheap. Use it liberally for codebase questions. Spawn multiple in parallel.",
|
|
26
30
|
"3. Use bash to run commands, check logs, reproduce issues",
|
|
27
31
|
"4. Use tools to trace the bug:",
|
|
28
32
|
" - cbm_search/cbm_search_code: find relevant code by concept or text",
|
|
@@ -31,8 +35,6 @@ export function brainstormSystemPrompt(taskType: TaskType, taskDescription: stri
|
|
|
31
35
|
" - lsp diagnostics: find type errors",
|
|
32
36
|
" - cbm_trace: trace call chains to/from suspect functions",
|
|
33
37
|
" - ast_search: find structural patterns (e.g. error handling, goroutines)",
|
|
34
|
-
"",
|
|
35
|
-
"IMPORTANT: Always specify subagent_type. Use Explore for codebase, Librarian for external docs.",
|
|
36
38
|
"",
|
|
37
39
|
"Produce two files:",
|
|
38
40
|
`- ${taskDir}/USER_REQUEST.md — the fix request. MUST follow this exact structure:`,
|
|
@@ -76,8 +78,11 @@ export function brainstormSystemPrompt(taskType: TaskType, taskDescription: stri
|
|
|
76
78
|
"",
|
|
77
79
|
"# How to work:",
|
|
78
80
|
"- Discuss the topic with the user. Ask clarifying questions. Propose approaches. Analyze tradeoffs.",
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
"- Spawn subagents for research (subagent_type is REQUIRED — calls without it are rejected):",
|
|
82
|
+
' Agent(subagent_type="Explore", ...) — codebase research. Prefer this for most lookups. Fast and cheap.',
|
|
83
|
+
' Agent(subagent_type="Librarian", ...) — external docs, library APIs, web research.',
|
|
84
|
+
' Agent(subagent_type="Task", ...) — only when you need a subtask that writes files or runs complex multi-step commands.',
|
|
85
|
+
" Spawn multiple Explore agents in parallel for broad searches.",
|
|
81
86
|
"- Use tools directly for quick lookups (cbm_search, lsp, ast_search, grep, etc.)",
|
|
82
87
|
"- Present findings to the user and discuss them. Don't just dump raw results.",
|
|
83
88
|
"- Do NOT modify project source code.",
|
|
@@ -120,18 +125,19 @@ export function brainstormSystemPrompt(taskType: TaskType, taskDescription: stri
|
|
|
120
125
|
"",
|
|
121
126
|
"# Steps:",
|
|
122
127
|
"1. Clarify requirements with the user if anything is ambiguous",
|
|
123
|
-
|
|
124
|
-
'
|
|
125
|
-
"
|
|
128
|
+
"2. Spawn subagents for research (subagent_type is REQUIRED — calls without it are rejected):",
|
|
129
|
+
' - Agent(subagent_type="Explore", ...) — codebase research. Prefer this for most lookups. Fast and cheap.',
|
|
130
|
+
' - Agent(subagent_type="Librarian", ...) — external docs, library APIs, web research.',
|
|
131
|
+
' - Agent(subagent_type="Task", ...) — only when you need a subtask that writes files or runs complex multi-step commands.',
|
|
132
|
+
" Spawn multiple Explore agents in parallel for broad searches.",
|
|
133
|
+
"3. Use tools to understand code structure:",
|
|
126
134
|
" - cbm_search: natural-language search across all symbols",
|
|
127
135
|
" - cbm_search_code: graph-augmented grep (deduplicates into functions)",
|
|
128
136
|
" - lsp documentSymbol, goToDefinition, findReferences, goToImplementation, hover",
|
|
129
137
|
" - cbm_trace: trace call chains for dependency understanding",
|
|
130
138
|
" - ast_search: find structural patterns across the codebase",
|
|
131
|
-
"
|
|
132
|
-
"
|
|
133
|
-
"",
|
|
134
|
-
"IMPORTANT: Always specify subagent_type. Use Explore for codebase, Librarian for external docs.",
|
|
139
|
+
"4. Ask the user follow-up questions as needed",
|
|
140
|
+
"5. Write findings into RESEARCH.md as results come back — don't wait for all subagents",
|
|
135
141
|
"",
|
|
136
142
|
"Produce two files:",
|
|
137
143
|
`- ${taskDir}/USER_REQUEST.md — MUST follow this exact structure:`,
|
|
@@ -22,9 +22,11 @@ export function implementationSystemPrompt(taskDir: string): string {
|
|
|
22
22
|
" - cbm_trace: trace dependencies across the codebase",
|
|
23
23
|
" - ast_search: find structural patterns (e.g. error handling conventions)",
|
|
24
24
|
"6. After completing changes, run cbm_changes to verify blast radius",
|
|
25
|
-
|
|
26
|
-
'
|
|
27
|
-
'
|
|
25
|
+
"7. Spawn subagents as needed (subagent_type is REQUIRED — calls without it are rejected):",
|
|
26
|
+
' - Agent(subagent_type="Explore", ...) — codebase research. Prefer this for most lookups. Fast and cheap.',
|
|
27
|
+
' - Agent(subagent_type="Librarian", ...) — external docs, library APIs, web research.',
|
|
28
|
+
' - Agent(subagent_type="Task", ...) — parallelizable, self-contained implementation subtasks.',
|
|
29
|
+
" Spawn multiple Explore agents in parallel for broad searches.",
|
|
28
30
|
"",
|
|
29
31
|
"If a fix fails 3 times, STOP and re-plan the approach — do not keep pushing.",
|
|
30
32
|
"",
|
|
@@ -10,6 +10,11 @@ export function reviewSystemPrompt(taskDir: string): string {
|
|
|
10
10
|
"- read, lsp, grep, find for understanding the code",
|
|
11
11
|
"- gh pr view for GitHub PR context if a PR URL is mentioned",
|
|
12
12
|
"",
|
|
13
|
+
"Spawn subagents as needed (subagent_type is REQUIRED — calls without it are rejected):",
|
|
14
|
+
'- Agent(subagent_type="Explore", ...) — codebase research. Prefer this for most lookups. Fast and cheap.',
|
|
15
|
+
'- Agent(subagent_type="Librarian", ...) — external docs, library APIs, web research.',
|
|
16
|
+
"Spawn multiple Explore agents in parallel for broad searches.",
|
|
17
|
+
"",
|
|
13
18
|
"Write your findings:",
|
|
14
19
|
`- ${taskDir}/USER_REQUEST.md — update with a clear problem statement of issues found`,
|
|
15
20
|
`- ${taskDir}/RESEARCH.md — detailed technical analysis`,
|
|
@@ -344,9 +344,9 @@ export async function resumeTask(
|
|
|
344
344
|
if (step === "await_planners" || step === "await_reviewers") {
|
|
345
345
|
ctx.ui.notify(`Resumed task. Awaiting subagents (${step}).`, "info");
|
|
346
346
|
} else if (step === "apply_feedback") {
|
|
347
|
-
pi.sendUserMessage(`[PI-PI] Resumed ${orchestrator.active.state.phase} phase. Read reviewer outputs and apply feedback
|
|
347
|
+
pi.sendUserMessage(`[PI-PI] Resumed ${orchestrator.active.state.phase} phase. Read reviewer outputs and apply feedback.`, { deliverAs: "followUp" });
|
|
348
348
|
} else {
|
|
349
|
-
pi.sendUserMessage(`[PI-PI] Resumed ${orchestrator.active.state.phase} phase. Continue working
|
|
349
|
+
pi.sendUserMessage(`[PI-PI] Resumed ${orchestrator.active.state.phase} phase. Continue working.`, { deliverAs: "followUp" });
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
return { ok: true };
|
|
@@ -591,6 +591,9 @@ function showUsage(ctx: any): void {
|
|
|
591
591
|
getTotalInputTokens(): number; getTotalOutputTokens(): number;
|
|
592
592
|
getTotalCacheReadTokens(): number; getTotalCacheWriteTokens(): number;
|
|
593
593
|
getTotalCost(): number; getCacheHitRate(): number;
|
|
594
|
+
getMainInputTokens(): number; getMainOutputTokens(): number;
|
|
595
|
+
getMainCacheReadTokens(): number; getMainCacheWriteTokens(): number;
|
|
596
|
+
getMainCost(): number;
|
|
594
597
|
getPerModelUsage(): Record<string, { inputTokens: number; outputTokens: number; cacheReadTokens: number; cacheWriteTokens: number; turns: number }>;
|
|
595
598
|
getSubagentList(): Array<{ description: string; agentType: string; modelId: string; inputTokens: number; outputTokens: number; cacheReadTokens: number; cacheWriteTokens: number; cost: number; durationMs: number; toolUses: number }>;
|
|
596
599
|
}
|
|
@@ -601,31 +604,21 @@ function showUsage(ctx: any): void {
|
|
|
601
604
|
return;
|
|
602
605
|
}
|
|
603
606
|
|
|
604
|
-
const
|
|
605
|
-
const
|
|
606
|
-
const
|
|
607
|
-
const
|
|
608
|
-
const mainCost = tracker.getTotalCost();
|
|
609
|
-
const models = tracker.getPerModelUsage();
|
|
610
|
-
const subagents = tracker.getSubagentList();
|
|
611
|
-
|
|
612
|
-
let saInput = 0, saOutput = 0, saCacheRead = 0, saCacheWrite = 0, saCost = 0;
|
|
613
|
-
for (const sa of subagents) {
|
|
614
|
-
saInput += sa.inputTokens;
|
|
615
|
-
saOutput += sa.outputTokens;
|
|
616
|
-
saCacheRead += sa.cacheReadTokens;
|
|
617
|
-
saCacheWrite += sa.cacheWriteTokens;
|
|
618
|
-
saCost += sa.cost;
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
const totalInput = mainInput + saInput;
|
|
622
|
-
const totalOutput = mainOutput + saOutput;
|
|
623
|
-
const totalCacheRead = mainCacheRead + saCacheRead;
|
|
624
|
-
const totalCost = mainCost + saCost;
|
|
607
|
+
const totalInput = tracker.getTotalInputTokens();
|
|
608
|
+
const totalOutput = tracker.getTotalOutputTokens();
|
|
609
|
+
const totalCacheRead = tracker.getTotalCacheReadTokens();
|
|
610
|
+
const totalCost = tracker.getTotalCost();
|
|
625
611
|
const totalCacheRate = (totalCacheRead + totalInput) > 0
|
|
626
612
|
? totalCacheRead / (totalCacheRead + totalInput)
|
|
627
613
|
: 0;
|
|
628
614
|
|
|
615
|
+
const mainInput = tracker.getMainInputTokens();
|
|
616
|
+
const mainOutput = tracker.getMainOutputTokens();
|
|
617
|
+
const mainCacheRead = tracker.getMainCacheReadTokens();
|
|
618
|
+
const mainCost = tracker.getMainCost();
|
|
619
|
+
const models = tracker.getPerModelUsage();
|
|
620
|
+
const subagents = tracker.getSubagentList();
|
|
621
|
+
|
|
629
622
|
const byModel = new Map<string, { input: number; output: number; cacheRead: number; cacheWrite: number; cost: number }>();
|
|
630
623
|
const mainModelEntries = Object.entries(models);
|
|
631
624
|
const mainTotalTokens = mainModelEntries.reduce((s, [, u]) => s + u.inputTokens + u.outputTokens, 0);
|
|
@@ -19,6 +19,11 @@ export interface UsageTracker {
|
|
|
19
19
|
getTotalCacheReadTokens(): number;
|
|
20
20
|
getTotalCacheWriteTokens(): number;
|
|
21
21
|
getTotalCost(): number;
|
|
22
|
+
getMainInputTokens(): number;
|
|
23
|
+
getMainOutputTokens(): number;
|
|
24
|
+
getMainCacheReadTokens(): number;
|
|
25
|
+
getMainCacheWriteTokens(): number;
|
|
26
|
+
getMainCost(): number;
|
|
22
27
|
getCacheHitRate(): number;
|
|
23
28
|
getPerModelUsage(): Record<string, ModelUsage>;
|
|
24
29
|
getSubagentTotals(): { inputTokens: number; outputTokens: number; cost: number };
|
|
@@ -203,11 +208,11 @@ export function createUsageTracker(): UsageTracker {
|
|
|
203
208
|
},
|
|
204
209
|
|
|
205
210
|
getTotalInputTokens(): number {
|
|
206
|
-
return state.totalInputTokens;
|
|
211
|
+
return state.totalInputTokens + state.subagentInputTokens;
|
|
207
212
|
},
|
|
208
213
|
|
|
209
214
|
getTotalOutputTokens(): number {
|
|
210
|
-
return state.totalOutputTokens;
|
|
215
|
+
return state.totalOutputTokens + state.subagentOutputTokens;
|
|
211
216
|
},
|
|
212
217
|
|
|
213
218
|
getTotalCacheReadTokens(): number {
|
|
@@ -219,13 +224,35 @@ export function createUsageTracker(): UsageTracker {
|
|
|
219
224
|
},
|
|
220
225
|
|
|
221
226
|
getTotalCost(): number {
|
|
227
|
+
return state.totalCost + state.subagentCost;
|
|
228
|
+
},
|
|
229
|
+
|
|
230
|
+
getMainInputTokens(): number {
|
|
231
|
+
return state.totalInputTokens;
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
getMainOutputTokens(): number {
|
|
235
|
+
return state.totalOutputTokens;
|
|
236
|
+
},
|
|
237
|
+
|
|
238
|
+
getMainCacheReadTokens(): number {
|
|
239
|
+
return state.totalCacheReadTokens;
|
|
240
|
+
},
|
|
241
|
+
|
|
242
|
+
getMainCacheWriteTokens(): number {
|
|
243
|
+
return state.totalCacheWriteTokens;
|
|
244
|
+
},
|
|
245
|
+
|
|
246
|
+
getMainCost(): number {
|
|
222
247
|
return state.totalCost;
|
|
223
248
|
},
|
|
224
249
|
|
|
225
250
|
getCacheHitRate(): number {
|
|
226
|
-
const
|
|
251
|
+
const totalInput = state.totalInputTokens + state.subagentInputTokens;
|
|
252
|
+
const totalCacheRead = state.totalCacheReadTokens;
|
|
253
|
+
const denominator = totalCacheRead + totalInput;
|
|
227
254
|
if (denominator <= 0) return 0;
|
|
228
|
-
return
|
|
255
|
+
return totalCacheRead / denominator;
|
|
229
256
|
},
|
|
230
257
|
|
|
231
258
|
getPerModelUsage(): Record<string, ModelUsage> {
|