copilot-session-usage 0.1.0__py3-none-any.whl
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.
- copilot_session_usage/__init__.py +10 -0
- copilot_session_usage/_internal/__init__.py +1 -0
- copilot_session_usage/_internal/copilot_cli.py +18 -0
- copilot_session_usage/_internal/core.py +1016 -0
- copilot_session_usage/_internal/vscode.py +242 -0
- copilot_session_usage/api.py +211 -0
- copilot_session_usage/cli.py +282 -0
- copilot_session_usage/data/__init__.py +0 -0
- copilot_session_usage/data/custom-models-pricing.yml +22 -0
- copilot_session_usage/data/models-and-pricing.lock +7 -0
- copilot_session_usage/data/models-and-pricing.yml +269 -0
- copilot_session_usage-0.1.0.dist-info/METADATA +187 -0
- copilot_session_usage-0.1.0.dist-info/RECORD +16 -0
- copilot_session_usage-0.1.0.dist-info/WHEEL +4 -0
- copilot_session_usage-0.1.0.dist-info/entry_points.txt +2 -0
- copilot_session_usage-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"""Click CLI entry point for copilot-session-usage."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import click
|
|
9
|
+
|
|
10
|
+
from copilot_session_usage._internal import core, vscode
|
|
11
|
+
|
|
12
|
+
CONTEXT_SETTINGS = {"help_option_names": ["-h", "--help"]}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _resolve_agent(agent: str) -> str:
|
|
16
|
+
"""Validate agent choice and return it."""
|
|
17
|
+
if agent == "cli":
|
|
18
|
+
raise click.ClickException(
|
|
19
|
+
"Copilot-CLI session discovery is not yet implemented. "
|
|
20
|
+
"Use --agent vscode (the default)."
|
|
21
|
+
)
|
|
22
|
+
return agent
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@click.group(context_settings=CONTEXT_SETTINGS)
|
|
26
|
+
@click.option(
|
|
27
|
+
"--workspace-storage",
|
|
28
|
+
"workspace_storage",
|
|
29
|
+
metavar="PATH",
|
|
30
|
+
help=(
|
|
31
|
+
"Override workspaceStorage directory (auto-detected by default). "
|
|
32
|
+
"Required on WSL2 when VS Code runs on the Windows host."
|
|
33
|
+
),
|
|
34
|
+
)
|
|
35
|
+
@click.option(
|
|
36
|
+
"--agent",
|
|
37
|
+
"agent",
|
|
38
|
+
type=click.Choice(("vscode", "cli")),
|
|
39
|
+
default="vscode",
|
|
40
|
+
show_default=True,
|
|
41
|
+
help="Provider to use for session discovery. 'cli' is not yet implemented.",
|
|
42
|
+
)
|
|
43
|
+
@click.pass_context
|
|
44
|
+
def cli(
|
|
45
|
+
ctx: click.Context,
|
|
46
|
+
workspace_storage: str | None,
|
|
47
|
+
agent: str,
|
|
48
|
+
) -> None:
|
|
49
|
+
"""Extract VS Code Copilot session cost KPIs from local debug logs.
|
|
50
|
+
|
|
51
|
+
Reads JSONL debug logs written by the VS Code Copilot Chat extension to
|
|
52
|
+
compute per-session token counts, estimated USD spend, model breakdowns,
|
|
53
|
+
duration, and subagent attribution.
|
|
54
|
+
|
|
55
|
+
Sessions are auto-discovered from the VS Code workspaceStorage directory
|
|
56
|
+
(override with --workspace-storage). Use the subcommands below to analyze
|
|
57
|
+
individual sessions, the latest session, or batches.
|
|
58
|
+
|
|
59
|
+
Output is controlled by --detail (minimal / compact / full) and
|
|
60
|
+
--format (table / json / detailed). Key capabilities include per-model
|
|
61
|
+
pricing with cache-hit discounts, threshold-aware tier switching for
|
|
62
|
+
long-context models, multi-model session handling, subagent cost
|
|
63
|
+
attribution, and cross-platform support (macOS, Linux, Windows, WSL2).
|
|
64
|
+
"""
|
|
65
|
+
ctx.ensure_object(dict)
|
|
66
|
+
ctx.obj["workspace_storage"] = workspace_storage
|
|
67
|
+
ctx.obj["agent"] = _resolve_agent(agent)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@cli.command()
|
|
71
|
+
@core.analysis_options
|
|
72
|
+
@click.argument("log_dir", metavar="PATH")
|
|
73
|
+
def analyze(
|
|
74
|
+
log_dir: str,
|
|
75
|
+
detail: str,
|
|
76
|
+
format_: str,
|
|
77
|
+
output_path: str | None,
|
|
78
|
+
) -> None:
|
|
79
|
+
"""Analyze a single session by its debug-log directory PATH.
|
|
80
|
+
|
|
81
|
+
PATH is typically the VS Code Copilot session debug log directory —
|
|
82
|
+
this is the fastest path, no discovery needed.
|
|
83
|
+
"""
|
|
84
|
+
session_dir = Path(log_dir)
|
|
85
|
+
if not session_dir.exists():
|
|
86
|
+
msg = f"log directory not found: {session_dir}"
|
|
87
|
+
raise click.ClickException(msg)
|
|
88
|
+
pricing = core.load_pricing()
|
|
89
|
+
result = core.analyze_session(session_dir, pricing)
|
|
90
|
+
detail = core.resolve_detail(detail, format_)
|
|
91
|
+
out_path = Path(output_path) if output_path else None
|
|
92
|
+
core.emit(core.shape_session(result, detail), core.normalize_format(format_), out_path)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@cli.command()
|
|
96
|
+
@core.analysis_options
|
|
97
|
+
@click.option(
|
|
98
|
+
"--workspace", metavar="PATH", help="Only consider sessions from this workspace folder."
|
|
99
|
+
)
|
|
100
|
+
@click.pass_context
|
|
101
|
+
def latest(
|
|
102
|
+
ctx: click.Context,
|
|
103
|
+
workspace: str | None,
|
|
104
|
+
detail: str,
|
|
105
|
+
format_: str,
|
|
106
|
+
output_path: str | None,
|
|
107
|
+
) -> None:
|
|
108
|
+
"""Analyze the most recently modified session across all workspaces."""
|
|
109
|
+
ws_roots = vscode.resolve_ws_roots(ctx.obj.get("workspace_storage"))
|
|
110
|
+
session_dir = vscode.find_latest_session_dir(ws_roots, workspace_filter=workspace)
|
|
111
|
+
if not session_dir:
|
|
112
|
+
msg = "no session debug logs found in workspace storage."
|
|
113
|
+
raise click.ClickException(msg)
|
|
114
|
+
pricing = core.load_pricing()
|
|
115
|
+
result = core.analyze_session(session_dir, pricing)
|
|
116
|
+
detail = core.resolve_detail(detail, format_)
|
|
117
|
+
out_path = Path(output_path) if output_path else None
|
|
118
|
+
core.emit(
|
|
119
|
+
core.shape_session(result, detail),
|
|
120
|
+
core.normalize_format(format_),
|
|
121
|
+
out_path,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
@cli.command(name="find")
|
|
126
|
+
@core.analysis_options
|
|
127
|
+
@click.option(
|
|
128
|
+
"--workspace",
|
|
129
|
+
metavar="PATH",
|
|
130
|
+
help="Only consider sessions from this workspace folder.",
|
|
131
|
+
)
|
|
132
|
+
@click.argument("title")
|
|
133
|
+
@click.pass_context
|
|
134
|
+
def find_by_title(
|
|
135
|
+
ctx: click.Context,
|
|
136
|
+
title: str,
|
|
137
|
+
workspace: str | None,
|
|
138
|
+
detail: str,
|
|
139
|
+
format_: str,
|
|
140
|
+
output_path: str | None,
|
|
141
|
+
) -> None:
|
|
142
|
+
"""Find and analyze a session by TITLE (case-insensitive substring match).
|
|
143
|
+
|
|
144
|
+
If more than one session matches, candidates are printed and the command
|
|
145
|
+
exits with an error — re-run with `id <SESSION_ID>` to pick one.
|
|
146
|
+
"""
|
|
147
|
+
ws_roots = vscode.resolve_ws_roots(ctx.obj.get("workspace_storage"))
|
|
148
|
+
matches = vscode.find_sessions_by_title(title, ws_roots)
|
|
149
|
+
if workspace:
|
|
150
|
+
matches = [m for m in matches if workspace in m.get("workspace_folder", "")]
|
|
151
|
+
if not matches:
|
|
152
|
+
msg = f"no sessions found matching title: {title!r}"
|
|
153
|
+
raise click.ClickException(msg)
|
|
154
|
+
if len(matches) > 1:
|
|
155
|
+
click.echo(f"Multiple sessions match {title!r}:", err=True)
|
|
156
|
+
for m in matches[:10]:
|
|
157
|
+
ts = core.ts_to_iso(m.get("created_ms")) or "unknown"
|
|
158
|
+
click.echo(f" {ts} {m['title']!r} (id: {m['session_id']})", err=True)
|
|
159
|
+
click.echo("Re-run with: copilot-session-usage id <SESSION_ID>", err=True)
|
|
160
|
+
sys.exit(1)
|
|
161
|
+
match = matches[0]
|
|
162
|
+
session_dir = Path(match["debug_log_dir"])
|
|
163
|
+
if not session_dir.exists():
|
|
164
|
+
msg = f"debug logs not present at: {session_dir}"
|
|
165
|
+
raise click.ClickException(msg)
|
|
166
|
+
pricing = core.load_pricing()
|
|
167
|
+
result = core.analyze_session(session_dir, pricing)
|
|
168
|
+
result["title"] = match.get("title") or result.get("title")
|
|
169
|
+
detail = core.resolve_detail(detail, format_)
|
|
170
|
+
out_path = Path(output_path) if output_path else None
|
|
171
|
+
core.emit(
|
|
172
|
+
core.shape_session(result, detail),
|
|
173
|
+
core.normalize_format(format_),
|
|
174
|
+
out_path,
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@cli.command(name="id")
|
|
179
|
+
@core.analysis_options
|
|
180
|
+
@click.argument("session_id")
|
|
181
|
+
@click.pass_context
|
|
182
|
+
def analyze_by_id(
|
|
183
|
+
ctx: click.Context,
|
|
184
|
+
session_id: str,
|
|
185
|
+
detail: str,
|
|
186
|
+
format_: str,
|
|
187
|
+
output_path: str | None,
|
|
188
|
+
) -> None:
|
|
189
|
+
"""Analyze a session by its exact SESSION_ID (UUID)."""
|
|
190
|
+
ws_roots = vscode.resolve_ws_roots(ctx.obj.get("workspace_storage"))
|
|
191
|
+
session_dir = vscode.find_session_dir_by_id(session_id, ws_roots)
|
|
192
|
+
if not session_dir:
|
|
193
|
+
msg = f"no debug logs found for session ID: {session_id}"
|
|
194
|
+
raise click.ClickException(msg)
|
|
195
|
+
pricing = core.load_pricing()
|
|
196
|
+
result = core.analyze_session(session_dir, pricing)
|
|
197
|
+
detail = core.resolve_detail(detail, format_)
|
|
198
|
+
out_path = Path(output_path) if output_path else None
|
|
199
|
+
core.emit(core.shape_session(result, detail), core.normalize_format(format_), out_path)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
@cli.command(name="list")
|
|
203
|
+
@core.format_option
|
|
204
|
+
@core.output_option
|
|
205
|
+
@click.option(
|
|
206
|
+
"--limit",
|
|
207
|
+
type=int,
|
|
208
|
+
default=20,
|
|
209
|
+
show_default=True,
|
|
210
|
+
help="Max sessions to return.",
|
|
211
|
+
)
|
|
212
|
+
@click.option(
|
|
213
|
+
"--since", metavar="DATE", help="Only sessions created after DATE (YYYY-MM-DD or ISO 8601)."
|
|
214
|
+
)
|
|
215
|
+
@click.option(
|
|
216
|
+
"--workspace", metavar="PATH", help="Only consider sessions from this workspace folder."
|
|
217
|
+
)
|
|
218
|
+
@click.pass_context
|
|
219
|
+
def list_sessions(
|
|
220
|
+
ctx: click.Context,
|
|
221
|
+
limit: int,
|
|
222
|
+
since: str | None,
|
|
223
|
+
workspace: str | None,
|
|
224
|
+
format_: str,
|
|
225
|
+
output_path: str | None,
|
|
226
|
+
) -> None:
|
|
227
|
+
"""List recent sessions (metadata only — no cost analysis)."""
|
|
228
|
+
ws_roots = vscode.resolve_ws_roots(ctx.obj.get("workspace_storage"))
|
|
229
|
+
since_ms = core.parse_since_to_ms(since) if since else None
|
|
230
|
+
sessions = vscode.list_recent_sessions(
|
|
231
|
+
ws_roots, limit=limit, since_ms=since_ms, workspace_filter=workspace
|
|
232
|
+
)
|
|
233
|
+
out_path = Path(output_path) if output_path else None
|
|
234
|
+
core.emit(sessions, core.normalize_format(format_), out_path)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
@cli.command()
|
|
238
|
+
@core.analysis_options
|
|
239
|
+
@click.option(
|
|
240
|
+
"--since", metavar="DATE", help="Only sessions created after DATE (YYYY-MM-DD or ISO 8601)."
|
|
241
|
+
)
|
|
242
|
+
@click.option(
|
|
243
|
+
"--workspace", metavar="PATH", help="Only consider sessions from this workspace folder."
|
|
244
|
+
)
|
|
245
|
+
@click.argument("count", type=int, metavar="N")
|
|
246
|
+
@click.pass_context
|
|
247
|
+
def batch(
|
|
248
|
+
ctx: click.Context,
|
|
249
|
+
count: int,
|
|
250
|
+
since: str | None,
|
|
251
|
+
workspace: str | None,
|
|
252
|
+
detail: str,
|
|
253
|
+
format_: str,
|
|
254
|
+
output_path: str | None,
|
|
255
|
+
) -> None:
|
|
256
|
+
"""Analyze the N most recent sessions in one invocation.
|
|
257
|
+
|
|
258
|
+
Always returns {"summary": {...}, "sessions": [...]}: a pre-computed
|
|
259
|
+
aggregate across all N sessions plus a per-session array shaped by
|
|
260
|
+
--detail. Much faster than N separate `id` invocations.
|
|
261
|
+
"""
|
|
262
|
+
ws_roots = vscode.resolve_ws_roots(ctx.obj.get("workspace_storage"))
|
|
263
|
+
since_ms = core.parse_since_to_ms(since) if since else None
|
|
264
|
+
sessions = vscode.list_recent_sessions(
|
|
265
|
+
ws_roots,
|
|
266
|
+
limit=count,
|
|
267
|
+
since_ms=since_ms,
|
|
268
|
+
workspace_filter=workspace,
|
|
269
|
+
require_logs=True,
|
|
270
|
+
)
|
|
271
|
+
pricing = core.load_pricing()
|
|
272
|
+
results: list[dict] = []
|
|
273
|
+
for session in sessions:
|
|
274
|
+
session_dir = Path(session["debug_log_dir"])
|
|
275
|
+
if not session_dir.exists():
|
|
276
|
+
continue
|
|
277
|
+
result = core.analyze_session(session_dir, pricing)
|
|
278
|
+
result["title"] = session.get("title") or result.get("title")
|
|
279
|
+
results.append(result)
|
|
280
|
+
detail = core.resolve_detail(detail, format_)
|
|
281
|
+
out_path = Path(output_path) if output_path else None
|
|
282
|
+
core.emit(core.shape_batch(results, detail), core.normalize_format(format_), out_path)
|
|
File without changes
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Custom model pricing for models not included in the GitHub Copilot plan.
|
|
2
|
+
# Prices are per 1 million tokens.
|
|
3
|
+
#
|
|
4
|
+
# Use this file to define pricing for models that appear in debug logs
|
|
5
|
+
# but are not part of the standard Copilot model catalog.
|
|
6
|
+
#
|
|
7
|
+
# Column keys:
|
|
8
|
+
# - model: The model name as it appears in the debug log.
|
|
9
|
+
# - provider: The model provider (optional, defaults to "custom").
|
|
10
|
+
# - input: Input token price per 1M tokens.
|
|
11
|
+
# - cached_input: Cached input token price per 1M tokens.
|
|
12
|
+
# - output: Output token price per 1M tokens.
|
|
13
|
+
# - notes: Optional notes about the model.
|
|
14
|
+
|
|
15
|
+
- model: 'Kimi-K2.6-azure'
|
|
16
|
+
provider: custom
|
|
17
|
+
input: $0.00
|
|
18
|
+
cached_input: $0.00
|
|
19
|
+
output: $0.00
|
|
20
|
+
notes: >
|
|
21
|
+
Azure-hosted Kimi K2.6 model. Pricing not tracked in Copilot plan;
|
|
22
|
+
set to $0 as a placeholder. Update if actual per-token pricing becomes available.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_captured": "2026-07-01T13:17:03.382420+00:00",
|
|
3
|
+
"_source": "https://raw.githubusercontent.com/github/docs/main/data/tables/copilot/models-and-pricing.yml",
|
|
4
|
+
"_yaml_path": "references/models-and-pricing.yml",
|
|
5
|
+
"model_count": 26,
|
|
6
|
+
"checksum": "0d398b5cf45bf9ff"
|
|
7
|
+
}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# This file defines per-token pricing for AI models available in GitHub Copilot.
|
|
2
|
+
# Prices are per 1 million tokens.
|
|
3
|
+
#
|
|
4
|
+
# Please keep this list sorted by provider, then alphabetically by model name.
|
|
5
|
+
# Providers in this order: OpenAI, Anthropic, Google, xAI, Fine-tuned (GitHub).
|
|
6
|
+
#
|
|
7
|
+
# Column keys:
|
|
8
|
+
# - model: The model name.
|
|
9
|
+
# - provider: The model provider (openai, anthropic, google, xai, github).
|
|
10
|
+
# - release_status: "GA" or "Public preview".
|
|
11
|
+
# - category: The model category or task area.
|
|
12
|
+
# - input: Input token price per 1M tokens.
|
|
13
|
+
# - cached_input: Cached input token price per 1M tokens.
|
|
14
|
+
# - output: Output token price per 1M tokens.
|
|
15
|
+
# - threshold: Input token threshold for pricing tier (OpenAI and Google only).
|
|
16
|
+
# - tier: Pricing tier label (OpenAI and Google only).
|
|
17
|
+
# - cache_write: Cache write price per 1M tokens (Anthropic only).
|
|
18
|
+
# - notes: Optional notes about the model.
|
|
19
|
+
|
|
20
|
+
# OpenAI
|
|
21
|
+
- model: 'GPT-5 mini'
|
|
22
|
+
provider: openai
|
|
23
|
+
release_status: GA
|
|
24
|
+
category: Lightweight
|
|
25
|
+
threshold: Not applicable
|
|
26
|
+
tier: Default
|
|
27
|
+
input: $0.25
|
|
28
|
+
cached_input: $0.025
|
|
29
|
+
output: $2.00
|
|
30
|
+
|
|
31
|
+
- model: GPT-5.3-Codex
|
|
32
|
+
provider: openai
|
|
33
|
+
release_status: GA
|
|
34
|
+
category: Powerful
|
|
35
|
+
threshold: Not applicable
|
|
36
|
+
tier: Default
|
|
37
|
+
input: $1.75
|
|
38
|
+
cached_input: $0.175
|
|
39
|
+
output: $14.00
|
|
40
|
+
|
|
41
|
+
- model: 'GPT-5.4'
|
|
42
|
+
provider: openai
|
|
43
|
+
release_status: GA
|
|
44
|
+
category: Versatile
|
|
45
|
+
threshold: '≤ 272K'
|
|
46
|
+
tier: Default
|
|
47
|
+
input: $2.50
|
|
48
|
+
cached_input: $0.25
|
|
49
|
+
output: $15.00
|
|
50
|
+
|
|
51
|
+
- model: GPT-5.4
|
|
52
|
+
provider: openai
|
|
53
|
+
release_status: GA
|
|
54
|
+
category: Versatile
|
|
55
|
+
threshold: '> 272K'
|
|
56
|
+
tier: Long context
|
|
57
|
+
input: $5.00
|
|
58
|
+
cached_input: $0.50
|
|
59
|
+
output: $22.50
|
|
60
|
+
|
|
61
|
+
- model: GPT-5.4 mini
|
|
62
|
+
provider: openai
|
|
63
|
+
release_status: GA
|
|
64
|
+
category: Lightweight
|
|
65
|
+
threshold: Not applicable
|
|
66
|
+
tier: Default
|
|
67
|
+
input: $0.75
|
|
68
|
+
cached_input: $0.075
|
|
69
|
+
output: $4.50
|
|
70
|
+
|
|
71
|
+
- model: GPT-5.4 nano
|
|
72
|
+
provider: openai
|
|
73
|
+
release_status: GA
|
|
74
|
+
category: Lightweight
|
|
75
|
+
threshold: Not applicable
|
|
76
|
+
tier: Default
|
|
77
|
+
input: $0.20
|
|
78
|
+
cached_input: $0.02
|
|
79
|
+
output: $1.25
|
|
80
|
+
|
|
81
|
+
- model: GPT-5.5
|
|
82
|
+
provider: openai
|
|
83
|
+
release_status: GA
|
|
84
|
+
category: Powerful
|
|
85
|
+
threshold: '≤ 272K'
|
|
86
|
+
tier: Default
|
|
87
|
+
input: $5.00
|
|
88
|
+
cached_input: $0.50
|
|
89
|
+
output: $30.00
|
|
90
|
+
|
|
91
|
+
- model: GPT-5.5
|
|
92
|
+
provider: openai
|
|
93
|
+
release_status: GA
|
|
94
|
+
category: Powerful
|
|
95
|
+
threshold: '> 272K'
|
|
96
|
+
tier: 'Long context'
|
|
97
|
+
input: $10.00
|
|
98
|
+
cached_input: $1.00
|
|
99
|
+
output: $45.00
|
|
100
|
+
|
|
101
|
+
# Anthropic
|
|
102
|
+
- model: Claude Haiku 4.5
|
|
103
|
+
provider: anthropic
|
|
104
|
+
release_status: GA
|
|
105
|
+
category: Versatile
|
|
106
|
+
input: $1.00
|
|
107
|
+
cached_input: $0.10
|
|
108
|
+
output: $5.00
|
|
109
|
+
cache_write: $1.25
|
|
110
|
+
|
|
111
|
+
- model: Claude Sonnet 4
|
|
112
|
+
provider: anthropic
|
|
113
|
+
release_status: GA
|
|
114
|
+
category: Versatile
|
|
115
|
+
input: $3.00
|
|
116
|
+
cached_input: $0.30
|
|
117
|
+
output: $15.00
|
|
118
|
+
cache_write: $3.75
|
|
119
|
+
|
|
120
|
+
- model: Claude Sonnet 4.5
|
|
121
|
+
provider: anthropic
|
|
122
|
+
release_status: GA
|
|
123
|
+
category: Versatile
|
|
124
|
+
input: $3.00
|
|
125
|
+
cached_input: $0.30
|
|
126
|
+
output: $15.00
|
|
127
|
+
cache_write: $3.75
|
|
128
|
+
|
|
129
|
+
- model: Claude Sonnet 4.6
|
|
130
|
+
provider: anthropic
|
|
131
|
+
release_status: GA
|
|
132
|
+
category: Versatile
|
|
133
|
+
input: $3.00
|
|
134
|
+
cached_input: $0.30
|
|
135
|
+
output: $15.00
|
|
136
|
+
cache_write: $3.75
|
|
137
|
+
|
|
138
|
+
- model: Claude Opus 4.5
|
|
139
|
+
provider: anthropic
|
|
140
|
+
release_status: GA
|
|
141
|
+
category: Powerful
|
|
142
|
+
input: $5.00
|
|
143
|
+
cached_input: $0.50
|
|
144
|
+
output: $25.00
|
|
145
|
+
cache_write: $6.25
|
|
146
|
+
|
|
147
|
+
- model: Claude Opus 4.6
|
|
148
|
+
provider: anthropic
|
|
149
|
+
release_status: GA
|
|
150
|
+
category: Powerful
|
|
151
|
+
input: $5.00
|
|
152
|
+
cached_input: $0.50
|
|
153
|
+
output: $25.00
|
|
154
|
+
cache_write: $6.25
|
|
155
|
+
|
|
156
|
+
- model: Claude Opus 4.7
|
|
157
|
+
provider: anthropic
|
|
158
|
+
release_status: GA
|
|
159
|
+
category: Powerful
|
|
160
|
+
input: $5.00
|
|
161
|
+
cached_input: $0.50
|
|
162
|
+
output: $25.00
|
|
163
|
+
cache_write: $6.25
|
|
164
|
+
|
|
165
|
+
- model: Claude Opus 4.8
|
|
166
|
+
provider: anthropic
|
|
167
|
+
release_status: GA
|
|
168
|
+
category: Powerful
|
|
169
|
+
input: $5.00
|
|
170
|
+
cached_input: $0.50
|
|
171
|
+
output: $25.00
|
|
172
|
+
cache_write: $6.25
|
|
173
|
+
|
|
174
|
+
- model: Claude Sonnet 5[^sonnet-5-promo]
|
|
175
|
+
provider: anthropic
|
|
176
|
+
release_status: GA
|
|
177
|
+
category: Versatile
|
|
178
|
+
input: $2.00
|
|
179
|
+
cached_input: $0.20
|
|
180
|
+
output: $10.00
|
|
181
|
+
cache_write: $2.50
|
|
182
|
+
|
|
183
|
+
- model: Claude Opus 4.8 (fast mode) (preview)
|
|
184
|
+
provider: anthropic
|
|
185
|
+
release_status: GA
|
|
186
|
+
category: Powerful
|
|
187
|
+
input: $10.00
|
|
188
|
+
cached_input: $1.00
|
|
189
|
+
output: $50.00
|
|
190
|
+
cache_write: $12.50
|
|
191
|
+
|
|
192
|
+
- model: Claude Fable 5
|
|
193
|
+
provider: anthropic
|
|
194
|
+
release_status: GA
|
|
195
|
+
category: Powerful
|
|
196
|
+
input: $10.00
|
|
197
|
+
cached_input: $1.00
|
|
198
|
+
output: $50.00
|
|
199
|
+
cache_write: $12.50
|
|
200
|
+
|
|
201
|
+
# Google
|
|
202
|
+
- model: 'Gemini 2.5 Pro'
|
|
203
|
+
provider: google
|
|
204
|
+
release_status: GA
|
|
205
|
+
category: Powerful
|
|
206
|
+
threshold: 'Not applicable'
|
|
207
|
+
tier: 'Default'
|
|
208
|
+
input: $1.25
|
|
209
|
+
cached_input: $0.125
|
|
210
|
+
output: $10.00
|
|
211
|
+
|
|
212
|
+
- model: 'Gemini 3 Flash'
|
|
213
|
+
provider: google
|
|
214
|
+
release_status: Public preview
|
|
215
|
+
category: Lightweight
|
|
216
|
+
threshold: 'Not applicable'
|
|
217
|
+
tier: 'Default'
|
|
218
|
+
input: $0.50
|
|
219
|
+
cached_input: $0.05
|
|
220
|
+
output: $3.00
|
|
221
|
+
|
|
222
|
+
- model: 'Gemini 3.1 Pro'
|
|
223
|
+
provider: google
|
|
224
|
+
release_status: Public preview
|
|
225
|
+
category: Powerful
|
|
226
|
+
threshold: '≤ 200K'
|
|
227
|
+
tier: 'Default'
|
|
228
|
+
input: $2.00
|
|
229
|
+
cached_input: $0.20
|
|
230
|
+
output: $12.00
|
|
231
|
+
|
|
232
|
+
- model: 'Gemini 3.1 Pro'
|
|
233
|
+
provider: google
|
|
234
|
+
release_status: Public preview
|
|
235
|
+
category: Powerful
|
|
236
|
+
threshold: '> 200K'
|
|
237
|
+
tier: 'Long context'
|
|
238
|
+
input: $4.00
|
|
239
|
+
cached_input: $0.40
|
|
240
|
+
output: $18.00
|
|
241
|
+
|
|
242
|
+
- model: 'Gemini 3.5 Flash'
|
|
243
|
+
provider: google
|
|
244
|
+
release_status: GA
|
|
245
|
+
category: Lightweight
|
|
246
|
+
threshold: 'Not applicable'
|
|
247
|
+
tier: 'Default'
|
|
248
|
+
input: $1.50
|
|
249
|
+
cached_input: $0.15
|
|
250
|
+
output: $9.00
|
|
251
|
+
|
|
252
|
+
# Microsoft
|
|
253
|
+
- model: 'MAI-Code-1-Flash'
|
|
254
|
+
provider: microsoft
|
|
255
|
+
release_status: GA
|
|
256
|
+
category: Lightweight
|
|
257
|
+
input: $0.75
|
|
258
|
+
cached_input: $0.075
|
|
259
|
+
output: $4.50
|
|
260
|
+
|
|
261
|
+
# Fine-tuned (GitHub)
|
|
262
|
+
- model: 'Raptor mini'
|
|
263
|
+
provider: github
|
|
264
|
+
release_status: GA
|
|
265
|
+
category: Versatile
|
|
266
|
+
input: $0.25
|
|
267
|
+
cached_input: $0.025
|
|
268
|
+
output: $2.00
|
|
269
|
+
notes: Uses GPT-5 mini pricing
|