pi-subagents-lite 1.4.5 → 1.4.6
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/package.json +1 -1
- package/src/agents/agent-manager.ts +14 -3
- package/src/agents/agent-runner.ts +3 -2
- package/src/agents/usage.ts +7 -0
- package/src/config/config-io.ts +1 -0
- package/src/config/config-store.ts +7 -0
- package/src/config/types.ts +1 -0
- package/src/types.ts +4 -2
- package/src/ui/menu/menu-widget-settings.ts +2 -0
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@ import { randomUUID } from "node:crypto";
|
|
|
8
8
|
import type { AgentSession, ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
9
9
|
import { runAgent } from "./agent-runner.js";
|
|
10
10
|
import { AgentOutputLog } from "./output-file.js";
|
|
11
|
+
import { getStore } from "../shell.js";
|
|
11
12
|
import {
|
|
12
13
|
type AgentRecord,
|
|
13
14
|
type AgentStatus,
|
|
@@ -18,7 +19,7 @@ import {
|
|
|
18
19
|
type ToolActivity,
|
|
19
20
|
} from "../types.js";
|
|
20
21
|
import type { SubagentType } from "./types.js";
|
|
21
|
-
import { addUsage, getLifetimeTotal, getSessionContextPercent, type
|
|
22
|
+
import { addUsage, getLifetimeTotal, getSessionContextPercent, type AgentUsage } from "./usage.js";
|
|
22
23
|
import { errorMessage } from "../utils.js";
|
|
23
24
|
|
|
24
25
|
/** How often to check for expired agent records (milliseconds). */
|
|
@@ -373,7 +374,7 @@ export class AgentManager {
|
|
|
373
374
|
options?: Pick<SpawnOptions, "onToolActivity" | "onAssistantUsage" | "onCompaction">,
|
|
374
375
|
): {
|
|
375
376
|
onToolActivity: (activity: ToolActivity) => void;
|
|
376
|
-
onAssistantUsage: (usage:
|
|
377
|
+
onAssistantUsage: (usage: AgentUsage) => void;
|
|
377
378
|
onCompaction: (info: CompactionInfo) => void;
|
|
378
379
|
} {
|
|
379
380
|
return {
|
|
@@ -382,7 +383,17 @@ export class AgentManager {
|
|
|
382
383
|
options?.onToolActivity?.(activity);
|
|
383
384
|
},
|
|
384
385
|
onAssistantUsage: (usage) => {
|
|
385
|
-
|
|
386
|
+
// vLLM doesn't report cache hits, so usage.input is full prompt_tokens.
|
|
387
|
+
// Estimate new tokens as delta from previous message's input.
|
|
388
|
+
const deltaEnabled = getStore().agent.deltaInputTokens;
|
|
389
|
+
const cacheRead = usage.cacheRead;
|
|
390
|
+
let inputDelta = usage.input;
|
|
391
|
+
if (deltaEnabled && cacheRead === 0 && record.stats.prevInputTokens != null && usage.input > record.stats.prevInputTokens) {
|
|
392
|
+
inputDelta = usage.input - record.stats.prevInputTokens;
|
|
393
|
+
}
|
|
394
|
+
record.stats.prevInputTokens = usage.input;
|
|
395
|
+
|
|
396
|
+
addUsage(record.stats.lifetimeUsage, { ...usage, input: inputDelta });
|
|
386
397
|
options?.onAssistantUsage?.(usage);
|
|
387
398
|
},
|
|
388
399
|
onCompaction: (info) => {
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
} from "@earendil-works/pi-coding-agent";
|
|
21
21
|
import { getAgentConfig, getConfig, getToolNamesForType, resolveVisibleTools } from "./agent-types.js";
|
|
22
22
|
import { extractText } from "../prompt/context.js";
|
|
23
|
-
import type {
|
|
23
|
+
import type { AgentUsage } from "./usage.js";
|
|
24
24
|
import { findModelInRegistry, GIT_EXEC_TIMEOUT_MS } from "../utils.js";
|
|
25
25
|
import { DEFAULT_AGENTS } from "./default-agents.js";
|
|
26
26
|
import { buildAgentPrompt, type PromptExtras } from "../prompt/prompts.js";
|
|
@@ -106,13 +106,14 @@ function forwardAbortSignal(session: AgentSession, signal?: AbortSignal): () =>
|
|
|
106
106
|
* assistant messages at runtime, but this shape isn't reflected in the
|
|
107
107
|
* AgentSessionEvent public types.
|
|
108
108
|
*/
|
|
109
|
-
function usageFromAssistantMessage(msg: Record<string, unknown>):
|
|
109
|
+
function usageFromAssistantMessage(msg: Record<string, unknown>): AgentUsage | undefined {
|
|
110
110
|
const usage = msg.usage as Record<string, unknown> | undefined;
|
|
111
111
|
if (!usage) return undefined;
|
|
112
112
|
return {
|
|
113
113
|
input: (usage.input as number) ?? 0,
|
|
114
114
|
output: (usage.output as number) ?? 0,
|
|
115
115
|
cacheWrite: (usage.cacheWrite as number) ?? 0,
|
|
116
|
+
cacheRead: (usage.cacheRead as number) ?? 0,
|
|
116
117
|
cost: ((usage.cost as Record<string, unknown>)?.total as number) ?? 0,
|
|
117
118
|
};
|
|
118
119
|
}
|
package/src/agents/usage.ts
CHANGED
|
@@ -9,6 +9,13 @@
|
|
|
9
9
|
*/
|
|
10
10
|
export type LifetimeUsage = { input: number; output: number; cacheWrite: number; cost: number };
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* A single per-turn usage event as emitted upstream. Adds `cacheRead`, which
|
|
14
|
+
* LifetimeUsage omits from totals (see issue #38). Used to estimate input
|
|
15
|
+
* deltas for providers like vLLM that don't report cache hits.
|
|
16
|
+
*/
|
|
17
|
+
export type AgentUsage = LifetimeUsage & { cacheRead: number };
|
|
18
|
+
|
|
12
19
|
/** Sum of lifetime usage components (including cost), or 0 if undefined. */
|
|
13
20
|
export function getLifetimeTotal(u?: LifetimeUsage): number {
|
|
14
21
|
return u ? u.input + u.output + u.cacheWrite + u.cost : 0;
|
package/src/config/config-io.ts
CHANGED
|
@@ -74,6 +74,8 @@ export interface ResolvedAgentSettings {
|
|
|
74
74
|
readonly showContext: boolean;
|
|
75
75
|
/** Whether to show elapsed time in widget stats line. */
|
|
76
76
|
readonly showTime: boolean;
|
|
77
|
+
/** Whether to estimate input token delta for vLLM (no cache reporting). */
|
|
78
|
+
readonly deltaInputTokens: boolean;
|
|
77
79
|
/** Buffer size for streaming thinking blocks to output file. 0 = disabled. */
|
|
78
80
|
readonly outputThinkingBufferSize: number;
|
|
79
81
|
}
|
|
@@ -133,6 +135,7 @@ export class ConfigStore {
|
|
|
133
135
|
showOutput: a.showOutput !== false,
|
|
134
136
|
showContext: a.showContext !== false,
|
|
135
137
|
showTime: a.showTime !== false,
|
|
138
|
+
deltaInputTokens: a.deltaInputTokens !== false,
|
|
136
139
|
outputThinkingBufferSize: a.outputThinkingBufferSize ?? 0,
|
|
137
140
|
};
|
|
138
141
|
}
|
|
@@ -265,6 +268,10 @@ export class ConfigStore {
|
|
|
265
268
|
setShowOutput: (enabled: boolean) => this.setAgentVisibility("showOutput", enabled),
|
|
266
269
|
setShowContext: (enabled: boolean) => this.setAgentVisibility("showContext", enabled),
|
|
267
270
|
setShowTime: (enabled: boolean) => this.setAgentVisibility("showTime", enabled),
|
|
271
|
+
setDeltaInputTokens: (enabled: boolean): void => {
|
|
272
|
+
this.config.agent.deltaInputTokens = enabled;
|
|
273
|
+
this.persist();
|
|
274
|
+
},
|
|
268
275
|
setOutputThinkingBufferSize: (size: number): void => {
|
|
269
276
|
this.config.agent.outputThinkingBufferSize = size;
|
|
270
277
|
this.persist();
|
package/src/config/types.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import type { Model } from "@earendil-works/pi-ai";
|
|
6
6
|
import type { AgentSession } from "@earendil-works/pi-coding-agent";
|
|
7
7
|
import type { AgentOutputLog } from "./agents/output-file.js";
|
|
8
|
-
import type { LifetimeUsage } from "./agents/usage.js";
|
|
8
|
+
import type { LifetimeUsage, AgentUsage } from "./agents/usage.js";
|
|
9
9
|
import type { SubagentType, AgentInvocation } from "./agents/types.js";
|
|
10
10
|
|
|
11
11
|
/** Thinking level for agent models. */
|
|
@@ -59,7 +59,7 @@ export interface RunCallbacks {
|
|
|
59
59
|
onTextDelta?: (delta: string, fullText: string) => void;
|
|
60
60
|
onSessionCreated?: (session: AgentSession) => void;
|
|
61
61
|
onTurnEnd?: (turnCount: number) => void;
|
|
62
|
-
onAssistantUsage?: (usage:
|
|
62
|
+
onAssistantUsage?: (usage: AgentUsage) => void;
|
|
63
63
|
onCompaction?: (info: CompactionInfo) => void;
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -156,6 +156,8 @@ export interface AgentAccumulatedStats {
|
|
|
156
156
|
maxTurns?: number;
|
|
157
157
|
/** Number of times this agent's session has compacted. Initialized to 0 at spawn. */
|
|
158
158
|
compactionCount: number;
|
|
159
|
+
/** Previous input token count for delta estimation (vLLM doesn't report cache hits). */
|
|
160
|
+
prevInputTokens?: number;
|
|
159
161
|
/** Last-known context usage percentage (0–100), captured at completion. */
|
|
160
162
|
contextPercent?: number | null;
|
|
161
163
|
}
|
|
@@ -26,6 +26,7 @@ function buildStatConfig(store: ReturnType<typeof getStore>) {
|
|
|
26
26
|
["showTools", { label: "Show tools", get: () => store.agent.showTools, set: (v) => store.mutate.agent.setShowTools(v) }],
|
|
27
27
|
["showTurns", { label: "Show turns", get: () => store.agent.showTurns, set: (v) => store.mutate.agent.setShowTurns(v) }],
|
|
28
28
|
["showInput", { label: "Show input tokens", get: () => store.agent.showInput, set: (v) => store.mutate.agent.setShowInput(v) }],
|
|
29
|
+
["deltaInputTokens", { label: "Delta input tokens", get: () => store.agent.deltaInputTokens, set: (v) => store.mutate.agent.setDeltaInputTokens(v) }],
|
|
29
30
|
["showOutput", { label: "Show output tokens", get: () => store.agent.showOutput, set: (v) => store.mutate.agent.setShowOutput(v) }],
|
|
30
31
|
["showContext", { label: "Show context %", get: () => store.agent.showContext, set: (v) => store.mutate.agent.setShowContext(v) }],
|
|
31
32
|
["showCost", { label: "Show cost", get: () => store.agent.showCost, set: (v) => store.mutate.agent.setShowCost(v) }],
|
|
@@ -66,6 +67,7 @@ export async function showWidgetSettingsMenu(ctx: ExtensionCommandContext): Prom
|
|
|
66
67
|
showTools: "Show tool count (🛠 ) in the widget.",
|
|
67
68
|
showTurns: "Show turn count (⟳ ) in the widget.",
|
|
68
69
|
showInput: "Show input tokens (↑) in the widget.",
|
|
70
|
+
deltaInputTokens: "Estimate input token delta for vLLM (no cache reporting).",
|
|
69
71
|
showOutput: "Show output tokens (↓) in the widget.",
|
|
70
72
|
showContext: "Show context-fill percent (%) in the widget.",
|
|
71
73
|
showCost: "Show dollar cost ($) in the widget.",
|