copilot-session-usage 0.2.1__tar.gz → 0.2.2__tar.gz
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-0.2.1 → copilot_session_usage-0.2.2}/CHANGELOG.md +6 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/PKG-INFO +3 -3
- copilot_session_usage-0.2.2/docs/source/explanation/how-cost-estimation-works.md +138 -0
- copilot_session_usage-0.2.2/docs/source/reference/pricing.md +122 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/justfile +1 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/_schema/Base.schema.yaml +10 -1
- copilot_session_usage-0.2.2/knowledge/_schema/Experiment.schema.yaml +44 -0
- copilot_session_usage-0.2.2/knowledge/_schema/Finding.schema.yaml +49 -0
- copilot_session_usage-0.2.2/knowledge/_schema/Principle.schema.yaml +25 -0
- copilot_session_usage-0.2.2/knowledge/_schema/Structure.schema.yaml +26 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/concepts/overview.md +2 -2
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/concepts/session-cost-analysis.md +1 -1
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/experiments/verify-subagent-cost-attribution.md +2 -1
- copilot_session_usage-0.2.2/knowledge/findings/cache-write-cost-not-tracked.md +83 -0
- copilot_session_usage-0.2.2/knowledge/findings/index.md +7 -0
- copilot_session_usage-0.2.2/knowledge/findings/title-jsonl-not-counted-as-model-turn.md +50 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/reference/debug-log-format.md +3 -2
- copilot_session_usage-0.2.2/knowledge/structures/cache-cost-approximation.md +86 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/structures/index.md +1 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/structures/subagent-cost-tracking.md +13 -5
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/structures/vscode-copilot-extension.md +9 -1
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/src/copilot_session_usage/_internal/core.py +53 -14
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/src/copilot_session_usage/_internal/vscode.py +54 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/src/copilot_session_usage/api.py +7 -1
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/src/copilot_session_usage/cli.py +5 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/src/copilot_session_usage/data/custom-models-pricing.yml +3 -2
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/tests/conftest.py +4 -6
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/tests/test_api.py +100 -109
- copilot_session_usage-0.2.2/tests/test_cli.py +280 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/tests/test_coverage_gaps.py +32 -33
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/tests/test_vscode.py +42 -0
- copilot_session_usage-0.2.1/docs/source/explanation/how-cost-estimation-works.md +0 -96
- copilot_session_usage-0.2.1/docs/source/reference/pricing.md +0 -62
- copilot_session_usage-0.2.1/knowledge/_schema/Experiment.schema.yaml +0 -55
- copilot_session_usage-0.2.1/knowledge/_schema/Finding.schema.yaml +0 -64
- copilot_session_usage-0.2.1/knowledge/_schema/Principle.schema.yaml +0 -40
- copilot_session_usage-0.2.1/knowledge/_schema/Structure.schema.yaml +0 -41
- copilot_session_usage-0.2.1/knowledge/findings/index.md +0 -5
- copilot_session_usage-0.2.1/tests/test_cli.py +0 -274
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/.editorconfig +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/.github/guidelines/knowledge-base.guidelines.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/.github/pull_request_template.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/.github/skills/consolidate-knowledge-base/SKILL.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/.github/skills/record-finding/SKILL.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/.github/workflows/ci.yml +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/.github/workflows/publish.yml +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/.gitignore +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/.readthedocs.yaml +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/AGENTS.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/CONTRIBUTING.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/LICENSE +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/README.md +2 -2
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/_static/changelog.js +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/_static/custom.css +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/changelog.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/conf.py +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/explanation/index.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/how-to/analyze-specific-session.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/how-to/batch-and-spending.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/how-to/export-json.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/how-to/index.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/how-to/wsl2.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/index.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/installation.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/reference/api.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/reference/cli.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/reference/index.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/tutorials/getting-started.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/docs/source/tutorials/index.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/_schema/Concept.schema.yaml +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/_schema/Playbook.schema.yaml +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/_schema/Reference.schema.yaml +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/concepts/copilot-cli.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/concepts/index.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/concepts/threshold-based-pricing.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/experiments/index.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/findings/subagent-logs-use-runsubagent-prefix.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/guides/automation-scripts.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/guides/cost-optimization.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/guides/index.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/guides/wsl2-setup.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/ideas/index.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/ideas/multi-session-efficiency-analytics.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/index.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/log.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/principles/findings-are-immutable.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/principles/index.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/reference/index.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/reference/pricing-formats.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/structures/knowledge-base-information-types.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/structures/session-discovery-algorithm.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/pyproject.toml +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/scripts/refresh_pricing.py +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/skills/copilot-session-usage/SKILL.md +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/src/copilot_session_usage/__init__.py +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/src/copilot_session_usage/_internal/__init__.py +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/src/copilot_session_usage/_internal/copilot_cli.py +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/src/copilot_session_usage/data/__init__.py +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/src/copilot_session_usage/data/models-and-pricing.lock +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/src/copilot_session_usage/data/models-and-pricing.yml +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/tests/test_core.py +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/tests/test_rendering.py +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/tests/test_vscode_platform.py +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/uv.lock +0 -0
- {copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/uv.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: copilot-session-usage
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Usage and cost analytics for GitHub Copilot and Copilot-CLI session logs
|
|
5
5
|
Project-URL: Homepage, https://github.com/gsemet/copilot-session-usage
|
|
6
6
|
Project-URL: Documentation, https://copilot-session-usage.readthedocs.io/en/stable/
|
|
@@ -27,6 +27,8 @@ Description-Content-Type: text/markdown
|
|
|
27
27
|
|
|
28
28
|
Extract VS Code Copilot session cost KPIs (tokens, estimated USD, model, duration) from local debug logs.
|
|
29
29
|
|
|
30
|
+
**Full documentation:** [copilot-session-usage.readthedocs.io](https://copilot-session-usage.readthedocs.io/)
|
|
31
|
+
|
|
30
32
|
## Installation
|
|
31
33
|
|
|
32
34
|
```bash
|
|
@@ -183,8 +185,6 @@ just docs
|
|
|
183
185
|
just docs-serve
|
|
184
186
|
```
|
|
185
187
|
|
|
186
|
-
**Full documentation:** [copilot-session-usage.readthedocs.io](https://copilot-session-usage.readthedocs.io/)
|
|
187
|
-
|
|
188
188
|
## License
|
|
189
189
|
|
|
190
190
|
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# How Cost Estimation Works
|
|
2
|
+
|
|
3
|
+
`copilot-session-usage` estimates session costs from VS Code debug logs.
|
|
4
|
+
This page explains each step.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Where the logs live
|
|
9
|
+
|
|
10
|
+
VS Code stores one directory per workspace under `workspaceStorage`. Inside
|
|
11
|
+
each workspace directory, the Copilot extension writes debug logs:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
workspaceStorage/
|
|
15
|
+
└── <workspace-hash>/
|
|
16
|
+
└── GitHub.copilot-chat/
|
|
17
|
+
└── debug-logs/
|
|
18
|
+
└── <session-uuid>/
|
|
19
|
+
├── *.jsonl ← token events
|
|
20
|
+
└── ...
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Default locations by platform:
|
|
24
|
+
|
|
25
|
+
| Platform | Path |
|
|
26
|
+
|----------|------|
|
|
27
|
+
| macOS | `~/Library/Application Support/Code/User/workspaceStorage/` |
|
|
28
|
+
| Linux | `~/.config/Code/User/workspaceStorage/` |
|
|
29
|
+
| Windows | `%APPDATA%\Code\User\workspaceStorage\` |
|
|
30
|
+
| WSL2 (remote) | `~/.vscode-server/data/User/workspaceStorage/` |
|
|
31
|
+
|
|
32
|
+
The tool also checks `Code - Insiders` variants automatically.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## How sessions are discovered
|
|
37
|
+
|
|
38
|
+
The tool reads the session title from VS Code's SQLite workspace database
|
|
39
|
+
(`state.vscdb`). Sessions are sorted by the last-modified time of their
|
|
40
|
+
debug-log directory, most recent first.
|
|
41
|
+
|
|
42
|
+
The `list` command reads only metadata (no JSONL parsing). The `analyze`,
|
|
43
|
+
`id`, and `batch` commands parse the full JSONL files.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Parsing JSONL logs
|
|
48
|
+
|
|
49
|
+
Each `.jsonl` file contains one JSON object per line. The tool extracts
|
|
50
|
+
token-count events emitted by the Copilot extension for each LLM call:
|
|
51
|
+
|
|
52
|
+
- `input_tokens` — tokens sent to the model
|
|
53
|
+
- `output_tokens` — tokens generated by the model
|
|
54
|
+
- `cached_tokens` — input tokens served from the provider's prompt cache
|
|
55
|
+
- `model` — the model name as reported by the provider
|
|
56
|
+
|
|
57
|
+
A single session may call multiple models (e.g., Claude Sonnet for the main
|
|
58
|
+
request and Claude Haiku for a subagent). Each model's tokens are summed
|
|
59
|
+
separately, then costs are computed per model and aggregated.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Cost calculation
|
|
64
|
+
|
|
65
|
+
The VS Code debug log reports `inputTokens` as the **total** prompt sent
|
|
66
|
+
(cached + non-cached combined). `cachedTokens` is the subset served from
|
|
67
|
+
the provider's cache. The non-cached portion is `inputTokens − cachedTokens`.
|
|
68
|
+
|
|
69
|
+
Each `llm_request` event also carries `copilotUsageNanoAiu` — VS Code's own
|
|
70
|
+
cost for that call in nano-AI Credits (nanoAIU). It is present for all
|
|
71
|
+
Copilot-plan models (Claude, GPT, and others). It is absent for Azure-hosted
|
|
72
|
+
models not billed via Copilot AIC — `Kimi-K2.6-azure` is one such model:
|
|
73
|
+
it is billed through Azure separately and correctly reports $0 AIC.
|
|
74
|
+
|
|
75
|
+
When `copilotUsageNanoAiu` is present and non-zero, the tool uses it directly:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
cost_usd = copilotUsageNanoAiu / 100_000_000_000 (1 nanoAIU = 1e-11 USD)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
For models that do not report `copilotUsageNanoAiu` — Azure-hosted models billed
|
|
82
|
+
outside the Copilot plan — the tool falls back to token-based computation
|
|
83
|
+
(or $0 when the model has no Copilot pricing entry):
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
cost_usd = (
|
|
87
|
+
(inputTokens - cachedTokens) × rate.input # fresh tokens
|
|
88
|
+
+ cachedTokens × rate.cached_input # cache-read tokens
|
|
89
|
+
+ outputTokens × rate.output
|
|
90
|
+
) / 1_000_000
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
plus the Anthropic cache-write approximation when applicable.
|
|
94
|
+
|
|
95
|
+
Verified on a real session: `copilotUsageNanoAiu`-based cost matches the
|
|
96
|
+
VS Code AIC panel at **0.000% error** for Claude models.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Subagent attribution
|
|
101
|
+
|
|
102
|
+
`runSubagent` calls appear in the JSONL as a distinct event type. The tool
|
|
103
|
+
tracks them separately so `--detail full` can show which fraction of tokens
|
|
104
|
+
was consumed by subagents vs. the main conversation.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Accuracy
|
|
109
|
+
|
|
110
|
+
For Copilot-plan models (Claude, GPT, etc.), the tool reads
|
|
111
|
+
`copilotUsageNanoAiu` — VS Code's own per-call cost field — directly from the
|
|
112
|
+
JSONL, so the session total matches the VS Code AIC panel at **0% error**.
|
|
113
|
+
|
|
114
|
+
For Azure-hosted models billed outside the Copilot plan (`Kimi-K2.6-azure` is
|
|
115
|
+
the current example), `copilotUsageNanoAiu` is absent. The tool falls back to
|
|
116
|
+
token-based pricing using rates in `custom-models-pricing.yml`. These models
|
|
117
|
+
are billed through Azure separately; setting their prices to `$0.00` in
|
|
118
|
+
`custom-models-pricing.yml` correctly reflects that they do not consume AIC.
|
|
119
|
+
|
|
120
|
+
### Why the LLM-call count differs by 1 from the panel
|
|
121
|
+
|
|
122
|
+
The VS Code Agent Debug panel excludes the `title-*.jsonl` file (background
|
|
123
|
+
title-generation calls). `copilot-session-usage` counts them because they
|
|
124
|
+
consume real tokens. A session with one title-generation call will show one
|
|
125
|
+
more LLM call and the corresponding (small) token counts compared to the panel.
|
|
126
|
+
|
|
127
|
+
### Why token counts can differ between tool and panel
|
|
128
|
+
|
|
129
|
+
Token counts in the tool include `title-*.jsonl`; the VS Code panel does not.
|
|
130
|
+
For session `438d24a8`, the delta is exactly one Kimi call: +441 input, +1,245
|
|
131
|
+
output.
|
|
132
|
+
|
|
133
|
+
### Pricing table updates
|
|
134
|
+
|
|
135
|
+
The bundled pricing table (`data/models-and-pricing.yml`) is updated with each
|
|
136
|
+
release. Run `just refresh-pricing` to pull the latest rates. Stale rates only
|
|
137
|
+
affect the token-based fallback path; `copilotUsageNanoAiu`-based costs are
|
|
138
|
+
unaffected by the table.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Pricing Reference
|
|
2
|
+
|
|
3
|
+
`copilot-session-usage` ships a bundled pricing table at
|
|
4
|
+
`src/copilot_session_usage/data/models-and-pricing.yml`.
|
|
5
|
+
|
|
6
|
+
## Upstream source
|
|
7
|
+
|
|
8
|
+
Prices are synced from the GitHub Copilot official rate card:
|
|
9
|
+
[`github/docs` — `data/tables/copilot/models-and-pricing.yml`](https://github.com/github/docs/blob/main/data/tables/copilot/models-and-pricing.yml)
|
|
10
|
+
|
|
11
|
+
The bundled copy is updated with each release.
|
|
12
|
+
|
|
13
|
+
## Cost formula
|
|
14
|
+
|
|
15
|
+
The VS Code debug log reports three token counts per LLM call:
|
|
16
|
+
|
|
17
|
+
| Field in log | Meaning |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `inputTokens` | **Total** prompt tokens sent — cached and non-cached combined |
|
|
20
|
+
| `cachedTokens` | Subset of `inputTokens` served from the provider's prompt cache |
|
|
21
|
+
| `outputTokens` | Completion tokens generated |
|
|
22
|
+
|
|
23
|
+
Non-cached input = `inputTokens − cachedTokens`. The two input
|
|
24
|
+
components are billed at different rates, so the formula splits them:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
cost_usd = (
|
|
28
|
+
(inputTokens - cachedTokens) × rate.input # fresh prompt tokens
|
|
29
|
+
+ cachedTokens × rate.cached_input # cache-read tokens
|
|
30
|
+
+ outputTokens × rate.output # completion tokens
|
|
31
|
+
) / 1_000_000
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Results are summed across all models called in the session.
|
|
35
|
+
|
|
36
|
+
The equivalent statement using Anthropic-style variable names
|
|
37
|
+
(where `input` already excludes cached tokens) is:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
cost_usd = (
|
|
41
|
+
input × rate.input
|
|
42
|
+
+ cache_read × rate.cached_input
|
|
43
|
+
+ cache_creation × (rate.cache_write ?? rate.input)
|
|
44
|
+
+ output × rate.output
|
|
45
|
+
) / 1_000_000
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
VS Code debug logs do not expose `cache_creation` tokens directly.
|
|
49
|
+
For Anthropic models, the tool approximates the incremental cache-creation
|
|
50
|
+
cost using fresh input as a proxy (see note below).
|
|
51
|
+
|
|
52
|
+
:::{note}
|
|
53
|
+
**Anthropic `cache_write` — approximated via fresh input.**
|
|
54
|
+
|
|
55
|
+
Anthropic models have a `cache_write` rate for tokens written to the provider's
|
|
56
|
+
cache for the first time. VS Code JSONL logs do not expose `cacheCreationTokens`;
|
|
57
|
+
`agent-traces.db` has the schema column but VS Code does not populate it for
|
|
58
|
+
Claude models (verified: 0 rows, VS Code 1.103+).
|
|
59
|
+
|
|
60
|
+
The tool approximates the incremental cost as:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
delta = (inputTokens - cachedTokens) × (cache_write_per_m - input_per_m) / 1_000_000
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Verified on a real 92-call Claude Sonnet 4.6 session: this matches the VS Code
|
|
67
|
+
AIC panel exactly ($5.9037 both ways). Models without `cache_write` (OpenAI,
|
|
68
|
+
Google) are unaffected — the delta is zero.
|
|
69
|
+
|
|
70
|
+
`agent_traces_db_paths()` in `vscode.py` locates `agent-traces.db` on all
|
|
71
|
+
platforms. When VS Code starts populating `gen_ai.usage.cache_creation.input_tokens`,
|
|
72
|
+
reading the exact value from the DB will replace this proxy without API changes.
|
|
73
|
+
:::
|
|
74
|
+
|
|
75
|
+
## AI Credits and USD
|
|
76
|
+
|
|
77
|
+
Post-2026-06-01, GitHub Copilot bills in **AI Credits (AIC)**.
|
|
78
|
+
The upstream rate card publishes prices in USD per million tokens.
|
|
79
|
+
The conversion is:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
1 AIC = $0.01 USD → 100 AIC = $1.00 USD
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
A model priced at `input: $3.00` per million tokens costs **300 AIC**
|
|
86
|
+
per million input tokens. This tool reports USD; multiply by 100 to get AIC.
|
|
87
|
+
|
|
88
|
+
The per-token AIC rate is identical across all Copilot plans. Plans differ
|
|
89
|
+
only in the monthly AIC allowance included — that allowance is not tracked
|
|
90
|
+
by this tool.
|
|
91
|
+
|
|
92
|
+
## Cache discounts
|
|
93
|
+
|
|
94
|
+
All providers discount tokens served from their prompt cache:
|
|
95
|
+
|
|
96
|
+
| Provider | Cache-read discount vs. input |
|
|
97
|
+
|----------|-------------------------------|
|
|
98
|
+
| OpenAI | ~10× cheaper |
|
|
99
|
+
| Anthropic | ~10× cheaper |
|
|
100
|
+
| Google | ~10× cheaper |
|
|
101
|
+
|
|
102
|
+
A session with 85% cache hit ratio costs significantly less than raw
|
|
103
|
+
token counts suggest.
|
|
104
|
+
|
|
105
|
+
## Long-context tier switching
|
|
106
|
+
|
|
107
|
+
Some models have two pricing tiers based on input token count:
|
|
108
|
+
|
|
109
|
+
| Model | Threshold | Effect |
|
|
110
|
+
|-------|-----------|--------|
|
|
111
|
+
| GPT-5.4 | > 272K tokens | Input/cached/output prices double |
|
|
112
|
+
| GPT-5.5 | > 272K tokens | Input/cached/output prices double |
|
|
113
|
+
| Gemini 3.1 Pro | > 200K tokens | Input/cached/output prices increase |
|
|
114
|
+
|
|
115
|
+
`copilot-session-usage` selects the correct tier automatically based on
|
|
116
|
+
the session's total input tokens per model.
|
|
117
|
+
|
|
118
|
+
## Custom pricing
|
|
119
|
+
|
|
120
|
+
Override any model's price by editing
|
|
121
|
+
`src/copilot_session_usage/data/custom-models-pricing.yml`. Entries in
|
|
122
|
+
this file take precedence over the main table.
|
{copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/_schema/Base.schema.yaml
RENAMED
|
@@ -23,4 +23,13 @@ properties:
|
|
|
23
23
|
description: ISO 8601 creation or last-updated timestamp.
|
|
24
24
|
type: string
|
|
25
25
|
format: date-time
|
|
26
|
-
|
|
26
|
+
links:
|
|
27
|
+
type: array
|
|
28
|
+
items:
|
|
29
|
+
type: string
|
|
30
|
+
description: "Bundle-relative paths this concept links to"
|
|
31
|
+
backlinks:
|
|
32
|
+
type: array
|
|
33
|
+
items:
|
|
34
|
+
type: string
|
|
35
|
+
description: "Bundle-relative paths of concepts that link to this one"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
$schema: "http://json-schema.org/draft-07/schema#"
|
|
2
|
+
title: Experiment
|
|
3
|
+
description: >-
|
|
4
|
+
A reusable, prepared procedure that can be executed one or two times to test a
|
|
5
|
+
hypothesis. Each execution produces one Finding. The Experiment is a template;
|
|
6
|
+
its recorded outcomes live as Finding documents.
|
|
7
|
+
allOf:
|
|
8
|
+
- $ref: "Base.schema.yaml"
|
|
9
|
+
- type: object
|
|
10
|
+
properties:
|
|
11
|
+
type:
|
|
12
|
+
description: Document type — must be "Experiment".
|
|
13
|
+
type: string
|
|
14
|
+
const: Experiment
|
|
15
|
+
hypothesis:
|
|
16
|
+
description: The claim the experiment is designed to confirm or falsify.
|
|
17
|
+
type: string
|
|
18
|
+
minLength: 1
|
|
19
|
+
steps:
|
|
20
|
+
description: Ordered procedure to run the experiment reproducibly.
|
|
21
|
+
type: array
|
|
22
|
+
items: { type: string }
|
|
23
|
+
minItems: 1
|
|
24
|
+
expected_signals:
|
|
25
|
+
description: Observable signals that indicate the hypothesis holds or fails.
|
|
26
|
+
type: array
|
|
27
|
+
items: { type: string }
|
|
28
|
+
max_runs:
|
|
29
|
+
description: How many times this experiment is meant to be run (typically 1–2).
|
|
30
|
+
type: integer
|
|
31
|
+
minimum: 1
|
|
32
|
+
status:
|
|
33
|
+
description: Lifecycle state of the experiment template.
|
|
34
|
+
type: string
|
|
35
|
+
enum: [proposed, active, retired, superseded]
|
|
36
|
+
derived_findings:
|
|
37
|
+
description: IDs of Findings produced by running this experiment.
|
|
38
|
+
type: array
|
|
39
|
+
items: { type: string }
|
|
40
|
+
superseded_by:
|
|
41
|
+
description: IDs of documents that supersede this experiment.
|
|
42
|
+
type: array
|
|
43
|
+
items: { type: string }
|
|
44
|
+
required: [type, hypothesis, steps]
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
$schema: "http://json-schema.org/draft-07/schema#"
|
|
2
|
+
title: Finding
|
|
3
|
+
description: >-
|
|
4
|
+
An empirical, dated, falsifiable record of what an agent or human truthfully
|
|
5
|
+
observed and believed at a point in time. The body is immutable once written;
|
|
6
|
+
only lifecycle frontmatter (status, contradicted_by, superseded_by) may be
|
|
7
|
+
appended later.
|
|
8
|
+
allOf:
|
|
9
|
+
- $ref: "Base.schema.yaml"
|
|
10
|
+
- type: object
|
|
11
|
+
properties:
|
|
12
|
+
type:
|
|
13
|
+
description: Document type — must be "Finding".
|
|
14
|
+
type: string
|
|
15
|
+
const: Finding
|
|
16
|
+
confidence:
|
|
17
|
+
description: How confident the reporter was at the time of recording.
|
|
18
|
+
type: string
|
|
19
|
+
enum: [low, medium, high, confirmed]
|
|
20
|
+
context:
|
|
21
|
+
description: >-
|
|
22
|
+
What the reporter believed and the situation at the time — the honest
|
|
23
|
+
basis for the finding, including assumptions that may later prove wrong.
|
|
24
|
+
type: string
|
|
25
|
+
minLength: 1
|
|
26
|
+
status:
|
|
27
|
+
description: Lifecycle state. Appended non-destructively; the body never changes.
|
|
28
|
+
type: string
|
|
29
|
+
enum: [active, contradicted, superseded]
|
|
30
|
+
derived_from:
|
|
31
|
+
description: ID of the Experiment whose run produced this finding, if any.
|
|
32
|
+
type: string
|
|
33
|
+
contradicts:
|
|
34
|
+
description: IDs of earlier Findings this finding contradicts.
|
|
35
|
+
type: array
|
|
36
|
+
items: { type: string }
|
|
37
|
+
supersedes:
|
|
38
|
+
description: IDs of earlier Findings this finding replaces.
|
|
39
|
+
type: array
|
|
40
|
+
items: { type: string }
|
|
41
|
+
contradicted_by:
|
|
42
|
+
description: IDs of later Findings that contradict this one (appended by review).
|
|
43
|
+
type: array
|
|
44
|
+
items: { type: string }
|
|
45
|
+
superseded_by:
|
|
46
|
+
description: IDs of later Findings that replace this one (appended by review).
|
|
47
|
+
type: array
|
|
48
|
+
items: { type: string }
|
|
49
|
+
required: [type, timestamp, confidence, context]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
$schema: "http://json-schema.org/draft-07/schema#"
|
|
2
|
+
title: Principle
|
|
3
|
+
description: >-
|
|
4
|
+
A standard or convention, usually defined with humans. Principles are stable,
|
|
5
|
+
normative statements ("we always…", "never…") — not dated observations. They
|
|
6
|
+
may be supported by Findings but are agreed, not merely observed.
|
|
7
|
+
allOf:
|
|
8
|
+
- $ref: "Base.schema.yaml"
|
|
9
|
+
- type: object
|
|
10
|
+
properties:
|
|
11
|
+
type:
|
|
12
|
+
description: Document type — must be "Principle".
|
|
13
|
+
type: string
|
|
14
|
+
const: Principle
|
|
15
|
+
rationale:
|
|
16
|
+
description: Why this principle exists and what it protects against.
|
|
17
|
+
type: string
|
|
18
|
+
authority:
|
|
19
|
+
description: Who agreed this principle (e.g. "team", "human-reviewed").
|
|
20
|
+
type: string
|
|
21
|
+
supported_by:
|
|
22
|
+
description: IDs of Findings that provide empirical support for this principle.
|
|
23
|
+
type: array
|
|
24
|
+
items: { type: string }
|
|
25
|
+
required: [type]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
$schema: "http://json-schema.org/draft-07/schema#"
|
|
2
|
+
title: Structure
|
|
3
|
+
description: >-
|
|
4
|
+
A description of how an object, system, or artifact is composed and how its
|
|
5
|
+
parts relate — the "how it works" view. Distinct from a Concept (an idea) and
|
|
6
|
+
from a Playbook (a procedure to perform).
|
|
7
|
+
allOf:
|
|
8
|
+
- $ref: "Base.schema.yaml"
|
|
9
|
+
- type: object
|
|
10
|
+
properties:
|
|
11
|
+
type:
|
|
12
|
+
description: Document type — must be "Structure".
|
|
13
|
+
type: string
|
|
14
|
+
const: Structure
|
|
15
|
+
subject:
|
|
16
|
+
description: The object or system whose structure is described.
|
|
17
|
+
type: string
|
|
18
|
+
parts:
|
|
19
|
+
description: The components, fields, or sub-parts that make up the subject.
|
|
20
|
+
type: array
|
|
21
|
+
items: { type: string }
|
|
22
|
+
related_concepts:
|
|
23
|
+
description: IDs of Concept documents that explain the ideas behind this structure.
|
|
24
|
+
type: array
|
|
25
|
+
items: { type: string }
|
|
26
|
+
required: [type]
|
|
@@ -19,9 +19,9 @@ Every LLM request made by a coding agent (parent or subagent) is logged as a str
|
|
|
19
19
|
|
|
20
20
|
| Metric | Source Field | Description |
|
|
21
21
|
|--------|-------------|-------------|
|
|
22
|
-
| Input Tokens | `attrs.inputTokens` |
|
|
22
|
+
| Input Tokens | `attrs.inputTokens` | **Total** prompt tokens sent (cached + non-cached) |
|
|
23
23
|
| Output Tokens | `attrs.outputTokens` | Tokens generated by the model |
|
|
24
|
-
| Cached Tokens | `attrs.cachedTokens` |
|
|
24
|
+
| Cached Tokens | `attrs.cachedTokens` | Subset of input tokens served from the provider's prompt cache (billed at a lower rate) |
|
|
25
25
|
| LLM Calls | Count of `llm_request` events | Number of individual model invocations |
|
|
26
26
|
| Model | `attrs.model` | Which model handled the request |
|
|
27
27
|
|
|
@@ -6,7 +6,7 @@ description: Process of extracting token usage metrics from Copilot debug logs
|
|
|
6
6
|
tags: [cost-analysis, tokens, pricing, debug-logs]
|
|
7
7
|
timestamp: 2026-06-30T22:00:00Z
|
|
8
8
|
links: []
|
|
9
|
-
backlinks: []
|
|
9
|
+
backlinks: [structures/cache-cost-approximation.md]
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Session Cost Analysis
|
|
@@ -18,7 +18,8 @@ steps: [Pick a session directory that contains at least one runSubagent-*.jsonl
|
|
|
18
18
|
expected_signals: ['Tool total equals independent sum (no double-count, no omission).',
|
|
19
19
|
Each subagent subtotal is attributed to its own runSubagent id.]
|
|
20
20
|
max_runs: 2
|
|
21
|
-
status:
|
|
21
|
+
status: superseded
|
|
22
|
+
superseded_by: [structures/subagent-cost-tracking.md]
|
|
22
23
|
links: []
|
|
23
24
|
backlinks: []
|
|
24
25
|
---
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Finding
|
|
3
|
+
title: "cache_write approximated via fresh_input — matches AIC panel exactly"
|
|
4
|
+
description: >
|
|
5
|
+
VS Code JSONL logs and agent-traces.db both lack cache_creation token counts.
|
|
6
|
+
Approximating cache_creation as fresh_input = inputTokens - cachedTokens and
|
|
7
|
+
billing only the incremental delta (cache_write - input) / 1M produces an exact
|
|
8
|
+
match to the VS Code AIC panel. Implemented in estimate_cost since v0.3.
|
|
9
|
+
tags: [cache-write, anthropic, aic, approximation, verified, implemented]
|
|
10
|
+
confidence: confirmed
|
|
11
|
+
context: >-
|
|
12
|
+
Verified by comparing copilot-session-usage output against the VS Code AIC
|
|
13
|
+
panel for multiple sessions. The approximation holds exactly when cache_write
|
|
14
|
+
is computed as fresh_input = inputTokens - cachedTokens.
|
|
15
|
+
timestamp: 2026-07-02T23:00:00Z
|
|
16
|
+
links: []
|
|
17
|
+
backlinks: [structures/cache-cost-approximation.md]
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Finding: cache_write approximated via fresh_input — now implemented
|
|
21
|
+
|
|
22
|
+
## Background
|
|
23
|
+
|
|
24
|
+
VS Code JSONL debug logs do not expose `cacheCreationTokens`. The OTel SQLite
|
|
25
|
+
store (`agent-traces.db`) has the schema column
|
|
26
|
+
`gen_ai.usage.cache_creation.input_tokens` but VS Code does not populate it for
|
|
27
|
+
Claude models (verified: 0 rows on VS Code 1.103+).
|
|
28
|
+
|
|
29
|
+
## The correct approximation
|
|
30
|
+
|
|
31
|
+
The key insight is that the current code already bills fresh input at `input_per_m`.
|
|
32
|
+
The incremental cost of cache creation is only the **difference**:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
delta = fresh_input × (cache_write_per_m − input_per_m) / 1_000_000
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
where `fresh_input = inputTokens − cachedTokens`.
|
|
39
|
+
|
|
40
|
+
## Verification on session 438d24a8 (Claude Sonnet 4.6, 92 calls)
|
|
41
|
+
|
|
42
|
+
| Metric | Value |
|
|
43
|
+
|--------|-------|
|
|
44
|
+
| Fresh input | 720,122 tokens |
|
|
45
|
+
| Delta formula: 720K × ($3.75 − $3.00)/M | **$0.5401** |
|
|
46
|
+
| Old tool cost (without delta) | $5.3636 |
|
|
47
|
+
| New tool cost (with delta) | $5.9037 |
|
|
48
|
+
| VS Code panel (590.37 AIC ÷ 100) | **$5.9037** |
|
|
49
|
+
|
|
50
|
+
Exact match.
|
|
51
|
+
|
|
52
|
+
Note: an earlier version of this finding incorrectly computed
|
|
53
|
+
`720K × $3.75/M = $2.70` (the full rate, not the incremental delta),
|
|
54
|
+
concluding a "5× overestimate". That calculation was wrong; the delta
|
|
55
|
+
formula gives the correct $0.54 increment.
|
|
56
|
+
|
|
57
|
+
## OTel DB fallback
|
|
58
|
+
|
|
59
|
+
`vscode.agent_traces_db_paths()` discovers all existing `agent-traces.db` paths
|
|
60
|
+
across Code / Code - Insiders on every platform. When VS Code eventually populates
|
|
61
|
+
`gen_ai.usage.cache_creation.input_tokens`, reading the exact value from the DB
|
|
62
|
+
will replace the proxy. The DB is not required for current operation.
|
|
63
|
+
|
|
64
|
+
## Implication
|
|
65
|
+
|
|
66
|
+
For Anthropic-heavy sessions, `copilot-session-usage` now closely matches the
|
|
67
|
+
VS Code AIC panel. The approximation is accurate when the full context prefix is
|
|
68
|
+
cached (typical for long Copilot sessions). Sessions that do not cache (very short
|
|
69
|
+
contexts, no system prompt) may over-count by at most `fresh_input × delta_rate`.
|
|
70
|
+
|
|
71
|
+
## Follow-up fix: model_breakdown now uses nano_aiu (2026-07-03)
|
|
72
|
+
|
|
73
|
+
The `model_breakdown` (per-model cost table) previously used `estimate_cost`
|
|
74
|
+
(token-based) on `global_per_model`, which did not accumulate `nano_aiu`.
|
|
75
|
+
This created a minor inconsistency: the session total used nano_aiu while the
|
|
76
|
+
per-model breakdown used token-based pricing (difference ~$0.0002 for session
|
|
77
|
+
438d24a8 = 0.001% error, well within tolerance).
|
|
78
|
+
|
|
79
|
+
Fix: `global_per_model` now accumulates `nano_aiu` from each file's per-model
|
|
80
|
+
bucket, and `model_breakdown` calls `estimate_cost_for_file({model: v}, pricing)`
|
|
81
|
+
instead of `estimate_cost(...)`. Both session total and per-model breakdown now
|
|
82
|
+
use the same nano_aiu-first logic. Verified: model_breakdown sum = $14.709213
|
|
83
|
+
matches session total $14.7092 (rounding only).
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Finding
|
|
2
|
+
|
|
3
|
+
An empirical, dated, falsifiable record of what an agent or human truthfully observed and believed at a point in time. The body is immutable once written; only lifecycle frontmatter (status, contradicted_by, superseded_by) may be appended later.
|
|
4
|
+
|
|
5
|
+
- [cache_write approximated via fresh_input — matches AIC panel exactly](cache-write-cost-not-tracked.md) — VS Code JSONL logs and agent-traces.db both lack cache_creation token counts. Approximating cache_creation as fresh_input = inputTokens - cachedTokens and billing only the incremental delta (cache_write - input) / 1M produces an exact match to the VS Code AIC panel. Implemented in estimate_cost since v0.3. [Finding]
|
|
6
|
+
- [Subagent Logs Use runSubagent Prefix](subagent-logs-use-runsubagent-prefix.md) — Subagent activity is recorded in separate JSONL files prefixed with "runSubagent-" inside the session debug-logs directory. [Finding]
|
|
7
|
+
- [title-*.jsonl adds 1 LLM call and its tokens to tool totals; VS Code panel excludes it](title-jsonl-not-counted-as-model-turn.md) — The VS Code Agent Debug panel "Model Turns" counter excludes title-generation calls. copilot-session-usage counts them. The delta is exactly the title-*.jsonl file's token counts. [Finding]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Finding
|
|
3
|
+
title: "title-*.jsonl adds 1 LLM call and its tokens to tool totals; VS Code panel
|
|
4
|
+
excludes it"
|
|
5
|
+
description: The VS Code Agent Debug panel "Model Turns" counter excludes
|
|
6
|
+
title-generation calls. copilot-session-usage counts them. The delta is
|
|
7
|
+
exactly the title-*.jsonl file's token counts.
|
|
8
|
+
tags: [token-counting, title-generation, panel-vs-tool, verified]
|
|
9
|
+
confidence: confirmed
|
|
10
|
+
context: >-
|
|
11
|
+
Observed by comparing VS Code Agent Debug panel metrics against
|
|
12
|
+
copilot-session-usage output for session 438d24a8. The delta in turns,
|
|
13
|
+
input tokens, and output tokens matched exactly the title-generation
|
|
14
|
+
JSONL file.
|
|
15
|
+
timestamp: 2026-07-02T22:00:00Z
|
|
16
|
+
links: []
|
|
17
|
+
backlinks: [structures/subagent-cost-tracking.md,
|
|
18
|
+
structures/vscode-copilot-extension.md]
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# Finding: title-*.jsonl not counted as "Model Turn" by VS Code panel
|
|
22
|
+
|
|
23
|
+
## Observed
|
|
24
|
+
|
|
25
|
+
Session `438d24a8` at the same snapshot:
|
|
26
|
+
|
|
27
|
+
| Metric | VS Code panel | copilot-session-usage | Delta |
|
|
28
|
+
|--------|---------------|-----------------------|-------|
|
|
29
|
+
| Turns/calls | 96 | 97 | +1 |
|
|
30
|
+
| Input tokens | 8,831,919 | 8,832,360 | +441 |
|
|
31
|
+
| Output tokens | 58,784 | 60,029 | +1,245 |
|
|
32
|
+
| Cached tokens | 8,097,846 | 8,097,846 | 0 |
|
|
33
|
+
|
|
34
|
+
The delta matches exactly the `title-ca686498-...jsonl` file:
|
|
35
|
+
`model=Kimi-K2.6-azure input=441 cached=0 output=1,245`
|
|
36
|
+
|
|
37
|
+
## Explanation
|
|
38
|
+
|
|
39
|
+
VS Code "Model Turns" counts only the main conversation turns.
|
|
40
|
+
The title-generation call (one `llm_request` in `title-*.jsonl`) is a
|
|
41
|
+
background call VS Code excludes from the panel display.
|
|
42
|
+
|
|
43
|
+
`copilot-session-usage` counts **all** `llm_request` events across all
|
|
44
|
+
`*.jsonl` files in the session directory, including `title-*.jsonl`.
|
|
45
|
+
|
|
46
|
+
## Implication
|
|
47
|
+
|
|
48
|
+
The tool over-counts by 1 call and the title call's tokens vs. the panel.
|
|
49
|
+
This is intentional: title-generation consumes real tokens and should be
|
|
50
|
+
included in cost tracking.
|
{copilot_session_usage-0.2.1 → copilot_session_usage-0.2.2}/knowledge/reference/debug-log-format.md
RENAMED
|
@@ -56,9 +56,10 @@ This is the only event type that contains cost information. All other events (`s
|
|
|
56
56
|
| Field | Type | Meaning |
|
|
57
57
|
|-------|------|---------|
|
|
58
58
|
| `attrs.model` | string | Model identifier (e.g., `Kimi-K2.6-azure`, `gpt-4o`) |
|
|
59
|
-
| `attrs.inputTokens` | integer |
|
|
59
|
+
| `attrs.inputTokens` | integer | **Total** prompt tokens sent — cached and non-cached combined |
|
|
60
60
|
| `attrs.outputTokens` | integer | Tokens generated |
|
|
61
|
-
| `attrs.cachedTokens` | integer |
|
|
61
|
+
| `attrs.cachedTokens` | integer | Subset of `inputTokens` served from the provider's prompt cache (billed at the lower `cached_input` rate) |
|
|
62
|
+
| `attrs.copilotUsageNanoAiu` | integer | VS Code's own AIC cost for this call in nano-units (÷ 1e9 = AIC, ÷ 1e11 = USD). Present for all Copilot-plan models (Claude, GPT, etc.). Absent for Azure-hosted models not billed via Copilot AIC (e.g. `Kimi-K2.6-azure`). |
|
|
62
63
|
| `attrs.ttft` | integer | Time to first token (ms) |
|
|
63
64
|
|
|
64
65
|
> **Mixed-model sessions:** A single `.jsonl` file can contain `llm_request` events from
|