deepseek-harness-usage 0.1.0__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.
@@ -0,0 +1,29 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ publish:
10
+ runs-on: ubuntu-latest
11
+ environment: pypi
12
+ permissions:
13
+ contents: read
14
+ id-token: write
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@v7.0.1
18
+ - name: Install uv
19
+ uses: astral-sh/setup-uv@v9.0.0
20
+ with:
21
+ enable-cache: false
22
+ - name: Verify version tag
23
+ run: test "$GITHUB_REF_NAME" = "v$(uv --no-config version --short)"
24
+ - name: Test
25
+ run: uv --no-config run --locked python -m unittest discover -s tests
26
+ - name: Build
27
+ run: uv --no-config build --no-sources
28
+ - name: Publish
29
+ run: uv publish --trusted-publishing always
@@ -0,0 +1,6 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.py[cod]
4
+ .ruff_cache/
5
+ dist/*
6
+ !dist/.gitignore
@@ -0,0 +1,189 @@
1
+ Metadata-Version: 2.5
2
+ Name: deepseek-harness-usage
3
+ Version: 0.1.0
4
+ Summary: DeepSeek Harness account balance monitor for official DeepSeek API accounts
5
+ Project-URL: Homepage, https://github.com/wakamex/deepseek-harness-usage
6
+ Project-URL: Source, https://github.com/wakamex/deepseek-harness-usage
7
+ Requires-Python: >=3.12
8
+ Requires-Dist: pyyaml>=6.0.3
9
+ Description-Content-Type: text/markdown
10
+
11
+ # deepseek-harness-usage
12
+
13
+ DeepSeek Harness account balance monitor. It follows the same usage-tool
14
+ interface as the other `/code/*usage` packages, but reports the allowance
15
+ DeepSeek actually exposes for API accounts: current prepaid balance and API
16
+ availability.
17
+
18
+ It does not estimate account usage from local Harness sessions.
19
+
20
+ ## Example output
21
+
22
+ These values are synthetic.
23
+
24
+ ```text
25
+ DeepSeek Harness balance
26
+ Status: live
27
+ API access: available
28
+ USD: 123.45 total (23.45 granted + 100.00 topped up)
29
+ ```
30
+
31
+ Statusline:
32
+
33
+ ```text
34
+ dsh:bal:USD123.45
35
+ ```
36
+
37
+ ## Install
38
+
39
+ ```bash
40
+ uv tool install deepseek-harness-usage
41
+ ```
42
+
43
+ For local development:
44
+
45
+ ```bash
46
+ uv tool install .
47
+ ```
48
+
49
+ ## Commands
50
+
51
+ | Command | Description |
52
+ | --- | --- |
53
+ | `deepseek-harness-usage` | Show a live account balance |
54
+ | `deepseek-harness-usage status` | Same as above |
55
+ | `deepseek-harness-usage json` | Print normalized live JSON |
56
+ | `deepseek-harness-usage statusline` | Print compact cache-first output |
57
+ | `deepseek-harness-usage refresh` | Refresh the cache and print the balance |
58
+ | `deepseek-harness-usage daemon [-i SECS]` | Keep the cache fresh |
59
+ | `deepseek-harness-usage install` | Print installation instructions |
60
+
61
+ Options:
62
+
63
+ - `--max-age SECS` sets the statusline cache lifetime. The default is 300.
64
+ - `--refresh` bypasses a fresh statusline cache.
65
+ - `-i SECS` sets the daemon refresh interval. The default is 300.
66
+
67
+ ## Data source
68
+
69
+ The tool calls DeepSeek's supported
70
+ [`GET /user/balance`](https://api-docs.deepseek.com/api/get-user-balance)
71
+ endpoint. The response supplies API availability and total, granted, and
72
+ topped-up balances per currency. Monetary values stay decimal strings from the
73
+ provider and are never converted through binary floating point.
74
+
75
+ DeepSeek does not document an API for aggregate token history, amount spent,
76
+ per-key usage, quota percentages, or reset windows. Its API is billed by token
77
+ usage against account balance, and concurrency limits are not a consumable
78
+ quota. The package therefore reports balance without inventing a percentage or
79
+ reset time.
80
+
81
+ ## Authentication
82
+
83
+ Every live request rereads the key. A dedicated
84
+ `DEEPSEEK_HARNESS_USAGE_API_KEY` is the highest-priority source and explicitly
85
+ identifies a key for the official DeepSeek account. Without it, the tool uses
86
+ the default DeepSeek Harness credential order:
87
+
88
+ 1. The inherited process environment.
89
+ 2. `$DSH_HOME/.credentials.yaml`.
90
+ 3. The invoking directory's `.env`.
91
+ 4. `$DSH_HOME/.env`.
92
+
93
+ `DSH_HOME` defaults to `~/.dsh`. The tool never refreshes, rotates, rewrites,
94
+ prints, or caches the key. It sends the key only to the fixed HTTPS balance
95
+ endpoint at `api.deepseek.com`, and rejects redirects before the authorization
96
+ header can be forwarded. Like Harness, it refuses a managed credential file
97
+ that is readable by group or other users. It parses and validates the complete
98
+ YAML document, so an invalid sibling entry cannot be silently ignored.
99
+
100
+ A Harness deployment that configures a different credential reference or a
101
+ custom credential-provider path cannot be discovered through the current CLI.
102
+ Set `DEEPSEEK_HARNESS_USAGE_API_KEY` to the official DeepSeek account key when
103
+ running this tool.
104
+
105
+ The balance endpoint accepts DeepSeek-issued API keys. If the Harness route
106
+ uses a gateway or another compatible provider, do not send that provider's key
107
+ to this tool. The package refuses custom endpoints and credential references
108
+ it can identify in the environment or Harness settings before reading the
109
+ credential. Profile-specific plugin patches are not discoverable from a
110
+ standalone invocation, so use the dedicated variable for those deployments.
111
+
112
+ ## Cache
113
+
114
+ The credential-free normalized snapshot is written atomically to
115
+ `$DSH_HOME/usage-limits.json`, or `~/.dsh/usage-limits.json` when `DSH_HOME` is
116
+ unset. `DEEPSEEK_HARNESS_USAGE_FILE` overrides that path.
117
+
118
+ The cache contains sensitive account metadata even though it contains no raw
119
+ credential. New cache files use mode `0600`, newly created parent directories
120
+ use mode `0700`, and replacement is atomic and does not follow a final cache
121
+ symlink. Do not publish or share the cache.
122
+
123
+ Freshness states are explicit:
124
+
125
+ | Status | Meaning |
126
+ | --- | --- |
127
+ | `live` | Returned by the balance API now |
128
+ | `cached` | Read from a cache younger than `--max-age` |
129
+ | `stale` | A live refresh failed, so an older valid cache was returned |
130
+ | `unavailable` | No live result or valid cache is available |
131
+
132
+ Cache entries are bound to a one-way SHA-256 fingerprint of the key that
133
+ produced them. A key rotation or per-run override cannot reuse another
134
+ account's cached balance. A failed statusline refresh records a 30-second
135
+ backoff so repeated prompts do not repeatedly wait on an unavailable service.
136
+ Refreshes use a non-blocking OS advisory lock, which is released automatically
137
+ if a writer exits or crashes.
138
+
139
+ Schema version 1 has this form:
140
+
141
+ ```json
142
+ {
143
+ "schema_version": 1,
144
+ "provider": "deepseek",
145
+ "client": "deepseek_harness",
146
+ "source": "deepseek_user_balance_api",
147
+ "retrieved_at": "2026-08-13T20:00:00+00:00",
148
+ "last_attempt_at": "2026-08-13T20:00:00+00:00",
149
+ "credential_fingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
150
+ "status": "live",
151
+ "account_balance": {
152
+ "available": true,
153
+ "balances": [
154
+ {
155
+ "currency": "USD",
156
+ "total": "123.45",
157
+ "granted": "23.45",
158
+ "topped_up": "100.00"
159
+ }
160
+ ]
161
+ }
162
+ }
163
+ ```
164
+
165
+ ## Reliability boundary
166
+
167
+ Balance is account-wide and authoritative for the account behind the API key.
168
+ It can change because of other clients, other keys, top-ups, or grant expiry.
169
+ Those changes make balance deltas unsuitable as exact spend history.
170
+
171
+ Harness does persist provider-reported tokens for ordinary assistant calls, but
172
+ that is not a complete billing ledger. Existing projections can omit retried
173
+ attempts, compaction, session-title calls, disconnected calls, and every use of
174
+ the key outside that Harness installation. Summing those records would produce
175
+ a precise-looking but incomplete account total.
176
+
177
+ A future local breakdown should be a separate Harness plugin wrapping the
178
+ documented `llm/stream` waterfall and recording each returned usage chunk
179
+ before forwarding it. That would reliably cover instrumented Harness calls
180
+ going forward, but it would still be local accounting rather than account-wide
181
+ usage.
182
+
183
+ ## Development
184
+
185
+ ```bash
186
+ uv --no-config lock --check
187
+ uv --no-config run --locked python -m unittest discover -s tests
188
+ uv --no-config build --no-sources
189
+ ```
@@ -0,0 +1,179 @@
1
+ # deepseek-harness-usage
2
+
3
+ DeepSeek Harness account balance monitor. It follows the same usage-tool
4
+ interface as the other `/code/*usage` packages, but reports the allowance
5
+ DeepSeek actually exposes for API accounts: current prepaid balance and API
6
+ availability.
7
+
8
+ It does not estimate account usage from local Harness sessions.
9
+
10
+ ## Example output
11
+
12
+ These values are synthetic.
13
+
14
+ ```text
15
+ DeepSeek Harness balance
16
+ Status: live
17
+ API access: available
18
+ USD: 123.45 total (23.45 granted + 100.00 topped up)
19
+ ```
20
+
21
+ Statusline:
22
+
23
+ ```text
24
+ dsh:bal:USD123.45
25
+ ```
26
+
27
+ ## Install
28
+
29
+ ```bash
30
+ uv tool install deepseek-harness-usage
31
+ ```
32
+
33
+ For local development:
34
+
35
+ ```bash
36
+ uv tool install .
37
+ ```
38
+
39
+ ## Commands
40
+
41
+ | Command | Description |
42
+ | --- | --- |
43
+ | `deepseek-harness-usage` | Show a live account balance |
44
+ | `deepseek-harness-usage status` | Same as above |
45
+ | `deepseek-harness-usage json` | Print normalized live JSON |
46
+ | `deepseek-harness-usage statusline` | Print compact cache-first output |
47
+ | `deepseek-harness-usage refresh` | Refresh the cache and print the balance |
48
+ | `deepseek-harness-usage daemon [-i SECS]` | Keep the cache fresh |
49
+ | `deepseek-harness-usage install` | Print installation instructions |
50
+
51
+ Options:
52
+
53
+ - `--max-age SECS` sets the statusline cache lifetime. The default is 300.
54
+ - `--refresh` bypasses a fresh statusline cache.
55
+ - `-i SECS` sets the daemon refresh interval. The default is 300.
56
+
57
+ ## Data source
58
+
59
+ The tool calls DeepSeek's supported
60
+ [`GET /user/balance`](https://api-docs.deepseek.com/api/get-user-balance)
61
+ endpoint. The response supplies API availability and total, granted, and
62
+ topped-up balances per currency. Monetary values stay decimal strings from the
63
+ provider and are never converted through binary floating point.
64
+
65
+ DeepSeek does not document an API for aggregate token history, amount spent,
66
+ per-key usage, quota percentages, or reset windows. Its API is billed by token
67
+ usage against account balance, and concurrency limits are not a consumable
68
+ quota. The package therefore reports balance without inventing a percentage or
69
+ reset time.
70
+
71
+ ## Authentication
72
+
73
+ Every live request rereads the key. A dedicated
74
+ `DEEPSEEK_HARNESS_USAGE_API_KEY` is the highest-priority source and explicitly
75
+ identifies a key for the official DeepSeek account. Without it, the tool uses
76
+ the default DeepSeek Harness credential order:
77
+
78
+ 1. The inherited process environment.
79
+ 2. `$DSH_HOME/.credentials.yaml`.
80
+ 3. The invoking directory's `.env`.
81
+ 4. `$DSH_HOME/.env`.
82
+
83
+ `DSH_HOME` defaults to `~/.dsh`. The tool never refreshes, rotates, rewrites,
84
+ prints, or caches the key. It sends the key only to the fixed HTTPS balance
85
+ endpoint at `api.deepseek.com`, and rejects redirects before the authorization
86
+ header can be forwarded. Like Harness, it refuses a managed credential file
87
+ that is readable by group or other users. It parses and validates the complete
88
+ YAML document, so an invalid sibling entry cannot be silently ignored.
89
+
90
+ A Harness deployment that configures a different credential reference or a
91
+ custom credential-provider path cannot be discovered through the current CLI.
92
+ Set `DEEPSEEK_HARNESS_USAGE_API_KEY` to the official DeepSeek account key when
93
+ running this tool.
94
+
95
+ The balance endpoint accepts DeepSeek-issued API keys. If the Harness route
96
+ uses a gateway or another compatible provider, do not send that provider's key
97
+ to this tool. The package refuses custom endpoints and credential references
98
+ it can identify in the environment or Harness settings before reading the
99
+ credential. Profile-specific plugin patches are not discoverable from a
100
+ standalone invocation, so use the dedicated variable for those deployments.
101
+
102
+ ## Cache
103
+
104
+ The credential-free normalized snapshot is written atomically to
105
+ `$DSH_HOME/usage-limits.json`, or `~/.dsh/usage-limits.json` when `DSH_HOME` is
106
+ unset. `DEEPSEEK_HARNESS_USAGE_FILE` overrides that path.
107
+
108
+ The cache contains sensitive account metadata even though it contains no raw
109
+ credential. New cache files use mode `0600`, newly created parent directories
110
+ use mode `0700`, and replacement is atomic and does not follow a final cache
111
+ symlink. Do not publish or share the cache.
112
+
113
+ Freshness states are explicit:
114
+
115
+ | Status | Meaning |
116
+ | --- | --- |
117
+ | `live` | Returned by the balance API now |
118
+ | `cached` | Read from a cache younger than `--max-age` |
119
+ | `stale` | A live refresh failed, so an older valid cache was returned |
120
+ | `unavailable` | No live result or valid cache is available |
121
+
122
+ Cache entries are bound to a one-way SHA-256 fingerprint of the key that
123
+ produced them. A key rotation or per-run override cannot reuse another
124
+ account's cached balance. A failed statusline refresh records a 30-second
125
+ backoff so repeated prompts do not repeatedly wait on an unavailable service.
126
+ Refreshes use a non-blocking OS advisory lock, which is released automatically
127
+ if a writer exits or crashes.
128
+
129
+ Schema version 1 has this form:
130
+
131
+ ```json
132
+ {
133
+ "schema_version": 1,
134
+ "provider": "deepseek",
135
+ "client": "deepseek_harness",
136
+ "source": "deepseek_user_balance_api",
137
+ "retrieved_at": "2026-08-13T20:00:00+00:00",
138
+ "last_attempt_at": "2026-08-13T20:00:00+00:00",
139
+ "credential_fingerprint": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
140
+ "status": "live",
141
+ "account_balance": {
142
+ "available": true,
143
+ "balances": [
144
+ {
145
+ "currency": "USD",
146
+ "total": "123.45",
147
+ "granted": "23.45",
148
+ "topped_up": "100.00"
149
+ }
150
+ ]
151
+ }
152
+ }
153
+ ```
154
+
155
+ ## Reliability boundary
156
+
157
+ Balance is account-wide and authoritative for the account behind the API key.
158
+ It can change because of other clients, other keys, top-ups, or grant expiry.
159
+ Those changes make balance deltas unsuitable as exact spend history.
160
+
161
+ Harness does persist provider-reported tokens for ordinary assistant calls, but
162
+ that is not a complete billing ledger. Existing projections can omit retried
163
+ attempts, compaction, session-title calls, disconnected calls, and every use of
164
+ the key outside that Harness installation. Summing those records would produce
165
+ a precise-looking but incomplete account total.
166
+
167
+ A future local breakdown should be a separate Harness plugin wrapping the
168
+ documented `llm/stream` waterfall and recording each returned usage chunk
169
+ before forwarding it. That would reliably cover instrumented Harness calls
170
+ going forward, but it would still be local accounting rather than account-wide
171
+ usage.
172
+
173
+ ## Development
174
+
175
+ ```bash
176
+ uv --no-config lock --check
177
+ uv --no-config run --locked python -m unittest discover -s tests
178
+ uv --no-config build --no-sources
179
+ ```
@@ -0,0 +1,4 @@
1
+ *
2
+ !.gitignore
3
+ *
4
+ !.gitignore
@@ -0,0 +1,23 @@
1
+ [project]
2
+ name = "deepseek-harness-usage"
3
+ version = "0.1.0"
4
+ description = "DeepSeek Harness account balance monitor for official DeepSeek API accounts"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ dependencies = [
8
+ "pyyaml>=6.0.3",
9
+ ]
10
+
11
+ [tool.uv]
12
+ package = true
13
+
14
+ [project.urls]
15
+ Homepage = "https://github.com/wakamex/deepseek-harness-usage"
16
+ Source = "https://github.com/wakamex/deepseek-harness-usage"
17
+
18
+ [project.scripts]
19
+ deepseek-harness-usage = "deepseek_harness_usage:main"
20
+
21
+ [build-system]
22
+ requires = ["hatchling"]
23
+ build-backend = "hatchling.build"