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.
- deepseek_harness_usage-0.1.0/.github/workflows/publish.yml +29 -0
- deepseek_harness_usage-0.1.0/.gitignore +6 -0
- deepseek_harness_usage-0.1.0/PKG-INFO +189 -0
- deepseek_harness_usage-0.1.0/README.md +179 -0
- deepseek_harness_usage-0.1.0/dist/.gitignore +4 -0
- deepseek_harness_usage-0.1.0/pyproject.toml +23 -0
- deepseek_harness_usage-0.1.0/src/deepseek_harness_usage/__init__.py +936 -0
- deepseek_harness_usage-0.1.0/src/deepseek_harness_usage/__main__.py +3 -0
- deepseek_harness_usage-0.1.0/tests/test_deepseek_harness_usage.py +619 -0
- deepseek_harness_usage-0.1.0/uv.lock +60 -0
|
@@ -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,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,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"
|