@royalcat/opencode-dcp-rc 4.0.0 → 4.0.1

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.
@@ -5,6 +5,7 @@
5
5
  import type { Logger } from "../logger";
6
6
  import type { SessionState, WithParts } from "../state";
7
7
  import { type AggregatedStats } from "../state/persistence";
8
+ import { type CompressionUsageTotals } from "../compress/usage";
8
9
  export interface StatsCommandContext {
9
10
  client: any;
10
11
  state: SessionState;
@@ -12,7 +13,7 @@ export interface StatsCommandContext {
12
13
  sessionId: string;
13
14
  messages: WithParts[];
14
15
  }
15
- export declare function formatStatsMessage(sessionTokens: number, sessionSummaryTokens: number, sessionTools: number, sessionMessages: number, sessionDurationMs: number, allTime: AggregatedStats): string;
16
+ export declare function formatStatsMessage(sessionTokens: number, sessionSummaryTokens: number, sessionTools: number, sessionMessages: number, sessionDurationMs: number, sessionUsage: CompressionUsageTotals, allTime: AggregatedStats): string;
16
17
  export declare function handleStatsCommand(ctx: StatsCommandContext): Promise<void>;
17
18
  export declare function buildStatsReport(state: SessionState, logger: Logger): Promise<{
18
19
  sessionTokens: number;
@@ -20,6 +21,7 @@ export declare function buildStatsReport(state: SessionState, logger: Logger): P
20
21
  sessionTools: number;
21
22
  sessionMessages: number;
22
23
  sessionDurationMs: number;
24
+ sessionCompressionUsage: CompressionUsageTotals;
23
25
  allTime: AggregatedStats;
24
26
  }>;
25
27
  //# sourceMappingURL=stats.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../lib/commands/stats.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAGvD,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAIhF,MAAM,WAAW,mBAAmB;IAChC,MAAM,EAAE,GAAG,CAAA;IACX,KAAK,EAAE,YAAY,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,SAAS,EAAE,CAAA;CACxB;AAED,wBAAgB,kBAAkB,CAC9B,aAAa,EAAE,MAAM,EACrB,oBAAoB,EAAE,MAAM,EAC5B,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,iBAAiB,EAAE,MAAM,EACzB,OAAO,EAAE,eAAe,GACzB,MAAM,CAyBR;AAsCD,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BhF;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM;;;;;;;GAuCzE"}
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../lib/commands/stats.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAGvD,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEhF,OAAO,EAAmC,KAAK,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAGhG,MAAM,WAAW,mBAAmB;IAChC,MAAM,EAAE,GAAG,CAAA;IACX,KAAK,EAAE,YAAY,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,SAAS,EAAE,CAAA;CACxB;AAED,wBAAgB,kBAAkB,CAC9B,aAAa,EAAE,MAAM,EACrB,oBAAoB,EAAE,MAAM,EAC5B,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,iBAAiB,EAAE,MAAM,EACzB,YAAY,EAAE,sBAAsB,EACpC,OAAO,EAAE,eAAe,GACzB,MAAM,CAsCR;AAsCD,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BhF;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM;;;;;;;;GA0CzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"rc.d.ts","sourceRoot":"","sources":["../../../lib/compress/rc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,SAAS,CAAA;AAG/D,OAAO,EAAqD,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AA4BjG,MAAM,WAAW,kBAAkB;IAC/B,GAAG,EAAE,MAAM,EAAE,CAAA;CAChB;AAuBD,UAAU,cAAc;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,cAAc,CAkChF;AAsGD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,WAAW,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAuF9E"}
1
+ {"version":3,"file":"rc.d.ts","sourceRoot":"","sources":["../../../lib/compress/rc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,SAAS,CAAA;AAG/D,OAAO,EAAqD,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAmCjG,MAAM,WAAW,kBAAkB;IAC/B,GAAG,EAAE,MAAM,EAAE,CAAA;CAChB;AAiCD,UAAU,cAAc;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,cAAc,CAkChF;AAsGD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,WAAW,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CA4F9E"}
@@ -3,8 +3,18 @@ import { type IdFormat } from "../message-ids";
3
3
  /**
4
4
  * Marker embedded in the hidden summary prompt so the plugin can recognize its
5
5
  * own transient (`session.generate`) request and strip everything else from it.
6
+ * Requests carry a per-call suffix (`[[DCP-RC-SUMMARY:<callId>]]`) so captured
7
+ * provider usage can be attributed to a specific request.
6
8
  */
7
9
  export declare const RC_SUMMARY_MARKER = "[[DCP-RC-SUMMARY]]";
10
+ /** Prefix shared by the static marker and its per-call variant. */
11
+ export declare const RC_SUMMARY_MARKER_PREFIX = "[[DCP-RC-SUMMARY";
12
+ /** Marker line for a hidden summary request, optionally tagged with a call id. */
13
+ export declare function buildSummaryMarker(callId?: string): string;
14
+ /** True when the text contains a hidden summary marker, with or without a call id. */
15
+ export declare function hasSummaryMarker(text: string): boolean;
16
+ /** Extract the call id from a hidden summary marker, when present. */
17
+ export declare function extractSummaryCallId(text: string): string | undefined;
8
18
  export interface PriorSummary {
9
19
  /** Canonical block reference, e.g. `b2` or `@b2@`. */
10
20
  ref: string;
@@ -37,7 +47,7 @@ export declare function serializeMessageForSummary(message: WithParts, selector:
37
47
  * Build the hidden summarization prompt. The selected segments are embedded
38
48
  * verbatim so the transient request does not depend on any injected metadata.
39
49
  */
40
- export declare function buildSummaryPrompt(selectors: SummarySegment[], idFormat?: IdFormat): string;
50
+ export declare function buildSummaryPrompt(selectors: SummarySegment[], idFormat?: IdFormat, callId?: string): string;
41
51
  /**
42
52
  * Normalize a selector written in either ID format (`m0004` or ``) into the
43
53
  * session's canonical format. Returns null when the selector is malformed.
@@ -1 +1 @@
1
- {"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../../lib/compress/summary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAqD,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEjG;;;GAGG;AACH,eAAO,MAAM,iBAAiB,uBAAuB,CAAA;AAErD,MAAM,WAAW,YAAY;IACzB,sDAAsD;IACtD,GAAG,EAAE,MAAM,CAAA;IACX,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,cAAc;IAC3B,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,SAAS,EAAE,CAAA;IACrB,6DAA6D;IAC7D,cAAc,CAAC,EAAE,YAAY,EAAE,CAAA;CAClC;AAED,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,qBAAqB;IAClC,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,KAAK,EAAE,MAAM,EAAE,CAAA;CAClB;AA+BD;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiDvF;AAWD;;;GAGG;AACH,wBAAgB,kBAAkB,CAC9B,SAAS,EAAE,cAAc,EAAE,EAC3B,QAAQ,GAAE,QAAgB,GAC3B,MAAM,CAiCR;AAOD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAE,QAAgB,GAAG,MAAM,GAAG,IAAI,CAsB9F;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAoBtD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAChC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,GAAE,QAAgB,GAC3B,qBAAqB,CAoDvB"}
1
+ {"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../../lib/compress/summary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAqD,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEjG;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,uBAAuB,CAAA;AACrD,mEAAmE;AACnE,eAAO,MAAM,wBAAwB,qBAAqB,CAAA;AAM1D,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAK1D;AAED,sFAAsF;AACtF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAErE;AAED,MAAM,WAAW,YAAY;IACzB,sDAAsD;IACtD,GAAG,EAAE,MAAM,CAAA;IACX,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,cAAc;IAC3B,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,SAAS,EAAE,CAAA;IACrB,6DAA6D;IAC7D,cAAc,CAAC,EAAE,YAAY,EAAE,CAAA;CAClC;AAED,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,qBAAqB;IAClC,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,KAAK,EAAE,MAAM,EAAE,CAAA;CAClB;AA+BD;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiDvF;AAWD;;;GAGG;AACH,wBAAgB,kBAAkB,CAC9B,SAAS,EAAE,cAAc,EAAE,EAC3B,QAAQ,GAAE,QAAgB,EAC1B,MAAM,CAAC,EAAE,MAAM,GAChB,MAAM,CAiCR;AAOD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAE,QAAgB,GAAG,MAAM,GAAG,IAAI,CAsB9F;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAoBtD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAChC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,GAAE,QAAgB,GAC3B,qBAAqB,CAoDvB"}
@@ -2,6 +2,13 @@ import type { PluginConfig } from "../config";
2
2
  import type { Logger } from "../logger";
3
3
  import type { PromptStore } from "../prompts/store";
4
4
  import type { CompressionBlock, CompressionMode, SessionState, WithParts } from "../state";
5
+ import type { CompressionUsage } from "./usage";
6
+ /** Result of the hidden transient model call (OpenCode V2 `session.generate`). */
7
+ export interface GenerateSummaryResult {
8
+ text: string;
9
+ /** Provider usage when captured, otherwise a local estimate. */
10
+ usage?: CompressionUsage;
11
+ }
5
12
  export interface ToolContext {
6
13
  client: any;
7
14
  state: SessionState;
@@ -12,7 +19,9 @@ export interface ToolContext {
12
19
  generate: (input: {
13
20
  sessionID: string;
14
21
  prompt: string;
15
- }) => Promise<string>;
22
+ /** Per-request id embedded in the prompt marker for usage attribution. */
23
+ callId?: string;
24
+ }) => Promise<GenerateSummaryResult>;
16
25
  }
17
26
  export interface BoundaryReference {
18
27
  kind: "message" | "compressed-block";
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../lib/compress/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAE1F,MAAM,WAAW,WAAW;IACxB,MAAM,EAAE,GAAG,CAAA;IACX,KAAK,EAAE,YAAY,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,YAAY,CAAA;IACpB,OAAO,EAAE,WAAW,CAAA;IACpB,oEAAoE;IACpE,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAC9E;AAED,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,SAAS,GAAG,kBAAkB,CAAA;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,eAAe,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,aAAa;IAC1B,WAAW,EAAE,SAAS,EAAE,CAAA;IACxB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACvC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;CAClD;AAED,MAAM,WAAW,mBAAmB;IAChC,cAAc,EAAE,iBAAiB,CAAA;IACjC,YAAY,EAAE,iBAAiB,CAAA;IAC/B,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,gBAAgB,EAAE,MAAM,EAAE,CAAA;CAC7B;AAED,MAAM,WAAW,wBAAwB;IACrC,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,yBAAyB,EAAE,MAAM,EAAE,CAAA;IACnC,sBAAsB,EAAE,MAAM,EAAE,CAAA;CACnC;AAED,MAAM,WAAW,qBAAqB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,eAAe,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,iBAAiB,EAAE,MAAM,CAAA;IACzB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;CACxB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../lib/compress/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAC1F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,kFAAkF;AAClF,MAAM,WAAW,qBAAqB;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,gEAAgE;IAChE,KAAK,CAAC,EAAE,gBAAgB,CAAA;CAC3B;AAED,MAAM,WAAW,WAAW;IACxB,MAAM,EAAE,GAAG,CAAA;IACX,KAAK,EAAE,YAAY,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,YAAY,CAAA;IACpB,OAAO,EAAE,WAAW,CAAA;IACpB,oEAAoE;IACpE,QAAQ,EAAE,CAAC,KAAK,EAAE;QACd,SAAS,EAAE,MAAM,CAAA;QACjB,MAAM,EAAE,MAAM,CAAA;QACd,0EAA0E;QAC1E,MAAM,CAAC,EAAE,MAAM,CAAA;KAClB,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAA;CACvC;AAED,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,SAAS,GAAG,kBAAkB,CAAA;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,eAAe,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,aAAa;IAC1B,WAAW,EAAE,SAAS,EAAE,CAAA;IACxB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACvC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;CAClD;AAED,MAAM,WAAW,mBAAmB;IAChC,cAAc,EAAE,iBAAiB,CAAA;IACjC,YAAY,EAAE,iBAAiB,CAAA;IAC/B,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,gBAAgB,EAAE,MAAM,EAAE,CAAA;CAC7B;AAED,MAAM,WAAW,wBAAwB;IACrC,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,yBAAyB,EAAE,MAAM,EAAE,CAAA;IACnC,sBAAsB,EAAE,MAAM,EAAE,CAAA;CACnC;AAED,MAAM,WAAW,qBAAqB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,eAAe,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,iBAAiB,EAAE,MAAM,CAAA;IACzB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;CACxB"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Usage accounting for the hidden compression (summary) request.
3
+ *
4
+ * Provider-reported usage is preferred: OpenCode V2 generates the summary
5
+ * through `session.generate`, which does not surface token usage to the
6
+ * caller, so the numbers are captured by wrapping the resolved language
7
+ * model (`ctx.aisdk.hook("language")`) and reading the `finish` usage.
8
+ * When that path is unavailable, local tokenizer estimates are recorded
9
+ * instead so the plugin can still report an approximate cost.
10
+ */
11
+ export type CompressionUsageSource = "provider" | "estimated";
12
+ /** Usage of a single hidden compression request. */
13
+ export interface CompressionUsage {
14
+ inputTokens: number;
15
+ outputTokens: number;
16
+ cacheReadTokens: number;
17
+ cacheWriteTokens: number;
18
+ reasoningTokens: number;
19
+ source: CompressionUsageSource;
20
+ }
21
+ /** Aggregated usage of all hidden compression requests in a session. */
22
+ export interface CompressionUsageTotals {
23
+ calls: number;
24
+ providerCalls: number;
25
+ estimatedCalls: number;
26
+ inputTokens: number;
27
+ outputTokens: number;
28
+ cacheReadTokens: number;
29
+ cacheWriteTokens: number;
30
+ reasoningTokens: number;
31
+ }
32
+ export declare function emptyCompressionUsage(): CompressionUsageTotals;
33
+ /**
34
+ * Normalize AI SDK v3 usage (`{ inputTokens: { total, noCache, cacheRead,
35
+ * cacheWrite }, outputTokens: { total, text, reasoning } }`) into the plugin
36
+ * shape. Returns undefined when there is nothing usable to record.
37
+ */
38
+ export declare function normalizeProviderUsage(raw: unknown): CompressionUsage | undefined;
39
+ /** Local fallback when the provider did not report usage. */
40
+ export declare function estimatedCompressionUsage(inputTokens: number, outputTokens: number): CompressionUsage;
41
+ export declare function addCompressionUsage(totals: CompressionUsageTotals, usage: CompressionUsage): CompressionUsageTotals;
42
+ export declare function addCompressionUsageTotals(totals: CompressionUsageTotals, other: CompressionUsageTotals): CompressionUsageTotals;
43
+ /** Backward-compatible load of persisted totals. */
44
+ export declare function normalizeCompressionUsageTotals(value: unknown): CompressionUsageTotals;
45
+ //# sourceMappingURL=usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../../lib/compress/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG,WAAW,CAAA;AAE7D,oDAAoD;AACpD,MAAM,WAAW,gBAAgB;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,eAAe,EAAE,MAAM,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;IACxB,eAAe,EAAE,MAAM,CAAA;IACvB,MAAM,EAAE,sBAAsB,CAAA;CACjC;AAED,wEAAwE;AACxE,MAAM,WAAW,sBAAsB;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,eAAe,EAAE,MAAM,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;IACxB,eAAe,EAAE,MAAM,CAAA;CAC1B;AAED,wBAAgB,qBAAqB,IAAI,sBAAsB,CAW9D;AASD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,GAAG,SAAS,CA0CjF;AAED,6DAA6D;AAC7D,wBAAgB,yBAAyB,CACrC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACrB,gBAAgB,CASlB;AAED,wBAAgB,mBAAmB,CAC/B,MAAM,EAAE,sBAAsB,EAC9B,KAAK,EAAE,gBAAgB,GACxB,sBAAsB,CAWxB;AAED,wBAAgB,yBAAyB,CACrC,MAAM,EAAE,sBAAsB,EAC9B,KAAK,EAAE,sBAAsB,GAC9B,sBAAsB,CAWxB;AAED,oDAAoD;AACpD,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,sBAAsB,CAetF"}
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import type { CompressionBlock, PrunedMessageEntry, SessionState, SessionStats } from "./types";
7
7
  import type { Logger } from "../logger";
8
+ import { type CompressionUsageTotals } from "../compress/usage";
8
9
  /** Prune state as stored on disk */
9
10
  export interface PersistedPruneMessagesState {
10
11
  byMessageId: Record<string, PrunedMessageEntry>;
@@ -40,6 +41,7 @@ export interface AggregatedStats {
40
41
  totalTools: number;
41
42
  totalMessages: number;
42
43
  sessionCount: number;
44
+ compressionUsage: CompressionUsageTotals;
43
45
  }
44
46
  export declare function loadAllSessionStats(logger: Logger): Promise<AggregatedStats>;
45
47
  //# sourceMappingURL=persistence.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../../lib/state/persistence.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAC/F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAGvC,oCAAoC;AACpC,MAAM,WAAW,2BAA2B;IACxC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;IAC/C,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IAC5C,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,QAAQ,CAAC,EAAE,2BAA2B,CAAA;CACzC;AAED,MAAM,WAAW,eAAe;IAC5B,mBAAmB,EAAE,MAAM,EAAE,CAAA;IAC7B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAA;CACnC;AAED,MAAM,WAAW,qBAAqB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,EAAE,cAAc,CAAA;IACrB,MAAM,EAAE,eAAe,CAAA;IACvB,KAAK,EAAE,YAAY,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;CACtB;AAqCD,wBAAsB,gBAAgB,CAClC,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CA6Bf;AAED,wBAAsB,gBAAgB,CAClC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAwFvC;AA6BD,wBAAsB,qBAAqB,CACvC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAG9B;AAED,wBAAsB,qBAAqB,CACvC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAMf;AAED,MAAM,WAAW,eAAe;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;CACvB;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CA2ClF"}
1
+ {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../../lib/state/persistence.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAC/F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAIH,KAAK,sBAAsB,EAC9B,MAAM,mBAAmB,CAAA;AAG1B,oCAAoC;AACpC,MAAM,WAAW,2BAA2B;IACxC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;IAC/C,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IAC5C,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,QAAQ,CAAC,EAAE,2BAA2B,CAAA;CACzC;AAED,MAAM,WAAW,eAAe;IAC5B,mBAAmB,EAAE,MAAM,EAAE,CAAA;IAC7B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAA;CACnC;AAED,MAAM,WAAW,qBAAqB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,EAAE,cAAc,CAAA;IACrB,MAAM,EAAE,eAAe,CAAA;IACvB,KAAK,EAAE,YAAY,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;CACtB;AAqCD,wBAAsB,gBAAgB,CAClC,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CA6Bf;AAED,wBAAsB,gBAAgB,CAClC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAwFvC;AA8BD,wBAAsB,qBAAqB,CACvC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAG9B;AAED,wBAAsB,qBAAqB,CACvC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAMf;AAED,MAAM,WAAW,eAAe;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,gBAAgB,EAAE,sBAAsB,CAAA;CAC3C;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAmDlF"}
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../lib/state/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAsB,SAAS,EAAE,MAAM,SAAS,CAAA;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAcvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE9C,eAAO,MAAM,YAAY,GACrB,QAAQ,GAAG,EACX,OAAO,YAAY,EACnB,QAAQ,MAAM,EACd,UAAU,SAAS,EAAE,EACrB,mBAAmB,OAAO,KAC3B,OAAO,CAAC,IAAI,CAyCd,CAAA;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,GAAE,QAAgB,GAAG,YAAY,CAsC3E;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CA+B3D;AAED,wBAAsB,wBAAwB,CAC1C,MAAM,EAAE,GAAG,EACX,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,SAAS,EAAE,EACrB,iBAAiB,EAAE,OAAO,GAC3B,OAAO,CAAC,IAAI,CAAC,CAgDf;AAED,wBAAsB,iBAAiB,CACnC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,OAAO,GAC3B,OAAO,CAAC,IAAI,CAAC,CAQf"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../lib/state/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAsB,SAAS,EAAE,MAAM,SAAS,CAAA;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAevC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE9C,eAAO,MAAM,YAAY,GACrB,QAAQ,GAAG,EACX,OAAO,YAAY,EACnB,QAAQ,MAAM,EACd,UAAU,SAAS,EAAE,EACrB,mBAAmB,OAAO,KAC3B,OAAO,CAAC,IAAI,CAyCd,CAAA;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,GAAE,QAAgB,GAAG,YAAY,CAuC3E;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAgC3D;AAED,wBAAsB,wBAAwB,CAC1C,MAAM,EAAE,GAAG,EACX,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,SAAS,EAAE,EACrB,iBAAiB,EAAE,OAAO,GAC3B,OAAO,CAAC,IAAI,CAAC,CAiDf;AAED,wBAAsB,iBAAiB,CACnC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,OAAO,GAC3B,OAAO,CAAC,IAAI,CAAC,CAQf"}
@@ -1,4 +1,5 @@
1
1
  import type { CompressionTimingState } from "../compress/timing";
2
+ import type { CompressionUsageTotals } from "../compress/usage";
2
3
  import type { IdFormat } from "../message-ids";
3
4
  import { Message, Part } from "@opencode-ai/sdk/v2";
4
5
  export interface WithParts {
@@ -18,6 +19,8 @@ export interface ToolParameterEntry {
18
19
  export interface SessionStats {
19
20
  pruneTokenCounter: number;
20
21
  totalPruneTokens: number;
22
+ /** Token usage of the hidden compression (summary) requests. */
23
+ compressionUsage: CompressionUsageTotals;
21
24
  }
22
25
  export interface PrunedMessageEntry {
23
26
  tokenCount: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../lib/state/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../lib/state/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"dialogs.d.ts","sourceRoot":"","sources":["../../../lib/tui/dialogs.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAI/D,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEnD,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAChC,GAAG,EAAE,OAAO,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAClB,OAQA;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACjC,GAAG,EAAE,OAAO,CAAA;IACZ,SAAS,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAA;IAClD,MAAM,EAAE,MAAM,IAAI,CAAA;CACrB,OAgEA;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE,OAwD3F;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE;IAC/B,GAAG,EAAE,OAAO,CAAA;IACZ,UAAU,EAAE,OAAO,CAAA;IACnB,WAAW,EAAE,OAAO,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CACvC,OAkDA"}
1
+ {"version":3,"file":"dialogs.d.ts","sourceRoot":"","sources":["../../../lib/tui/dialogs.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAI/D,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEnD,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAChC,GAAG,EAAE,OAAO,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAClB,OAQA;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACjC,GAAG,EAAE,OAAO,CAAA;IACZ,SAAS,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAA;IAClD,MAAM,EAAE,MAAM,IAAI,CAAA;CACrB,OAgEA;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE,OAgF3F;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE;IAC/B,GAAG,EAAE,OAAO,CAAA;IACZ,UAAU,EAAE,OAAO,CAAA;IACnB,WAAW,EAAE,OAAO,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CACvC,OAkDA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/v2/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAG9C,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAkClC,wBAAsB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,iBAE5E;AAED,wBAAsB,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,OAAO,qCAuW9C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/v2/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAG9C,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAuClC,wBAAsB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,iBAE5E;AAED,wBAAsB,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,OAAO,qCAiZ9C"}
@@ -33,11 +33,31 @@ export declare const rpc: {
33
33
  sessionDurationMs: import("zod").ZodNumber;
34
34
  sessionTools: import("zod").ZodNumber;
35
35
  sessionMessages: import("zod").ZodNumber;
36
+ sessionCompressionUsage: import("zod").ZodObject<{
37
+ calls: import("zod").ZodNumber;
38
+ providerCalls: import("zod").ZodNumber;
39
+ estimatedCalls: import("zod").ZodNumber;
40
+ inputTokens: import("zod").ZodNumber;
41
+ outputTokens: import("zod").ZodNumber;
42
+ cacheReadTokens: import("zod").ZodNumber;
43
+ cacheWriteTokens: import("zod").ZodNumber;
44
+ reasoningTokens: import("zod").ZodNumber;
45
+ }, import("zod/v4/core").$strip>;
36
46
  allTime: import("zod").ZodObject<{
37
47
  totalTokens: import("zod").ZodNumber;
38
48
  totalTools: import("zod").ZodNumber;
39
49
  totalMessages: import("zod").ZodNumber;
40
50
  sessionCount: import("zod").ZodNumber;
51
+ compressionUsage: import("zod").ZodObject<{
52
+ calls: import("zod").ZodNumber;
53
+ providerCalls: import("zod").ZodNumber;
54
+ estimatedCalls: import("zod").ZodNumber;
55
+ inputTokens: import("zod").ZodNumber;
56
+ outputTokens: import("zod").ZodNumber;
57
+ cacheReadTokens: import("zod").ZodNumber;
58
+ cacheWriteTokens: import("zod").ZodNumber;
59
+ reasoningTokens: import("zod").ZodNumber;
60
+ }, import("zod/v4/core").$strip>;
41
61
  }, import("zod/v4/core").$strip>;
42
62
  }, import("zod/v4/core").$strip>;
43
63
  }, import("zod/v4/core").$strip>;
@@ -1 +1 @@
1
- {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../../lib/v2/rpc.ts"],"names":[],"mappings":"AA8BA,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiBN,CAAA"}
1
+ {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../../lib/v2/rpc.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiBN,CAAA"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Captures token usage of the hidden compression (summary) requests.
3
+ *
4
+ * OpenCode V2 `session.generate` returns only the reply text, so provider
5
+ * usage is observed in two complementary ways: wrapping the resolved language
6
+ * model through the `aisdk.language` hook (AI SDK packages) and reading the
7
+ * raw response body through the session `http.response` hook (native
8
+ * `@opencode/ai` packages, whose model never passes through the core AISDK
9
+ * service). The session `generate` hook records a local input estimate as a
10
+ * fallback for runtimes where neither capture path is available. All state is
11
+ * kept in memory and keyed by the per-request call id embedded in the hidden
12
+ * prompt marker.
13
+ */
14
+ import type { Plugin } from "@opencode/plugin";
15
+ import type { Logger } from "../logger";
16
+ import { type CompressionUsage } from "../compress/usage";
17
+ export interface CompressionUsageTracker {
18
+ recordProvider(callId: string, usage: CompressionUsage): void;
19
+ recordEstimatedInput(callId: string, inputTokens: number): void;
20
+ /** Provider usage when captured, otherwise a tokenizer estimate, otherwise undefined. */
21
+ resolve(callId: string, outputText: string): CompressionUsage | undefined;
22
+ discard(callId: string): void;
23
+ }
24
+ export declare function createCompressionUsageTracker(): CompressionUsageTracker;
25
+ /**
26
+ * Best-effort registration of the language-model wrapper. Runtimes without the
27
+ * `aisdk` hook simply rely on the local estimate fallback.
28
+ */
29
+ export declare function installCompressionUsageHook(ctx: Plugin.Context, tracker: CompressionUsageTracker, logger: Logger): Promise<void>;
30
+ /**
31
+ * Parse provider usage from a raw model response body. Handles plain JSON
32
+ * bodies and SSE streams from the common provider protocols (OpenAI
33
+ * responses/chat, Anthropic, Google) by merging every usage-like object.
34
+ */
35
+ export declare function parseProviderUsageFromBody(body: string): CompressionUsage | undefined;
36
+ /**
37
+ * Best-effort capture of provider usage from the raw HTTP response of the
38
+ * hidden summary request. Needed for native `@opencode/ai` provider packages,
39
+ * which bypass the core AISDK service entirely. The hook reads clones of the
40
+ * request/response, so the real traffic is never disturbed, and any failure
41
+ * falls back to the local estimate recorded by the `generate` hook.
42
+ */
43
+ export declare function installHttpUsageHook(ctx: Plugin.Context, tracker: CompressionUsageTracker, logger: Logger): Promise<void>;
44
+ //# sourceMappingURL=usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../../lib/v2/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAGvC,OAAO,EAGH,KAAK,gBAAgB,EACxB,MAAM,mBAAmB,CAAA;AAO1B,MAAM,WAAW,uBAAuB;IACpC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAC7D,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/D,yFAAyF;IACzF,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAAA;IACzE,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAChC;AAED,wBAAgB,6BAA6B,IAAI,uBAAuB,CAsCvE;AAgHD;;;GAGG;AACH,wBAAsB,2BAA2B,CAC7C,GAAG,EAAE,MAAM,CAAC,OAAO,EACnB,OAAO,EAAE,uBAAuB,EAChC,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAyCf;AA6FD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CA8BrF;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACtC,GAAG,EAAE,MAAM,CAAC,OAAO,EACnB,OAAO,EAAE,uBAAuB,EAChC,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CA6Cf"}
@@ -9,6 +9,7 @@ import { sendIgnoredMessage } from "../ui/notification"
9
9
  import { formatTokenCount } from "../ui/utils"
10
10
  import { loadAllSessionStats, type AggregatedStats } from "../state/persistence"
11
11
  import { getCurrentParams } from "../token-utils"
12
+ import { normalizeCompressionUsageTotals, type CompressionUsageTotals } from "../compress/usage"
12
13
  import { getActiveCompressionTargets } from "./compression-targets"
13
14
 
14
15
  export interface StatsCommandContext {
@@ -25,6 +26,7 @@ export function formatStatsMessage(
25
26
  sessionTools: number,
26
27
  sessionMessages: number,
27
28
  sessionDurationMs: number,
29
+ sessionUsage: CompressionUsageTotals,
28
30
  allTime: AggregatedStats,
29
31
  ): string {
30
32
  const lines: string[] = []
@@ -42,6 +44,16 @@ export function formatStatsMessage(
42
44
  lines.push(` Time: ${formatCompressionTime(sessionDurationMs)}`)
43
45
  lines.push(` Messages: ${sessionMessages}`)
44
46
  lines.push(` Tools: ${sessionTools}`)
47
+ lines.push(
48
+ ` Summary requests: ${sessionUsage.calls} (${sessionUsage.providerCalls} provider, ${sessionUsage.estimatedCalls} estimated)`,
49
+ )
50
+ lines.push(
51
+ ` Request in|out: ~${formatTokenCount(sessionUsage.inputTokens)} | ~${formatTokenCount(sessionUsage.outputTokens)}`,
52
+ )
53
+ lines.push(
54
+ ` Request cache: ~${formatTokenCount(sessionUsage.cacheReadTokens)} read | ~${formatTokenCount(sessionUsage.cacheWriteTokens)} write`,
55
+ )
56
+ lines.push(` Request reason: ~${formatTokenCount(sessionUsage.reasoningTokens)}`)
45
57
  lines.push("")
46
58
  lines.push("All-time:")
47
59
  lines.push("─".repeat(60))
@@ -49,6 +61,9 @@ export function formatStatsMessage(
49
61
  lines.push(` Tools pruned: ${allTime.totalTools}`)
50
62
  lines.push(` Messages pruned: ${allTime.totalMessages}`)
51
63
  lines.push(` Sessions: ${allTime.sessionCount}`)
64
+ lines.push(
65
+ ` Summary requests: ${allTime.compressionUsage.calls} (~${formatTokenCount(allTime.compressionUsage.inputTokens)} in | ~${formatTokenCount(allTime.compressionUsage.outputTokens)} out)`,
66
+ )
52
67
 
53
68
  return lines.join("\n")
54
69
  }
@@ -99,6 +114,7 @@ export async function handleStatsCommand(ctx: StatsCommandContext): Promise<void
99
114
  report.sessionTools,
100
115
  report.sessionMessages,
101
116
  report.sessionDurationMs,
117
+ report.sessionCompressionUsage,
102
118
  report.allTime,
103
119
  )
104
120
 
@@ -111,9 +127,11 @@ export async function handleStatsCommand(ctx: StatsCommandContext): Promise<void
111
127
  sessionTools: report.sessionTools,
112
128
  sessionMessages: report.sessionMessages,
113
129
  sessionDurationMs: report.sessionDurationMs,
130
+ sessionCompressionUsage: report.sessionCompressionUsage,
114
131
  allTimeTokens: report.allTime.totalTokens,
115
132
  allTimeTools: report.allTime.totalTools,
116
133
  allTimeMessages: report.allTime.totalMessages,
134
+ allTimeCompressionUsage: report.allTime.compressionUsage,
117
135
  })
118
136
  }
119
137
 
@@ -138,6 +156,8 @@ export async function buildStatsReport(state: SessionState, logger: Logger) {
138
156
  }
139
157
  const sessionTools = prunedToolIds.size
140
158
 
159
+ const sessionCompressionUsage = normalizeCompressionUsageTotals(state.stats.compressionUsage)
160
+
141
161
  let sessionMessages = 0
142
162
  for (const entry of state.prune.messages.byMessageId.values()) {
143
163
  if (entry.activeBlockIds.length > 0) {
@@ -154,6 +174,7 @@ export async function buildStatsReport(state: SessionState, logger: Logger) {
154
174
  sessionTools,
155
175
  sessionMessages,
156
176
  sessionDurationMs,
177
+ sessionCompressionUsage,
157
178
  allTime,
158
179
  }
159
180
  }
@@ -21,6 +21,13 @@ import { countTokens } from "../token-utils"
21
21
  import { saveSessionState } from "../state/persistence"
22
22
  import { rcFormat } from "../prompts/extensions/tool"
23
23
  import { appendProtectedPromptInfo, appendProtectedTools } from "./protected-content"
24
+ import {
25
+ addCompressionUsage,
26
+ addCompressionUsageTotals,
27
+ emptyCompressionUsage,
28
+ estimatedCompressionUsage,
29
+ type CompressionUsageTotals,
30
+ } from "./usage"
24
31
  import {
25
32
  buildSummaryPrompt,
26
33
  parseSummarySections,
@@ -34,6 +41,16 @@ export interface RcCompressToolArgs {
34
41
  ids: string[]
35
42
  }
36
43
 
44
+ let summaryCallCounter = 0
45
+
46
+ /** Unique per hidden summary request so provider usage can be attributed. */
47
+ function nextSummaryCallId(): string {
48
+ summaryCallCounter += 1
49
+ return `c${summaryCallCounter.toString(36)}-${Date.now().toString(36)}-${Math.random()
50
+ .toString(36)
51
+ .slice(2, 8)}`
52
+ }
53
+
37
54
  /**
38
55
  * Compress selections with a hidden, synchronous summary request.
39
56
  *
@@ -244,7 +261,12 @@ export function createRcCompressTool(ctx: ToolContext): ReturnType<typeof tool>
244
261
  priorSummaries: plan.priorSummaries,
245
262
  }))
246
263
 
247
- const text = await generateSummaries(ctx, sessionID, segments)
264
+ const { text, usage } = await generateSummaries(ctx, sessionID, segments)
265
+ ctx.state.stats.compressionUsage = addCompressionUsageTotals(
266
+ ctx.state.stats.compressionUsage,
267
+ usage,
268
+ )
269
+ await saveSessionState(ctx.state, ctx.logger)
248
270
  const accepted = await resolveAcceptedSections(
249
271
  ctx,
250
272
  plans.map((plan) => plan.selector.selector),
@@ -290,9 +312,24 @@ async function generateSummaries(
290
312
  ctx: ToolContext,
291
313
  sessionID: string,
292
314
  segments: SummarySegment[],
293
- ): Promise<string> {
294
- const prompt = buildSummaryPrompt(segments, ctx.state.idFormat)
295
- let text = await ctx.generate({ sessionID, prompt })
315
+ ): Promise<{ text: string; usage: CompressionUsageTotals }> {
316
+ let usage = emptyCompressionUsage()
317
+
318
+ const summarize = async (promptSegments: SummarySegment[]): Promise<string> => {
319
+ const callId = nextSummaryCallId()
320
+ const prompt = buildSummaryPrompt(promptSegments, ctx.state.idFormat, callId)
321
+ const result = await ctx.generate({ sessionID, prompt, callId })
322
+ const text = result.text ?? ""
323
+ // Provider usage is authoritative; fall back to a local estimate when
324
+ // the plugin could not observe the underlying model call.
325
+ usage = addCompressionUsage(
326
+ usage,
327
+ result.usage ?? estimatedCompressionUsage(countTokens(prompt), countTokens(text)),
328
+ )
329
+ return text
330
+ }
331
+
332
+ let text = await summarize(segments)
296
333
 
297
334
  // One retry for sections the model failed to emit.
298
335
  for (let retry = 0; retry < 2; retry++) {
@@ -311,14 +348,13 @@ async function generateSummaries(
311
348
  if (retrySegments.length === 0) {
312
349
  break
313
350
  }
314
- const retryPrompt = buildSummaryPrompt(retrySegments, ctx.state.idFormat)
315
351
  try {
316
- text += "\n\n" + (await ctx.generate({ sessionID, prompt: retryPrompt }))
352
+ text += "\n\n" + (await summarize(retrySegments))
317
353
  } catch {
318
354
  break
319
355
  }
320
356
  }
321
- return text
357
+ return { text, usage }
322
358
  }
323
359
 
324
360
  async function resolveAcceptedSections(
@@ -4,8 +4,34 @@ import { formatBlockRef, formatMessageRef, parseBoundaryId, type IdFormat } from
4
4
  /**
5
5
  * Marker embedded in the hidden summary prompt so the plugin can recognize its
6
6
  * own transient (`session.generate`) request and strip everything else from it.
7
+ * Requests carry a per-call suffix (`[[DCP-RC-SUMMARY:<callId>]]`) so captured
8
+ * provider usage can be attributed to a specific request.
7
9
  */
8
10
  export const RC_SUMMARY_MARKER = "[[DCP-RC-SUMMARY]]"
11
+ /** Prefix shared by the static marker and its per-call variant. */
12
+ export const RC_SUMMARY_MARKER_PREFIX = "[[DCP-RC-SUMMARY"
13
+
14
+ function sanitizeCallId(callId: string): string {
15
+ return callId.replace(/[^A-Za-z0-9_-]/g, "-")
16
+ }
17
+
18
+ /** Marker line for a hidden summary request, optionally tagged with a call id. */
19
+ export function buildSummaryMarker(callId?: string): string {
20
+ if (!callId) {
21
+ return RC_SUMMARY_MARKER
22
+ }
23
+ return `${RC_SUMMARY_MARKER_PREFIX}:${sanitizeCallId(callId)}]]`
24
+ }
25
+
26
+ /** True when the text contains a hidden summary marker, with or without a call id. */
27
+ export function hasSummaryMarker(text: string): boolean {
28
+ return text.includes(RC_SUMMARY_MARKER_PREFIX)
29
+ }
30
+
31
+ /** Extract the call id from a hidden summary marker, when present. */
32
+ export function extractSummaryCallId(text: string): string | undefined {
33
+ return text.match(/\[\[DCP-RC-SUMMARY:([A-Za-z0-9_-]+)\]\]/)?.[1]
34
+ }
9
35
 
10
36
  export interface PriorSummary {
11
37
  /** Canonical block reference, e.g. `b2` or `@b2@`. */
@@ -134,6 +160,7 @@ const SUMMARY_RULES = `RULES
134
160
  export function buildSummaryPrompt(
135
161
  selectors: SummarySegment[],
136
162
  idFormat: IdFormat = "xml",
163
+ callId?: string,
137
164
  ): string {
138
165
  const selectorList = selectors.map((segment) => segment.selector)
139
166
  const example = selectorList[0] ?? (idFormat === "compact" ? "" : "m0004")
@@ -152,7 +179,7 @@ export function buildSummaryPrompt(
152
179
  })
153
180
  .join("\n\n")
154
181
 
155
- return `${RC_SUMMARY_MARKER}
182
+ return `${buildSummaryMarker(callId)}
156
183
 
157
184
  You generate compressed-context entries for a coding session. Summarize ONLY the conversation segments listed below. Do not summarize anything else and do not ask questions.
158
185
 
@@ -2,6 +2,14 @@ import type { PluginConfig } from "../config"
2
2
  import type { Logger } from "../logger"
3
3
  import type { PromptStore } from "../prompts/store"
4
4
  import type { CompressionBlock, CompressionMode, SessionState, WithParts } from "../state"
5
+ import type { CompressionUsage } from "./usage"
6
+
7
+ /** Result of the hidden transient model call (OpenCode V2 `session.generate`). */
8
+ export interface GenerateSummaryResult {
9
+ text: string
10
+ /** Provider usage when captured, otherwise a local estimate. */
11
+ usage?: CompressionUsage
12
+ }
5
13
 
6
14
  export interface ToolContext {
7
15
  client: any
@@ -10,7 +18,12 @@ export interface ToolContext {
10
18
  config: PluginConfig
11
19
  prompts: PromptStore
12
20
  /** Hidden transient model call (OpenCode V2 `session.generate`). */
13
- generate: (input: { sessionID: string; prompt: string }) => Promise<string>
21
+ generate: (input: {
22
+ sessionID: string
23
+ prompt: string
24
+ /** Per-request id embedded in the prompt marker for usage attribution. */
25
+ callId?: string
26
+ }) => Promise<GenerateSummaryResult>
14
27
  }
15
28
 
16
29
  export interface BoundaryReference {