opencode-top 3.1.1 → 3.2.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.
Files changed (103) hide show
  1. package/bin/octop.js +2 -9
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +22432 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/cli.mjs +22570 -0
  7. package/dist/core/agents.d.ts +11 -0
  8. package/dist/core/agents.d.ts.map +1 -0
  9. package/dist/core/agents.js +58 -0
  10. package/dist/core/agents.js.map +1 -0
  11. package/dist/core/session.d.ts +19 -0
  12. package/dist/core/session.d.ts.map +1 -0
  13. package/dist/core/session.js +261 -0
  14. package/dist/core/session.js.map +1 -0
  15. package/dist/core/types.d.ts +140 -0
  16. package/dist/core/types.d.ts.map +1 -0
  17. package/dist/core/types.js +29 -0
  18. package/dist/core/types.js.map +1 -0
  19. package/dist/data/pricing.d.ts +4 -0
  20. package/dist/data/pricing.d.ts.map +1 -0
  21. package/dist/data/pricing.js +76 -0
  22. package/dist/data/pricing.js.map +1 -0
  23. package/dist/data/sqlite.d.ts +5 -0
  24. package/dist/data/sqlite.d.ts.map +1 -0
  25. package/dist/data/sqlite.js +222 -0
  26. package/dist/data/sqlite.js.map +1 -0
  27. package/dist/index.d.ts +7 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/{src/index.ts → dist/index.js} +1 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/ui/App.d.ts +6 -0
  32. package/dist/ui/App.d.ts.map +1 -0
  33. package/dist/ui/App.js +101 -0
  34. package/dist/ui/App.js.map +1 -0
  35. package/dist/ui/components/AgentChainGraph.d.ts +9 -0
  36. package/dist/ui/components/AgentChainGraph.d.ts.map +1 -0
  37. package/dist/ui/components/AgentChainGraph.js +41 -0
  38. package/dist/ui/components/AgentChainGraph.js.map +1 -0
  39. package/dist/ui/components/AgentTree.d.ts +13 -0
  40. package/dist/ui/components/AgentTree.d.ts.map +1 -0
  41. package/dist/ui/components/AgentTree.js +50 -0
  42. package/dist/ui/components/AgentTree.js.map +1 -0
  43. package/dist/ui/components/DetailsPanel.d.ts +9 -0
  44. package/dist/ui/components/DetailsPanel.d.ts.map +1 -0
  45. package/dist/ui/components/DetailsPanel.js +82 -0
  46. package/dist/ui/components/DetailsPanel.js.map +1 -0
  47. package/dist/ui/components/MessagesPanel.d.ts +12 -0
  48. package/dist/ui/components/MessagesPanel.d.ts.map +1 -0
  49. package/dist/ui/components/MessagesPanel.js +107 -0
  50. package/dist/ui/components/MessagesPanel.js.map +1 -0
  51. package/dist/ui/components/SparkLine.d.ts +10 -0
  52. package/dist/ui/components/SparkLine.d.ts.map +1 -0
  53. package/dist/ui/components/SparkLine.js +12 -0
  54. package/dist/ui/components/SparkLine.js.map +1 -0
  55. package/dist/ui/components/StatusBar.d.ts +9 -0
  56. package/dist/ui/components/StatusBar.d.ts.map +1 -0
  57. package/dist/ui/components/StatusBar.js +9 -0
  58. package/dist/ui/components/StatusBar.js.map +1 -0
  59. package/dist/ui/components/TabBar.d.ts +10 -0
  60. package/dist/ui/components/TabBar.d.ts.map +1 -0
  61. package/dist/ui/components/TabBar.js +17 -0
  62. package/dist/ui/components/TabBar.js.map +1 -0
  63. package/dist/ui/screens/OverviewScreen.d.ts +12 -0
  64. package/dist/ui/screens/OverviewScreen.d.ts.map +1 -0
  65. package/dist/ui/screens/OverviewScreen.js +94 -0
  66. package/dist/ui/screens/OverviewScreen.js.map +1 -0
  67. package/dist/ui/screens/SessionsScreen.d.ts +12 -0
  68. package/dist/ui/screens/SessionsScreen.d.ts.map +1 -0
  69. package/dist/ui/screens/SessionsScreen.js +98 -0
  70. package/dist/ui/screens/SessionsScreen.js.map +1 -0
  71. package/dist/ui/screens/TimelineScreen.d.ts +11 -0
  72. package/dist/ui/screens/TimelineScreen.d.ts.map +1 -0
  73. package/dist/ui/screens/TimelineScreen.js +128 -0
  74. package/dist/ui/screens/TimelineScreen.js.map +1 -0
  75. package/dist/ui/screens/ToolsScreen.d.ts +12 -0
  76. package/dist/ui/screens/ToolsScreen.d.ts.map +1 -0
  77. package/dist/ui/screens/ToolsScreen.js +113 -0
  78. package/dist/ui/screens/ToolsScreen.js.map +1 -0
  79. package/dist/ui/theme.d.ts +21 -0
  80. package/dist/ui/theme.d.ts.map +1 -0
  81. package/dist/ui/theme.js +21 -0
  82. package/dist/ui/theme.js.map +1 -0
  83. package/package.json +2 -1
  84. package/bin/octop.mjs +0 -13
  85. package/src/cli.ts +0 -60
  86. package/src/core/agents.ts +0 -78
  87. package/src/core/session.ts +0 -315
  88. package/src/core/types.ts +0 -156
  89. package/src/data/pricing.ts +0 -82
  90. package/src/data/sqlite.ts +0 -347
  91. package/src/ui/App.tsx +0 -141
  92. package/src/ui/components/AgentChainGraph.tsx +0 -95
  93. package/src/ui/components/AgentTree.tsx +0 -101
  94. package/src/ui/components/DetailsPanel.tsx +0 -211
  95. package/src/ui/components/MessagesPanel.tsx +0 -323
  96. package/src/ui/components/SparkLine.tsx +0 -18
  97. package/src/ui/components/StatusBar.tsx +0 -24
  98. package/src/ui/components/TabBar.tsx +0 -42
  99. package/src/ui/screens/OverviewScreen.tsx +0 -327
  100. package/src/ui/screens/SessionsScreen.tsx +0 -168
  101. package/src/ui/screens/TimelineScreen.tsx +0 -222
  102. package/src/ui/screens/ToolsScreen.tsx +0 -260
  103. package/src/ui/theme.ts +0 -21
@@ -1,315 +0,0 @@
1
- import Decimal from "decimal.js";
2
- import { TokenUsage } from "./types";
3
- import type { Session, Workflow, ToolUsage, ModelPricing, OverviewStats } from "./types";
4
- import type { MessagePart } from "./types";
5
-
6
- export function getSessionTokens(session: Session): TokenUsage {
7
- return session.interactions.reduce((acc, i) => acc.add(i.tokens), new TokenUsage());
8
- }
9
-
10
- export function getSessionCost(session: Session, pricing: Map<string, ModelPricing>): Decimal {
11
- return session.interactions.reduce((acc, i) => {
12
- const p = pricing.get(i.modelId);
13
- if (!p) return acc;
14
- return acc.plus(i.tokens.calculateCost(p));
15
- }, new Decimal(0));
16
- }
17
-
18
- export function getSessionCostSingle(session: Session, pricing: ModelPricing): Decimal {
19
- return session.interactions.reduce((acc, i) => {
20
- return acc.plus(i.tokens.calculateCost(pricing));
21
- }, new Decimal(0));
22
- }
23
-
24
- export function getSessionDuration(session: Session): number {
25
- const interactions = session.interactions;
26
- if (interactions.length === 0) return 0;
27
-
28
- // Use real time.completed when available
29
- const times: number[] = [];
30
- for (const i of interactions) {
31
- if (i.time.created !== null) times.push(i.time.created);
32
- if (i.time.completed !== null) times.push(i.time.completed);
33
- }
34
-
35
- if (times.length === 0) return 0;
36
- return Math.max(...times) - Math.min(...times);
37
- }
38
-
39
- export function getWorkflowTokens(workflow: Workflow): TokenUsage {
40
- const main = getSessionTokens(workflow.mainSession);
41
- const subs = workflow.subAgentSessions.reduce(
42
- (acc, s) => acc.add(getSessionTokens(s)),
43
- new TokenUsage()
44
- );
45
- return main.add(subs);
46
- }
47
-
48
- export function getWorkflowCost(workflow: Workflow, pricing: Map<string, ModelPricing>): Decimal {
49
- const main = getSessionCost(workflow.mainSession, pricing);
50
- const subs = workflow.subAgentSessions.reduce(
51
- (acc, s) => acc.plus(getSessionCost(s, pricing)),
52
- new Decimal(0)
53
- );
54
- return main.plus(subs);
55
- }
56
-
57
- export function getWorkflowCostSingle(workflow: Workflow, pricing: ModelPricing): Decimal {
58
- const main = getSessionCostSingle(workflow.mainSession, pricing);
59
- const subs = workflow.subAgentSessions.reduce(
60
- (acc, s) => acc.plus(getSessionCostSingle(s, pricing)),
61
- new Decimal(0)
62
- );
63
- return main.plus(subs);
64
- }
65
-
66
- export function getToolUsage(session: Session): ToolUsage[] {
67
- const tools = new Map<
68
- string,
69
- { calls: number; successes: number; failures: number; totalDurationMs: number; recentErrors: string[] }
70
- >();
71
-
72
- for (const interaction of session.interactions) {
73
- for (const part of interaction.parts) {
74
- if (part.type !== "tool") continue;
75
-
76
- const existing = tools.get(part.toolName) ?? {
77
- calls: 0,
78
- successes: 0,
79
- failures: 0,
80
- totalDurationMs: 0,
81
- recentErrors: [],
82
- };
83
-
84
- existing.calls++;
85
- if (part.status === "completed") {
86
- existing.successes++;
87
- } else if (part.status === "error") {
88
- existing.failures++;
89
- // Keep last 3 errors
90
- if (existing.recentErrors.length < 3) {
91
- existing.recentErrors.push(part.output?.slice(0, 200) ?? "unknown error");
92
- }
93
- }
94
-
95
- const durationMs = part.timeEnd > 0 && part.timeStart > 0 ? part.timeEnd - part.timeStart : 0;
96
- existing.totalDurationMs += durationMs;
97
-
98
- tools.set(part.toolName, existing);
99
- }
100
- }
101
-
102
- return Array.from(tools.entries()).map(([name, stats]) => ({
103
- name,
104
- calls: stats.calls,
105
- successes: stats.successes,
106
- failures: stats.failures,
107
- totalDurationMs: stats.totalDurationMs,
108
- avgDurationMs: stats.calls > 0 ? stats.totalDurationMs / stats.calls : 0,
109
- recentErrors: stats.recentErrors,
110
- }));
111
- }
112
-
113
- export function getWorkflowToolUsage(workflow: Workflow): ToolUsage[] {
114
- const allSessions = [workflow.mainSession, ...workflow.subAgentSessions];
115
- const merged = new Map<
116
- string,
117
- { calls: number; successes: number; failures: number; totalDurationMs: number; recentErrors: string[] }
118
- >();
119
-
120
- for (const session of allSessions) {
121
- const usage = getToolUsage(session);
122
- for (const tool of usage) {
123
- const existing = merged.get(tool.name) ?? {
124
- calls: 0,
125
- successes: 0,
126
- failures: 0,
127
- totalDurationMs: 0,
128
- recentErrors: [],
129
- };
130
- existing.calls += tool.calls;
131
- existing.successes += tool.successes;
132
- existing.failures += tool.failures;
133
- existing.totalDurationMs += tool.totalDurationMs;
134
- for (const err of tool.recentErrors) {
135
- if (existing.recentErrors.length < 3) existing.recentErrors.push(err);
136
- }
137
- merged.set(tool.name, existing);
138
- }
139
- }
140
-
141
- return Array.from(merged.entries()).map(([name, stats]) => ({
142
- name,
143
- calls: stats.calls,
144
- successes: stats.successes,
145
- failures: stats.failures,
146
- totalDurationMs: stats.totalDurationMs,
147
- avgDurationMs: stats.calls > 0 ? stats.totalDurationMs / stats.calls : 0,
148
- recentErrors: stats.recentErrors,
149
- }));
150
- }
151
-
152
- export function getOutputRate(session: Session): number {
153
- const rates = session.interactions
154
- .map((i) => i.outputRate)
155
- .filter((r) => r > 0)
156
- .sort((a, b) => a - b);
157
-
158
- if (rates.length === 0) return 0;
159
-
160
- const mid = Math.floor(rates.length / 2);
161
- return rates.length % 2 !== 0 ? rates[mid] : (rates[mid - 1] + rates[mid]) / 2;
162
- }
163
-
164
- export function computeOverviewStats(
165
- workflows: Workflow[],
166
- pricing: Map<string, ModelPricing>
167
- ): OverviewStats {
168
- const totalTokens = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, reasoning: 0 };
169
- let totalCost = new Decimal(0);
170
- const modelBreakdown = new Map<string, { cost: Decimal; tokens: number; calls: number }>();
171
- const projectBreakdown = new Map<string, { cost: Decimal; sessions: number }>();
172
- const agentBreakdown = new Map<string, { cost: Decimal; calls: number }>();
173
- const agentToolErrors = new Map<string, { calls: number; errors: number }>();
174
- const toolCallCounts = new Map<string, { calls: number; errors: number; totalDurationMs: number }>();
175
- const weeklyTokenMap = new Map<string, number>();
176
- const weeklySessionMap = new Map<string, number>();
177
- const hourlyActivity = new Array(24).fill(0);
178
-
179
- const now = Date.now();
180
- const sevenDaysAgo = now - 7 * 86_400_000;
181
-
182
- for (const workflow of workflows) {
183
- const allSessions = [workflow.mainSession, ...workflow.subAgentSessions];
184
-
185
- for (const session of allSessions) {
186
- const projName = session.projectName ?? "Unknown";
187
- const projEntry = projectBreakdown.get(projName) ?? { cost: new Decimal(0), sessions: 0 };
188
- projEntry.sessions++;
189
-
190
- // Weekly session count
191
- const sessionTs = session.timeCreated;
192
- if (sessionTs && sessionTs >= sevenDaysAgo) {
193
- const day = new Date(sessionTs).toISOString().slice(5, 10); // MM-DD
194
- weeklySessionMap.set(day, (weeklySessionMap.get(day) ?? 0) + 1);
195
- }
196
-
197
- for (const interaction of session.interactions) {
198
- const p = pricing.get(interaction.modelId);
199
- const cost = p ? interaction.tokens.calculateCost(p) : new Decimal(0);
200
-
201
- totalCost = totalCost.plus(cost);
202
- projEntry.cost = projEntry.cost.plus(cost);
203
-
204
- totalTokens.input += interaction.tokens.input;
205
- totalTokens.output += interaction.tokens.output;
206
- totalTokens.cacheRead += interaction.tokens.cacheRead;
207
- totalTokens.cacheWrite += interaction.tokens.cacheWrite;
208
- totalTokens.reasoning += interaction.tokens.reasoning;
209
-
210
- // Model breakdown
211
- const modelEntry = modelBreakdown.get(interaction.modelId) ?? {
212
- cost: new Decimal(0),
213
- tokens: 0,
214
- calls: 0,
215
- };
216
- modelEntry.cost = modelEntry.cost.plus(cost);
217
- modelEntry.tokens += interaction.tokens.total;
218
- modelEntry.calls++;
219
- modelBreakdown.set(interaction.modelId, modelEntry);
220
-
221
- // Agent breakdown
222
- const agentKey = interaction.agent ?? "main";
223
- const agentEntry = agentBreakdown.get(agentKey) ?? { cost: new Decimal(0), calls: 0 };
224
- agentEntry.cost = agentEntry.cost.plus(cost);
225
- agentEntry.calls++;
226
- agentBreakdown.set(agentKey, agentEntry);
227
-
228
- // Hourly activity
229
- const ts = interaction.time.created;
230
- if (ts) {
231
- hourlyActivity[new Date(ts).getHours()]++;
232
-
233
- // Weekly token trend
234
- if (ts >= sevenDaysAgo) {
235
- const day = new Date(ts).toISOString().slice(5, 10);
236
- weeklyTokenMap.set(day, (weeklyTokenMap.get(day) ?? 0) + interaction.tokens.total);
237
- }
238
- }
239
-
240
- // Tool stats: per-tool call counts and agent tool errors
241
- for (const part of interaction.parts) {
242
- if (part.type !== "tool") continue;
243
-
244
- const isError = part.status === "error";
245
- const dur = part.timeEnd > 0 && part.timeStart > 0 ? part.timeEnd - part.timeStart : 0;
246
-
247
- // Tool call counts
248
- const toolEntry = toolCallCounts.get(part.toolName) ?? { calls: 0, errors: 0, totalDurationMs: 0 };
249
- toolEntry.calls++;
250
- if (isError) toolEntry.errors++;
251
- toolEntry.totalDurationMs += dur;
252
- toolCallCounts.set(part.toolName, toolEntry);
253
-
254
- // Agent tool errors
255
- const agentToolEntry = agentToolErrors.get(agentKey) ?? { calls: 0, errors: 0 };
256
- agentToolEntry.calls++;
257
- if (isError) agentToolEntry.errors++;
258
- agentToolErrors.set(agentKey, agentToolEntry);
259
- }
260
- }
261
-
262
- projectBreakdown.set(projName, projEntry);
263
- }
264
- }
265
-
266
- // Build 7-day arrays (last 7 days, MM-DD labels)
267
- const today = new Date();
268
- const weeklyTokens: { date: string; tokens: number }[] = [];
269
- const weeklySessions: { date: string; sessions: number }[] = [];
270
- for (let i = 6; i >= 0; i--) {
271
- const d = new Date(today);
272
- d.setDate(d.getDate() - i);
273
- const day = d.toISOString().slice(5, 10);
274
- weeklyTokens.push({ date: day, tokens: weeklyTokenMap.get(day) ?? 0 });
275
- weeklySessions.push({ date: day, sessions: weeklySessionMap.get(day) ?? 0 });
276
- }
277
-
278
- return {
279
- totalCost,
280
- totalTokens: new TokenUsage(
281
- totalTokens.input,
282
- totalTokens.output,
283
- totalTokens.cacheRead,
284
- totalTokens.cacheWrite,
285
- totalTokens.reasoning
286
- ),
287
- modelBreakdown,
288
- projectBreakdown,
289
- agentBreakdown,
290
- agentToolErrors,
291
- toolCallCounts,
292
- weeklyTokens,
293
- weeklySessions,
294
- hourlyActivity,
295
- };
296
- }
297
-
298
- /** Build spark series (8 levels) from numeric array */
299
- export function buildSparkSeries(values: number[]): string {
300
- if (values.length === 0) return "";
301
- const max = Math.max(...values);
302
- if (max === 0) return "▁".repeat(values.length);
303
- const chars = ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"];
304
- return values
305
- .map((v) => {
306
- const idx = Math.min(7, Math.floor((v / max) * 8));
307
- return chars[idx];
308
- })
309
- .join("");
310
- }
311
-
312
- /** All parts across all interactions in a session */
313
- export function getAllParts(session: Session): MessagePart[] {
314
- return session.interactions.flatMap((i) => i.parts);
315
- }
package/src/core/types.ts DELETED
@@ -1,156 +0,0 @@
1
- import Decimal from "decimal.js";
2
-
3
- export class TokenUsage {
4
- constructor(
5
- readonly input: number = 0,
6
- readonly output: number = 0,
7
- readonly cacheRead: number = 0,
8
- readonly cacheWrite: number = 0,
9
- readonly reasoning: number = 0
10
- ) {}
11
-
12
- get total(): number {
13
- return this.input + this.output + this.cacheRead + this.cacheWrite;
14
- }
15
-
16
- add(other: TokenUsage): TokenUsage {
17
- return new TokenUsage(
18
- this.input + other.input,
19
- this.output + other.output,
20
- this.cacheRead + other.cacheRead,
21
- this.cacheWrite + other.cacheWrite,
22
- this.reasoning + other.reasoning
23
- );
24
- }
25
-
26
- calculateCost(pricing: ModelPricing): Decimal {
27
- const inputCost = new Decimal(this.input).mul(pricing.input).div(1_000_000);
28
- const outputCost = new Decimal(this.output).mul(pricing.output).div(1_000_000);
29
- const cacheReadCost = new Decimal(this.cacheRead).mul(pricing.cacheRead).div(1_000_000);
30
- const cacheWriteCost = new Decimal(this.cacheWrite).mul(pricing.cacheWrite).div(1_000_000);
31
- return inputCost.plus(outputCost).plus(cacheReadCost).plus(cacheWriteCost);
32
- }
33
- }
34
-
35
- export interface TimeData {
36
- created: number | null;
37
- completed: number | null;
38
- }
39
-
40
- // Part types from the `part` table
41
- export type MessagePart =
42
- | {
43
- type: "text";
44
- text: string;
45
- timeStart: number;
46
- timeEnd: number;
47
- }
48
- | {
49
- type: "tool";
50
- callId: string;
51
- toolName: string;
52
- status: "completed" | "pending" | "error";
53
- input: Record<string, unknown>;
54
- output: string;
55
- title: string | null;
56
- exitCode: number | null;
57
- truncated: boolean;
58
- timeStart: number;
59
- timeEnd: number;
60
- }
61
- | {
62
- type: "reasoning";
63
- text: string;
64
- timeStart: number;
65
- timeEnd: number;
66
- }
67
- | {
68
- type: "patch";
69
- hash: string;
70
- files: string[];
71
- };
72
-
73
- export interface Interaction {
74
- id: string;
75
- sessionId: string;
76
- modelId: string;
77
- providerId: string | null;
78
- role: "assistant" | "user";
79
- tokens: TokenUsage;
80
- time: TimeData;
81
- agent: string | null;
82
- finishReason: string | null;
83
- outputRate: number;
84
- parts: MessagePart[];
85
- }
86
-
87
- export interface Session {
88
- id: string;
89
- parentId: string | null;
90
- projectId: string | null;
91
- projectName: string | null;
92
- title: string | null;
93
- timeCreated: number | null;
94
- timeArchived: number | null;
95
- interactions: Interaction[];
96
- source: "sqlite" | "files";
97
- }
98
-
99
- export interface AgentNode {
100
- session: Session;
101
- children: AgentNode[];
102
- depth: number;
103
- }
104
-
105
- export interface FlatNode {
106
- id: string;
107
- session: Session;
108
- workflowIndex: number;
109
- depth: number;
110
- hasChildren: boolean;
111
- agentNode: AgentNode;
112
- }
113
-
114
- export interface Workflow {
115
- id: string;
116
- mainSession: Session;
117
- subAgentSessions: Session[];
118
- agentTree: AgentNode;
119
- }
120
-
121
- export interface ModelPricing {
122
- input: Decimal;
123
- output: Decimal;
124
- cacheRead: Decimal;
125
- cacheWrite: Decimal;
126
- contextWindow: number;
127
- }
128
-
129
- export interface ToolUsage {
130
- name: string;
131
- calls: number;
132
- successes: number;
133
- failures: number;
134
- totalDurationMs: number;
135
- avgDurationMs: number;
136
- recentErrors: string[];
137
- }
138
-
139
- export interface OverviewStats {
140
- totalCost: Decimal;
141
- totalTokens: TokenUsage;
142
- modelBreakdown: Map<string, { cost: Decimal; tokens: number; calls: number }>;
143
- projectBreakdown: Map<string, { cost: Decimal; sessions: number }>;
144
- agentBreakdown: Map<string, { cost: Decimal; calls: number }>;
145
- agentToolErrors: Map<string, { calls: number; errors: number }>;
146
- toolCallCounts: Map<string, { calls: number; errors: number; totalDurationMs: number }>;
147
- // 7-day daily data
148
- weeklyTokens: { date: string; tokens: number }[];
149
- weeklySessions: { date: string; sessions: number }[];
150
- // 24-hour activity pattern (interactions per hour, all-time)
151
- hourlyActivity: number[];
152
- }
153
-
154
- export type ScreenId = "sessions" | "tools" | "overview";
155
-
156
- export type { Decimal };
@@ -1,82 +0,0 @@
1
- import Decimal from "decimal.js";
2
- import type { ModelPricing } from "../core/types";
3
-
4
- const DEFAULT_PRICING: ModelPricing = {
5
- input: new Decimal(0),
6
- output: new Decimal(0),
7
- cacheRead: new Decimal(0),
8
- cacheWrite: new Decimal(0),
9
- contextWindow: 128000,
10
- };
11
-
12
- const KNOWN_PRICING: Record<string, Partial<ModelPricing>> = {
13
- "claude-sonnet-4-20250514": {
14
- input: new Decimal(3),
15
- output: new Decimal(15),
16
- cacheRead: new Decimal(0.3),
17
- cacheWrite: new Decimal(3.75),
18
- contextWindow: 200000,
19
- },
20
- "claude-3-5-sonnet-20241022": {
21
- input: new Decimal(3),
22
- output: new Decimal(15),
23
- cacheRead: new Decimal(0.3),
24
- cacheWrite: new Decimal(3.75),
25
- contextWindow: 200000,
26
- },
27
- "claude-3-5-sonnet-20240620": {
28
- input: new Decimal(3),
29
- output: new Decimal(15),
30
- cacheRead: new Decimal(0.3),
31
- cacheWrite: new Decimal(3.75),
32
- contextWindow: 200000,
33
- },
34
- "claude-3-5-haiku-20241022": {
35
- input: new Decimal(1),
36
- output: new Decimal(5),
37
- cacheRead: new Decimal(0.1),
38
- cacheWrite: new Decimal(1.25),
39
- contextWindow: 200000,
40
- },
41
- "claude-3-haiku-20240307": {
42
- input: new Decimal(0.25),
43
- output: new Decimal(1.25),
44
- cacheRead: new Decimal(0.03),
45
- cacheWrite: new Decimal(0.3),
46
- contextWindow: 200000,
47
- },
48
- "claude-3-opus-20240229": {
49
- input: new Decimal(15),
50
- output: new Decimal(75),
51
- cacheRead: new Decimal(1.5),
52
- cacheWrite: new Decimal(18.75),
53
- contextWindow: 200000,
54
- },
55
- "claude-opus-4-20250514": {
56
- input: new Decimal(15),
57
- output: new Decimal(75),
58
- cacheRead: new Decimal(1.5),
59
- cacheWrite: new Decimal(18.75),
60
- contextWindow: 200000,
61
- },
62
- };
63
-
64
- export function getPricing(modelId: string): ModelPricing {
65
- const normalized = modelId.toLowerCase();
66
-
67
- for (const [key, pricing] of Object.entries(KNOWN_PRICING)) {
68
- if (normalized.includes(key.toLowerCase()) || key.toLowerCase().includes(normalized)) {
69
- return { ...DEFAULT_PRICING, ...pricing };
70
- }
71
- }
72
-
73
- return DEFAULT_PRICING;
74
- }
75
-
76
- export function getAllPricing(): Map<string, ModelPricing> {
77
- const result = new Map<string, ModelPricing>();
78
- for (const [key, pricing] of Object.entries(KNOWN_PRICING)) {
79
- result.set(key.toLowerCase(), { ...DEFAULT_PRICING, ...pricing });
80
- }
81
- return result;
82
- }