@chenlongapps/opencode-token-usage 0.3.3 → 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/README.md +22 -1
- package/README.zh-CN.md +22 -1
- package/ROADMAP.md +9 -7
- package/dist/context-rpc.d.ts +52 -0
- package/dist/context-rpc.js +35 -0
- package/dist/context-sources.d.ts +22 -0
- package/dist/context-sources.js +108 -0
- package/dist/controller.d.ts +11 -3
- package/dist/controller.js +18 -4
- package/dist/index.js +23 -1
- package/dist/pricing.d.ts +57 -1
- package/dist/pricing.js +75 -3
- package/dist/source.d.ts +3 -1
- package/dist/source.js +8 -0
- package/dist/tui.js +620 -13
- package/dist/usage.d.ts +32 -0
- package/dist/usage.js +110 -25
- package/docs/pricing.md +17 -5
- package/docs/verification.md +48 -0
- package/package.json +1 -1
package/dist/pricing.js
CHANGED
|
@@ -2,7 +2,7 @@ export const OFFICIAL_PRICE_SNAPSHOT = {
|
|
|
2
2
|
verified: "2026-09-23",
|
|
3
3
|
newModelCutoff: "2026-03-22",
|
|
4
4
|
entries: [
|
|
5
|
-
// OpenAI
|
|
5
|
+
// OpenAI API rates. Tier sizes are exclusive thresholds, so
|
|
6
6
|
// 272,000 implements the official ">272K input tokens" boundary.
|
|
7
7
|
{
|
|
8
8
|
id: "gpt-5.5", released: "2026-04-23", source: "https://developers.openai.com/api/docs/pricing",
|
|
@@ -11,6 +11,14 @@ export const OFFICIAL_PRICE_SNAPSHOT = {
|
|
|
11
11
|
{ tier: { type: "context", size: 272_000 }, input: 10, output: 45, cache: { read: 1 } },
|
|
12
12
|
],
|
|
13
13
|
},
|
|
14
|
+
{
|
|
15
|
+
id: "gpt-5.5-fast", providers: ["openai"], released: "2026-04-23", source: "https://developers.openai.com/api/docs/pricing",
|
|
16
|
+
prices: [
|
|
17
|
+
{ input: 12.5, output: 75, cache: { read: 1.25 } },
|
|
18
|
+
// OpenAI publishes no Fast rate for GPT-5.5 above 272K input tokens.
|
|
19
|
+
{ tier: { type: "context", size: 272_000 } },
|
|
20
|
+
],
|
|
21
|
+
},
|
|
14
22
|
{
|
|
15
23
|
id: "gpt-5.5-pro", released: "2026-04-23", source: "https://developers.openai.com/api/docs/pricing",
|
|
16
24
|
prices: [
|
|
@@ -60,6 +68,50 @@ export const OFFICIAL_PRICE_SNAPSHOT = {
|
|
|
60
68
|
{ tier: { type: "context", size: 272_000 }, input: 0.2, output: 0.75, cache: { read: 0.02, write: 0.25 } },
|
|
61
69
|
],
|
|
62
70
|
},
|
|
71
|
+
{
|
|
72
|
+
// OpenAI Fast processing is a separate exact ID and restricted to the
|
|
73
|
+
// first-party provider so ordinary or gateway model IDs keep standard rates.
|
|
74
|
+
id: "gpt-6-luna-fast", providers: ["openai"], released: "2026-09-22", source: "https://developers.openai.com/api/docs/pricing",
|
|
75
|
+
prices: [
|
|
76
|
+
{ input: 0.2, output: 1, cache: { read: 0.02, write: 0.25 } },
|
|
77
|
+
{ tier: { type: "context", size: 272_000 }, input: 0.4, output: 1.5, cache: { read: 0.04, write: 0.5 } },
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: "gpt-5.6-sol-fast", providers: ["openai"], released: "2026-07-09", source: "https://developers.openai.com/api/docs/pricing",
|
|
82
|
+
prices: [
|
|
83
|
+
{ input: 8, output: 40, cache: { read: 0.8, write: 10 } },
|
|
84
|
+
{ tier: { type: "context", size: 272_000 }, input: 16, output: 60, cache: { read: 1.6, write: 20 } },
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: "gpt-5.6-terra-fast", providers: ["openai"], released: "2026-07-09", source: "https://developers.openai.com/api/docs/pricing",
|
|
89
|
+
prices: [
|
|
90
|
+
{ input: 4, output: 24, cache: { read: 0.4, write: 5 } },
|
|
91
|
+
{ tier: { type: "context", size: 272_000 }, input: 8, output: 36, cache: { read: 0.8, write: 10 } },
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "gpt-5.6-luna-fast", providers: ["openai"], released: "2026-07-09", source: "https://developers.openai.com/api/docs/pricing",
|
|
96
|
+
prices: [
|
|
97
|
+
{ input: 0.4, output: 2.4, cache: { read: 0.04, write: 0.5 } },
|
|
98
|
+
{ tier: { type: "context", size: 272_000 }, input: 0.8, output: 3.6, cache: { read: 0.08, write: 1 } },
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: "gpt-6-astra-fast", providers: ["openai"], released: "2026-09-04", source: "https://developers.openai.com/api/docs/pricing",
|
|
103
|
+
prices: [
|
|
104
|
+
{ input: 20, output: 100, cache: { read: 2, write: 25 } },
|
|
105
|
+
{ tier: { type: "context", size: 272_000 }, input: 40, output: 150, cache: { read: 4, write: 50 } },
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: "gpt-6-sol-fast", providers: ["openai"], released: "2026-09-22", source: "https://developers.openai.com/api/docs/pricing",
|
|
110
|
+
prices: [
|
|
111
|
+
{ input: 4, output: 20, cache: { read: 0.4, write: 5 } },
|
|
112
|
+
{ tier: { type: "context", size: 272_000 }, input: 8, output: 30, cache: { read: 0.8, write: 10 } },
|
|
113
|
+
],
|
|
114
|
+
},
|
|
63
115
|
// The official ChatGPT SKU `chat-latest`. OpenRouter serves it under the
|
|
64
116
|
// slug `openai/gpt-chat-latest`, which is registered as an exact alias.
|
|
65
117
|
{
|
|
@@ -89,6 +141,20 @@ export const OFFICIAL_PRICE_SNAPSHOT = {
|
|
|
89
141
|
id: "claude-opus-5", released: "2026-07-24", source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
90
142
|
prices: [{ input: 5, output: 25, cache: { read: 0.5, write: 6.25 } }],
|
|
91
143
|
},
|
|
144
|
+
{
|
|
145
|
+
// Fast mode is first-party Claude API only. Cache multipliers apply to
|
|
146
|
+
// the Fast input price; aggregate cache writes use the 5-minute rate.
|
|
147
|
+
id: "claude-opus-5-fast", providers: ["anthropic"], released: "2026-07-24", source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
148
|
+
prices: [{ input: 10, output: 50, cache: { read: 1, write: 12.5 } }],
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: "claude-opus-4-8-fast", providers: ["anthropic"], released: "2026-05-28", source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
152
|
+
prices: [{ input: 10, output: 50, cache: { read: 1, write: 12.5 } }],
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
id: "claude-opus-5-5-fast", providers: ["anthropic"], released: "2026-09-22", source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
156
|
+
prices: [{ input: 8, output: 40, cache: { read: 0.4, write: 10 } }],
|
|
157
|
+
},
|
|
92
158
|
{
|
|
93
159
|
id: "claude-fable-5-1", aliases: ["claude-fable-5.1"], released: "2026-09-01",
|
|
94
160
|
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
@@ -502,8 +568,14 @@ export function officialPrice(model) {
|
|
|
502
568
|
const dot = id.lastIndexOf(".");
|
|
503
569
|
if (dot >= 0)
|
|
504
570
|
candidates.push(id.slice(dot + 1));
|
|
505
|
-
|
|
571
|
+
const available = (candidate) => {
|
|
506
572
|
const entry = index.get(candidate);
|
|
573
|
+
return entry && (!entry.providers || entry.providers.some(provider => provider.toLowerCase() === model.providerID.toLowerCase()))
|
|
574
|
+
? entry
|
|
575
|
+
: undefined;
|
|
576
|
+
};
|
|
577
|
+
for (const candidate of candidates) {
|
|
578
|
+
const entry = available(candidate);
|
|
507
579
|
if (entry)
|
|
508
580
|
return entry;
|
|
509
581
|
}
|
|
@@ -511,7 +583,7 @@ export function officialPrice(model) {
|
|
|
511
583
|
for (const suffix of ["-free", ":free"]) {
|
|
512
584
|
if (!candidate.endsWith(suffix))
|
|
513
585
|
continue;
|
|
514
|
-
const entry =
|
|
586
|
+
const entry = available(candidate.slice(0, -suffix.length));
|
|
515
587
|
if (entry)
|
|
516
588
|
return entry;
|
|
517
589
|
}
|
package/dist/source.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { OpenCodeClient, SessionInfo } from "@opencode/client";
|
|
2
|
+
import type { ContextSources } from "./context-sources.js";
|
|
2
3
|
import type { PriceCatalog, UsageMessage } from "./usage.js";
|
|
3
|
-
export type Session = Pick<SessionInfo, "id" | "parentID" | "fork" | "model" | "location">;
|
|
4
|
+
export type Session = Pick<SessionInfo, "id" | "parentID" | "fork" | "model" | "location" | "title">;
|
|
4
5
|
export interface Page<T> {
|
|
5
6
|
data: T[];
|
|
6
7
|
cursor: {
|
|
@@ -19,6 +20,7 @@ export interface UsageSource {
|
|
|
19
20
|
children(id: string, cursor: string | undefined, signal: AbortSignal): Promise<Page<Session>>;
|
|
20
21
|
messages(id: string, cursor: string | undefined, signal: AbortSignal): Promise<Page<UsageMessage>>;
|
|
21
22
|
model(session: Session, signal: AbortSignal): Promise<ActiveModel>;
|
|
23
|
+
composition?(session: Session, signal: AbortSignal): Promise<ContextSources | undefined>;
|
|
22
24
|
}
|
|
23
25
|
export declare function createSource(client: OpenCodeClient): UsageSource;
|
|
24
26
|
export declare function pages<T>(read: (cursor?: string) => Promise<Page<T>>, signal: AbortSignal): Promise<T[]>;
|
package/dist/source.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ContextSourceRpc } from "./context-rpc.js";
|
|
2
|
+
import { parseContextSources } from "./context-sources.js";
|
|
1
3
|
import { modelKey } from "./usage.js";
|
|
2
4
|
export function createSource(client) {
|
|
3
5
|
return {
|
|
@@ -21,6 +23,12 @@ export function createSource(client) {
|
|
|
21
23
|
context: model?.limit?.context,
|
|
22
24
|
};
|
|
23
25
|
},
|
|
26
|
+
async composition(session, signal) {
|
|
27
|
+
const response = await client.rpc(ContextSourceRpc).latest({ sessionID: session.id }, { location: session.location, signal });
|
|
28
|
+
if (!response || typeof response !== "object" || !("estimate" in response))
|
|
29
|
+
return undefined;
|
|
30
|
+
return parseContextSources(response.estimate);
|
|
31
|
+
},
|
|
24
32
|
};
|
|
25
33
|
}
|
|
26
34
|
export async function pages(read, signal) {
|