deepthonk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +293 -0
- package/dist/commands/export.d.ts +2 -0
- package/dist/commands/export.js +24 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/inspect.d.ts +2 -0
- package/dist/commands/inspect.js +38 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/mutate.d.ts +2 -0
- package/dist/commands/mutate.js +41 -0
- package/dist/commands/mutate.js.map +1 -0
- package/dist/commands/plan.d.ts +2 -0
- package/dist/commands/plan.js +25 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/rank.d.ts +2 -0
- package/dist/commands/rank.js +38 -0
- package/dist/commands/rank.js.map +1 -0
- package/dist/commands/resume.d.ts +2 -0
- package/dist/commands/resume.js +16 -0
- package/dist/commands/resume.js.map +1 -0
- package/dist/commands/run.d.ts +2 -0
- package/dist/commands/run.js +74 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/serveMcp.d.ts +2 -0
- package/dist/commands/serveMcp.js +16 -0
- package/dist/commands/serveMcp.js.map +1 -0
- package/dist/commands/setup.d.ts +2 -0
- package/dist/commands/setup.js +104 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.js +265 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Xule Lin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# DeepThonk
|
|
2
|
+
|
|
3
|
+
*thonk harder, not richer.*
|
|
4
|
+
|
|
5
|
+
DeepThonk implements the OpenDeepThink algorithm (Zhou et al., 2026, [arXiv:2605.15177](https://arxiv.org/abs/2605.15177)) as a budget-friendly, provider-neutral "deep think / pro mode" wrapper, with first-class DeepSeek support. See [Acknowledgments](#acknowledgments).
|
|
6
|
+
|
|
7
|
+
DeepThonk runs a population of candidate answers through pairwise judging, Bradley-Terry ranking, critique-guided mutation, elite preservation, and a final dense ranking pass. The CLI and MCP server both call the same TypeScript core engine.
|
|
8
|
+
|
|
9
|
+
**Designed for agents.** Every algorithm dimension — population shape (`n`, `k`, `t`, `m`), regularization (`lambda`), per-phase temperatures, prompt style, and per-phase prompt templates — is reachable inline through MCP arguments and CLI flags. No filesystem detours required. Every intermediate artifact (candidates, comparisons, scores, per-call usage, status) is exposed as a streaming MCP resource so an agent can inspect any step. See [Customization](https://github.com/linxule/deepthonk/blob/main/docs/customization.md) for the full agent-composable surface.
|
|
10
|
+
|
|
11
|
+
Use it for hard, verifiable reasoning, coding, planning, and synthesis where breadth plus judgment can beat one expensive single shot. Avoid it for highly subjective tasks where judge noise dominates.
|
|
12
|
+
|
|
13
|
+
## Quickstart
|
|
14
|
+
|
|
15
|
+
Run without installing:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx -y deepthonk plan --profile paper
|
|
19
|
+
npx -y deepthonk run --provider fake --profile quick \
|
|
20
|
+
--task "Find the smallest positive integer divisible by 3, 4, and 5." \
|
|
21
|
+
--out runs/test-quick
|
|
22
|
+
npx -y deepthonk inspect runs/test-quick
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or install globally:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install -g deepthonk
|
|
29
|
+
deepthonk plan --profile paper
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The paper profile plans 285 model calls and 8 sequential rounds. Confirm budget and provider pricing before pointing it at paid models. The short alias `dt` is installed alongside `deepthonk`. Develop from source: see [Development](#development).
|
|
33
|
+
|
|
34
|
+
> v0.1 scope: an independent TypeScript reimplementation of the OpenDeepThink algorithm as a CLI + MCP server. The published algorithm is the load-bearing part; this release is a practical integration layer with explicit limits documented below. Cost guarantees rely on provider pricing being present in config; resume only inspects trace state, it does not replay; the MCP HTTP transport is loopback-only. The included acceptance smoke uses the deterministic fake provider and a toy task — it is not a CF-73 / HLE reproduction; see `docs/` and [Acknowledgments](#acknowledgments) for the canonical paper and Python reference.
|
|
35
|
+
|
|
36
|
+
## Setup
|
|
37
|
+
|
|
38
|
+
Create a reusable local config:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
deepthonk setup \
|
|
42
|
+
--provider deepseek \
|
|
43
|
+
--api-key-env DEEPSEEK_API_KEY \
|
|
44
|
+
--fast-model deepseek-v4-flash \
|
|
45
|
+
--judge-model deepseek-v4-pro
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
By default this writes `~/.config/deepthonk/config.yaml`. `deepthonk run` loads that file automatically when `--config` is not supplied. If you pass `--api-key`, setup stores it in `~/.config/deepthonk/env`; otherwise it uses the named environment variable from your shell.
|
|
49
|
+
|
|
50
|
+
## DeepSeek
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
export DEEPSEEK_API_KEY=...
|
|
54
|
+
deepthonk run \
|
|
55
|
+
--task task.md \
|
|
56
|
+
--profile paper \
|
|
57
|
+
--provider deepseek \
|
|
58
|
+
--generator-model deepseek-v4-flash \
|
|
59
|
+
--mutator-model deepseek-v4-flash \
|
|
60
|
+
--judge-model deepseek-v4-pro \
|
|
61
|
+
--out runs/task-paper
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
DeepSeek is implemented as an OpenAI-compatible profile using `https://api.deepseek.com/v1`. DeepThonk ships default USD pricing for `deepseek-v4-flash` and `deepseek-v4-pro` from the official DeepSeek pricing page, including cache-hit/cache-miss input rates. Model names and prices are still editable config because both can change.
|
|
65
|
+
|
|
66
|
+
Before paid runs, inspect cost shape and resolved config:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
deepthonk plan --config ~/.config/deepthonk/config.yaml
|
|
70
|
+
deepthonk run --task task.md --config ~/.config/deepthonk/config.yaml --profile quick --dry-run
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Start with `--profile quick` and consider `--max-concurrency`, `--max-input-tokens`, `--max-output-tokens`, `--max-usd`, and `--request-timeout-ms` before larger paid profiles. Runtime token/USD budgets are enforced after completed provider calls and can overshoot by at most the active concurrency window. Every completed run summary includes call/token usage, and includes `usage.usd` when matching model pricing is available.
|
|
74
|
+
|
|
75
|
+
## OpenAI-Compatible Providers
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
export DEEPTHONK_API_KEY=...
|
|
79
|
+
deepthonk run \
|
|
80
|
+
--task task.md \
|
|
81
|
+
--profile balanced \
|
|
82
|
+
--provider openai-compatible \
|
|
83
|
+
--base-url https://provider.example.com/v1 \
|
|
84
|
+
--api-key-env DEEPTHONK_API_KEY \
|
|
85
|
+
--generator-model cheap-model \
|
|
86
|
+
--judge-model strong-model
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The driver calls `POST {base_url}/chat/completions` and requests JSON mode for comparisons when supported. If a provider returns a `400` with a body that mentions `response_format` or `json`, the driver retries without JSON mode and uses robust JSON extraction on the plain text response. Providers that reject JSON mode with a different status code (e.g. `422`) surface as a normal provider error — set `supportsJsonMode: false` in YAML to disable JSON mode up front.
|
|
90
|
+
|
|
91
|
+
Provider names are flexible. For a custom OpenAI-compatible endpoint, use any provider label with `--base-url`, `--api-key-env`, and role-specific model flags. For OpenRouter:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
export OPENROUTER_API_KEY=...
|
|
95
|
+
deepthonk run \
|
|
96
|
+
--task task.md \
|
|
97
|
+
--profile balanced \
|
|
98
|
+
--provider openrouter \
|
|
99
|
+
--generator-model openrouter/auto \
|
|
100
|
+
--mutator-model openrouter/auto \
|
|
101
|
+
--judge-model openrouter/auto
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
For mixed-provider runs, use YAML config and override individual roles under `providers`, especially `judge`.
|
|
105
|
+
|
|
106
|
+
Optional `finalizer_model` / `--finalizer-model` can post-process the ranked winner. Leave it unset when you want the raw ranked answer as the final artifact.
|
|
107
|
+
|
|
108
|
+
## MCP
|
|
109
|
+
|
|
110
|
+
The MCP server exposes the same engine the CLI runs. Once wired into an MCP host, the host can plan budgets, kick off background runs, poll status, fetch winners, and stream structured trace artifacts — all through MCP tools, resources, and prompts.
|
|
111
|
+
|
|
112
|
+
Provider API keys come from the host process's environment, not from DeepThonk's config alone. Each host handles env passthrough slightly differently — see the concrete patterns below.
|
|
113
|
+
|
|
114
|
+
### Claude Code
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
claude mcp add deepthonk \
|
|
118
|
+
-e DEEPSEEK_API_KEY=$DEEPSEEK_API_KEY \
|
|
119
|
+
-- npx -y deepthonk serve-mcp --transport stdio
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Use `-s user` for cross-project scope or `-s project` to commit registration into `.claude/`. Verify with `claude mcp list`. See `claude mcp --help` for the authoritative flag set.
|
|
123
|
+
|
|
124
|
+
### Claude Desktop
|
|
125
|
+
|
|
126
|
+
Config path: `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS), `%APPDATA%\Claude\claude_desktop_config.json` (Windows), `~/.config/Claude/claude_desktop_config.json` (Linux). Add:
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"mcpServers": {
|
|
131
|
+
"deepthonk": {
|
|
132
|
+
"command": "npx",
|
|
133
|
+
"args": ["-y", "deepthonk", "serve-mcp", "--transport", "stdio"],
|
|
134
|
+
"env": {
|
|
135
|
+
"DEEPSEEK_API_KEY": "sk-..."
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Restart Claude Desktop after editing.
|
|
143
|
+
|
|
144
|
+
### Cursor
|
|
145
|
+
|
|
146
|
+
Project-scoped: `.cursor/mcp.json` in the workspace. User-global: `~/.cursor/mcp.json`. Same JSON shape as Claude Desktop:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"mcpServers": {
|
|
151
|
+
"deepthonk": {
|
|
152
|
+
"command": "npx",
|
|
153
|
+
"args": ["-y", "deepthonk", "serve-mcp", "--transport", "stdio"],
|
|
154
|
+
"env": { "DEEPSEEK_API_KEY": "sk-..." }
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Other MCP hosts (stdio)
|
|
161
|
+
|
|
162
|
+
Any host that speaks MCP stdio launches:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
npx -y deepthonk serve-mcp --transport stdio
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
with the relevant provider env vars set on the process. If you'd rather install globally, `npm install -g deepthonk` then use `command: "deepthonk"` directly. Refer to the host's MCP registration docs for the configuration shape.
|
|
169
|
+
|
|
170
|
+
### Streamable HTTP
|
|
171
|
+
|
|
172
|
+
For local web hosts, or when stdio isn't available:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
deepthonk serve-mcp --transport http --port 3333
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
The server binds `127.0.0.1:3333` only (loopback) and the endpoint is `POST http://127.0.0.1:3333/mcp`. DNS rebinding protection is on (CVE-2025-66414): requests with `Host` headers outside `127.0.0.1:3333` / `localhost:3333` are rejected. Do not expose this port through a reverse proxy without re-evaluating that trust boundary.
|
|
179
|
+
|
|
180
|
+
### Tools
|
|
181
|
+
|
|
182
|
+
| Tool | Purpose |
|
|
183
|
+
|---|---|
|
|
184
|
+
| `deepthonk.plan` | Estimate calls and sequential rounds for a profile (no model calls). Use before paid runs. |
|
|
185
|
+
| `deepthonk.start` | Start a run in the background; returns `run_dir` + `job_id`. |
|
|
186
|
+
| `deepthonk.status` | Poll job status from a `run_dir`. |
|
|
187
|
+
| `deepthonk.result` | Return final summary + winner once a job is complete. |
|
|
188
|
+
| `deepthonk.cancel` | Request cancellation by writing `cancel.json` into the run directory. |
|
|
189
|
+
| `deepthonk.run` | Blocking convenience: start + await completion in one call. Prefer `start` + polling for long-running jobs. |
|
|
190
|
+
| `deepthonk.rank` | Rank a user-supplied candidate set with pairwise judging + Bradley-Terry (skip generation). |
|
|
191
|
+
| `deepthonk.mutate` | Mutate one supplied candidate with critique (one-shot). |
|
|
192
|
+
| `deepthonk.resume` | Detect whether a run can be resumed. Reports state only; does not replay yet. |
|
|
193
|
+
| `deepthonk.export` | Export run summary or full trace in JSON or markdown. |
|
|
194
|
+
|
|
195
|
+
All tools accept inline provider/model fields, or `config_path` pointing at a DeepThonk YAML config.
|
|
196
|
+
|
|
197
|
+
### Resources
|
|
198
|
+
|
|
199
|
+
- `deepthonk://runs` — JSON index of all runs in `runs/`.
|
|
200
|
+
- `deepthonk://runs/{run_id}/summary` — run summary (JSON).
|
|
201
|
+
- `deepthonk://runs/{run_id}/{candidates|comparisons|scores|trace}` — per-phase NDJSON.
|
|
202
|
+
- `deepthonk://runs/{run_id}/{winner|final}` — text artifacts.
|
|
203
|
+
- `deepthonk://runs/{run_id}/status` — run state (JSON).
|
|
204
|
+
- `deepthonk://jobs/{job_id}/{status|result}?run_dir=...` — job-scoped lookup; the `run_dir` query param is required.
|
|
205
|
+
|
|
206
|
+
### Prompts
|
|
207
|
+
|
|
208
|
+
Four templates mirror the core loop: `deepthonk/generate`, `deepthonk/compare`, `deepthonk/mutate`, `deepthonk/finalize`. Hosts can render them directly to drive the algorithm by hand without invoking the tool surface.
|
|
209
|
+
|
|
210
|
+
### Limits
|
|
211
|
+
|
|
212
|
+
MCP Sampling is deferred and not exposed as a provider mode — direct provider mode is the only option in v0.1. `deepthonk.resume` reports trace state and safe phase boundaries but does not replay interrupted runs. The HTTP transport is loopback-only by design.
|
|
213
|
+
|
|
214
|
+
## Customization
|
|
215
|
+
|
|
216
|
+
Every algorithm dimension is reachable through MCP arguments and CLI flags:
|
|
217
|
+
|
|
218
|
+
- **Population shape**: `n`, `k`, `t`, `m` — override profile defaults inline.
|
|
219
|
+
- **Algorithm constants**: `lambda`, `sample_temperature`, `mutate_temperature`, `judge_temperature`.
|
|
220
|
+
- **Prompt style**: `general` or `paper-programming`.
|
|
221
|
+
- **Per-phase prompt templates**: override `generate`, `compare`, `mutate`, or `finalize` with custom system/user templates and variable substitution (`{task}`, `{rubric}`, `{candidate}`, `{candidateA}`, `{candidateB}`, `{critique}`). Unknown variables throw a fail-fast error at run-start.
|
|
222
|
+
- **Concurrency**: per-phase caps for `generate`, `judge`, `mutate`.
|
|
223
|
+
|
|
224
|
+
Example agent call (MCP), no YAML file required:
|
|
225
|
+
|
|
226
|
+
```json
|
|
227
|
+
{
|
|
228
|
+
"task": "Draft a concise non-solicitation clause for a senior sales employee.",
|
|
229
|
+
"profile": "balanced",
|
|
230
|
+
"n": 6, "t": 1,
|
|
231
|
+
"provider": "deepseek",
|
|
232
|
+
"judge_model": "deepseek-v4-pro",
|
|
233
|
+
"prompts": {
|
|
234
|
+
"generate": { "system": "You are an experienced employment-law attorney." },
|
|
235
|
+
"compare": { "system": "Prefer enforceable clauses under California law. Return strict JSON only." }
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
CLI accepts the same surface, except prompt overrides are loaded from a YAML file via `--prompts <yaml>` (shell-quoting multi-line templates is hostile). MCP and CLI both merge over any `--config`/`config_path` YAML defaults.
|
|
241
|
+
|
|
242
|
+
See the [Customization guide](https://github.com/linxule/deepthonk/blob/main/docs/customization.md) for the complete variable contract, the compare-phase JSON safety rule, and three worked examples. Per-role provider routing (`providers.judge.provider = openrouter`) and per-model pricing remain YAML-only — they're nested structured config, not inline ergonomics.
|
|
243
|
+
|
|
244
|
+
## Trace Files
|
|
245
|
+
|
|
246
|
+
A successful run writes:
|
|
247
|
+
|
|
248
|
+
```txt
|
|
249
|
+
runs/{run_id}/
|
|
250
|
+
config.json
|
|
251
|
+
events.jsonl
|
|
252
|
+
candidates.jsonl
|
|
253
|
+
comparisons.jsonl
|
|
254
|
+
scores.jsonl
|
|
255
|
+
usage.jsonl
|
|
256
|
+
summary.json
|
|
257
|
+
artifacts/winner.txt
|
|
258
|
+
artifacts/final.txt
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
`status.json` is written when the run is launched through MCP `deepthonk.start` (so async clients can poll). `cancel.json` is written only when cancellation is requested. A `run.lock` file is held for the duration of the run.
|
|
262
|
+
|
|
263
|
+
JSONL writes are streamed as each candidate / comparison / call completes, and all appends go through a per-trace serialization queue. If a run is killed mid-tournament, completed pairs are durable on disk and the JSONL files remain readable.
|
|
264
|
+
|
|
265
|
+
`usage.jsonl` carries one row per provider call (generator, judge, mutator, finalizer) with phase/role/provider/model/token/USD/latency/retry. It contains no prompt content. `jq` over `usage.jsonl` is the simplest way to break a run's cost down by role.
|
|
266
|
+
|
|
267
|
+
Prompts and raw model outputs are off by default. API keys are never written. Candidate answers, critiques, scores, and final artifacts are trace data and are stored/exported by design, so do not use a shared run directory for sensitive tasks unless that is acceptable.
|
|
268
|
+
|
|
269
|
+
## Development
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
pnpm install
|
|
273
|
+
pnpm run build
|
|
274
|
+
pnpm test
|
|
275
|
+
pnpm run lint
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
This repository is source-only. Generated run traces, paper notes, build output, coverage, logs, and `node_modules` are intentionally ignored.
|
|
279
|
+
|
|
280
|
+
Known limits for this release:
|
|
281
|
+
|
|
282
|
+
- Conservative resume reports trace state and safe phase boundaries, but does not replay interrupted runs yet.
|
|
283
|
+
- MCP Sampling is deferred until there is a real host-backed Sampling driver.
|
|
284
|
+
- `maxUsd` requires known model pricing; add explicit prices in YAML for custom providers and model IDs. Optional fields `longContextThresholdTokens`, `inputUsdPerMillionLong`, and `outputUsdPerMillionLong` enable tiered pricing for models with a long-context surcharge (e.g., Gemini at 200K input tokens). Cache hit/miss rates remain flat.
|
|
285
|
+
|
|
286
|
+
## Acknowledgments
|
|
287
|
+
|
|
288
|
+
DeepThonk is an independent TypeScript reimplementation of the OpenDeepThink algorithm. It is not a fork; no source code from the reference implementation is vendored. Credit for the algorithm, the benchmark methodology, and the empirical results belongs to the paper authors.
|
|
289
|
+
|
|
290
|
+
- **Paper**: Shang Zhou, Wenhao Chai, Kaiyuan Liu, Huanzhi Mao, Qiuyang Mang, Jingbo Shang. *OpenDeepThink: Parallel Reasoning via Bradley–Terry Aggregation*. arXiv:2605.15177, 2026. <https://arxiv.org/abs/2605.15177>
|
|
291
|
+
- **Reference Python implementation**: <https://github.com/ZhouShang0817/open-deep-think> (MIT). This is the authors' code release and the canonical implementation for reproducing paper results (CF-73, HLE).
|
|
292
|
+
|
|
293
|
+
DeepThonk's contribution is an integration layer: a provider-neutral TypeScript core, an MCP server, a CLI, structured trace artifacts, and budget enforcement. The algorithm itself is theirs.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { exportRun } from "@deepthonk/core";
|
|
2
|
+
import { resolveCliPath } from "../config.js";
|
|
3
|
+
export function registerExport(program) {
|
|
4
|
+
program
|
|
5
|
+
.command("export")
|
|
6
|
+
.description("Export a DeepThonk run.")
|
|
7
|
+
.argument("<runDir>")
|
|
8
|
+
.option("--format <format>", "json|markdown|jsonl", "json")
|
|
9
|
+
.action(async (runDir, options) => {
|
|
10
|
+
if (!["json", "markdown", "jsonl"].includes(options.format))
|
|
11
|
+
throw new Error(`Unsupported export format: ${options.format}. Use json, markdown, or jsonl.`);
|
|
12
|
+
runDir = resolveCliPath(runDir);
|
|
13
|
+
const exported = await exportRun(runDir, options.format);
|
|
14
|
+
if (options.format === "jsonl") {
|
|
15
|
+
process.stdout.write(String(exported.jsonl ?? ""));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (options.format === "markdown")
|
|
19
|
+
console.log(exported.markdown);
|
|
20
|
+
else
|
|
21
|
+
console.log(JSON.stringify(exported, null, 2));
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,yBAAyB,CAAC;SACtC,QAAQ,CAAC,UAAU,CAAC;SACpB,MAAM,CAAC,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,CAAC;SAC1D,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,OAAO,EAAE,EAAE;QACxC,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,OAAO,CAAC,MAAM,iCAAiC,CAAC,CAAC;QAC5J,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACzD,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;YACnD,OAAO;QACT,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU;YAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;;YAC7D,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { readRunArtifact, runArtifactFiles } from "@deepthonk/core";
|
|
2
|
+
import { TraceStore } from "@deepthonk/core";
|
|
3
|
+
import { resolveCliPath } from "../config.js";
|
|
4
|
+
export function registerInspect(program) {
|
|
5
|
+
program
|
|
6
|
+
.command("inspect")
|
|
7
|
+
.description("Inspect a DeepThonk run directory.")
|
|
8
|
+
.argument("<runDir>")
|
|
9
|
+
.option("--generation <generation>")
|
|
10
|
+
.action(async (runDir, options) => {
|
|
11
|
+
runDir = resolveCliPath(runDir);
|
|
12
|
+
const trace = new TraceStore(runDir);
|
|
13
|
+
const summary = await trace.readSummary();
|
|
14
|
+
const scores = await trace.readJsonl(runArtifactFiles.scores);
|
|
15
|
+
const candidates = await trace.readJsonl(runArtifactFiles.candidates);
|
|
16
|
+
const comparisons = await trace.readJsonl(runArtifactFiles.comparisons);
|
|
17
|
+
const generation = options.generation ?? "final";
|
|
18
|
+
const topScores = scores
|
|
19
|
+
.filter((score) => String(score.generation) === String(generation))
|
|
20
|
+
.sort((left, right) => left.rank - right.rank)
|
|
21
|
+
.slice(0, 5);
|
|
22
|
+
const byId = new Map(candidates.map((candidate) => [candidate.id, candidate]));
|
|
23
|
+
const finalText = await readRunArtifact(runDir, "final").catch(() => "");
|
|
24
|
+
console.log(JSON.stringify({
|
|
25
|
+
summary,
|
|
26
|
+
call_counts: {
|
|
27
|
+
candidates: candidates.length,
|
|
28
|
+
comparisons: comparisons.length
|
|
29
|
+
},
|
|
30
|
+
top_candidates: topScores.map((score) => ({
|
|
31
|
+
...score,
|
|
32
|
+
preview: byId.get(score.candidateId)?.content.slice(0, 160)
|
|
33
|
+
})),
|
|
34
|
+
final_preview: finalText.slice(0, 500)
|
|
35
|
+
}, null, 2));
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=inspect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../src/commands/inspect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAiD,MAAM,iBAAiB,CAAC;AACnH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,oCAAoC,CAAC;SACjD,QAAQ,CAAC,UAAU,CAAC;SACpB,MAAM,CAAC,2BAA2B,CAAC;SACnC,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,OAAO,EAAE,EAAE;QACxC,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,SAAS,CAAU,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACvE,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,SAAS,CAAY,gBAAgB,CAAC,UAAU,CAAC,CAAC;QACjF,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,SAAS,CAAa,gBAAgB,CAAC,WAAW,CAAC,CAAC;QACpF,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC;QACjD,MAAM,SAAS,GAAG,MAAM;aACrB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC;aAClE,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;aAC7C,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACf,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;QAC/E,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACzE,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,SAAS,CACZ;YACE,OAAO;YACP,WAAW,EAAE;gBACX,UAAU,EAAE,UAAU,CAAC,MAAM;gBAC7B,WAAW,EAAE,WAAW,CAAC,MAAM;aAChC;YACD,cAAc,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACxC,GAAG,KAAK;gBACR,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;aAC5D,CAAC,CAAC;YACH,aAAa,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;SACvC,EACD,IAAI,EACJ,CAAC,CACF,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { mutateCandidate } from "@deepthonk/core";
|
|
2
|
+
import { createDriver } from "@deepthonk/providers";
|
|
3
|
+
import { readPathOrInline, resolveProviderOnlyConfig } from "../config.js";
|
|
4
|
+
export function registerMutate(program) {
|
|
5
|
+
program
|
|
6
|
+
.command("mutate")
|
|
7
|
+
.description("Mutate one candidate with supplied critique.")
|
|
8
|
+
.requiredOption("--task <path-or-inline>")
|
|
9
|
+
.requiredOption("--candidate <path-or-inline>")
|
|
10
|
+
.requiredOption("--critique <path-or-inline>")
|
|
11
|
+
.option("--rubric <path-or-inline>")
|
|
12
|
+
.option("--config <yaml>")
|
|
13
|
+
.option("--provider <provider>", "fake|deepseek|openrouter|openai-compatible or any OpenAI-compatible alias")
|
|
14
|
+
.option("--base-url <url>")
|
|
15
|
+
.option("--api-key-env <name>")
|
|
16
|
+
.option("--mutator-model <model>")
|
|
17
|
+
.option("--json", "Print a structured JSON result.")
|
|
18
|
+
.action(async (options) => {
|
|
19
|
+
const [task, candidateText, critique, rubric] = await Promise.all([
|
|
20
|
+
readPathOrInline(options.task),
|
|
21
|
+
readPathOrInline(options.candidate),
|
|
22
|
+
readPathOrInline(options.critique),
|
|
23
|
+
options.rubric ? readPathOrInline(options.rubric) : undefined
|
|
24
|
+
]);
|
|
25
|
+
const resolved = await resolveProviderOnlyConfig(options);
|
|
26
|
+
const result = await mutateCandidate({
|
|
27
|
+
task,
|
|
28
|
+
rubric,
|
|
29
|
+
candidate: { id: "user-candidate", content: candidateText },
|
|
30
|
+
driver: createDriver(resolved.providerConfig),
|
|
31
|
+
mutatorModel: resolved.models.mutator,
|
|
32
|
+
temperature: 1,
|
|
33
|
+
critique
|
|
34
|
+
});
|
|
35
|
+
if (options.json)
|
|
36
|
+
console.log(JSON.stringify(result, null, 2));
|
|
37
|
+
else
|
|
38
|
+
console.log(result.mutated);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=mutate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutate.js","sourceRoot":"","sources":["../../src/commands/mutate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAE3E,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,cAAc,CAAC,yBAAyB,CAAC;SACzC,cAAc,CAAC,8BAA8B,CAAC;SAC9C,cAAc,CAAC,6BAA6B,CAAC;SAC7C,MAAM,CAAC,2BAA2B,CAAC;SACnC,MAAM,CAAC,iBAAiB,CAAC;SACzB,MAAM,CAAC,uBAAuB,EAAE,2EAA2E,CAAC;SAC5G,MAAM,CAAC,kBAAkB,CAAC;SAC1B,MAAM,CAAC,sBAAsB,CAAC;SAC9B,MAAM,CAAC,yBAAyB,CAAC;SACjC,MAAM,CAAC,QAAQ,EAAE,iCAAiC,CAAC;SACnD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAChE,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC;YAC9B,gBAAgB,CAAC,OAAO,CAAC,SAAS,CAAC;YACnC,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC;YAClC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;SAC9D,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,yBAAyB,CAAC,OAAO,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC;YACnC,IAAI;YACJ,MAAM;YACN,SAAS,EAAE,EAAE,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAAE;YAC3D,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC7C,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO;YACrC,WAAW,EAAE,CAAC;YACd,QAAQ;SACT,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,IAAI;YAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;;YAC1D,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { planBudget } from "@deepthonk/core";
|
|
3
|
+
import YAML from "yaml";
|
|
4
|
+
import { profileFromOptions, resolveCliPath } from "../config.js";
|
|
5
|
+
export function registerPlan(program) {
|
|
6
|
+
program
|
|
7
|
+
.command("plan")
|
|
8
|
+
.description("Print DeepThonk call budget for a profile.")
|
|
9
|
+
.option("--config <yaml>")
|
|
10
|
+
.option("--profile <profile>", "quick|balanced|paper", "quick")
|
|
11
|
+
.option("--n <number>")
|
|
12
|
+
.option("--k <number>")
|
|
13
|
+
.option("--t <number>")
|
|
14
|
+
.option("--m <number>")
|
|
15
|
+
.action(async (options) => {
|
|
16
|
+
if (options.config) {
|
|
17
|
+
const parsed = YAML.parse(await readFile(resolveCliPath(options.config), "utf8"));
|
|
18
|
+
console.log(JSON.stringify(planBudget(parsed.profile === "balanced" || parsed.profile === "paper" ? parsed.profile : "quick"), null, 2));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const hasOverrides = Boolean(options.n || options.k || options.t || options.m);
|
|
22
|
+
console.log(JSON.stringify(planBudget(hasOverrides ? profileFromOptions(options) : options.profile), null, 2));
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/commands/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAElE,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,4CAA4C,CAAC;SACzD,MAAM,CAAC,iBAAiB,CAAC;SACzB,MAAM,CAAC,qBAAqB,EAAE,sBAAsB,EAAE,OAAO,CAAC;SAC9D,MAAM,CAAC,cAAc,CAAC;SACtB,MAAM,CAAC,cAAc,CAAC;SACtB,MAAM,CAAC,cAAc,CAAC;SACtB,MAAM,CAAC,cAAc,CAAC;SACtB,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAyB,CAAC;YAC1G,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,KAAK,UAAU,IAAI,MAAM,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACzI,OAAO;QACT,CAAC;QACD,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;QAC/E,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACjH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { rankCandidates } from "@deepthonk/core";
|
|
3
|
+
import { createDriver } from "@deepthonk/providers";
|
|
4
|
+
import { readPathOrInline, resolveCliPath, resolveProviderOnlyConfig } from "../config.js";
|
|
5
|
+
export function registerRank(program) {
|
|
6
|
+
program
|
|
7
|
+
.command("rank")
|
|
8
|
+
.description("Rank user-provided JSONL candidates with pairwise judging.")
|
|
9
|
+
.requiredOption("--task <path-or-inline>")
|
|
10
|
+
.requiredOption("--candidates <jsonl>")
|
|
11
|
+
.option("--rubric <path-or-inline>")
|
|
12
|
+
.option("--config <yaml>")
|
|
13
|
+
.option("--provider <provider>", "fake|deepseek|openrouter|openai-compatible or any OpenAI-compatible alias")
|
|
14
|
+
.option("--base-url <url>")
|
|
15
|
+
.option("--api-key-env <name>")
|
|
16
|
+
.option("--judge-model <model>")
|
|
17
|
+
.action(async (options) => {
|
|
18
|
+
const task = await readPathOrInline(options.task);
|
|
19
|
+
const rubric = options.rubric ? await readPathOrInline(options.rubric) : undefined;
|
|
20
|
+
const candidates = (await readFile(resolveCliPath(options.candidates), "utf8"))
|
|
21
|
+
.split("\n")
|
|
22
|
+
.filter(Boolean)
|
|
23
|
+
.map((line, index) => {
|
|
24
|
+
const parsed = JSON.parse(line);
|
|
25
|
+
return { id: parsed.id ?? `candidate-${index + 1}`, content: parsed.content };
|
|
26
|
+
});
|
|
27
|
+
const resolved = await resolveProviderOnlyConfig(options);
|
|
28
|
+
const result = await rankCandidates({
|
|
29
|
+
task,
|
|
30
|
+
rubric,
|
|
31
|
+
candidates,
|
|
32
|
+
driver: createDriver(resolved.providerConfig),
|
|
33
|
+
judgeModel: resolved.models.judge
|
|
34
|
+
});
|
|
35
|
+
console.log(JSON.stringify(result.scores, null, 2));
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=rank.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rank.js","sourceRoot":"","sources":["../../src/commands/rank.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAuB,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAE3F,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,4DAA4D,CAAC;SACzE,cAAc,CAAC,yBAAyB,CAAC;SACzC,cAAc,CAAC,sBAAsB,CAAC;SACtC,MAAM,CAAC,2BAA2B,CAAC;SACnC,MAAM,CAAC,iBAAiB,CAAC;SACzB,MAAM,CAAC,uBAAuB,EAAE,2EAA2E,CAAC;SAC5G,MAAM,CAAC,kBAAkB,CAAC;SAC1B,MAAM,CAAC,sBAAsB,CAAC;SAC9B,MAAM,CAAC,uBAAuB,CAAC;SAC/B,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACnF,MAAM,UAAU,GAAqB,CAAC,MAAM,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC;aAC9F,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC,CAAC,IAAY,EAAE,KAAa,EAAE,EAAE;YACnC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAqC,CAAC;YACpE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,IAAI,aAAa,KAAK,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;QAChF,CAAC,CAAC,CAAC;QACL,MAAM,QAAQ,GAAG,MAAM,yBAAyB,CAAC,OAAO,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC;YAClC,IAAI;YACJ,MAAM;YACN,UAAU;YACV,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC7C,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK;SAClC,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { detectResumeState } from "@deepthonk/core";
|
|
2
|
+
import { resolveCliPath } from "../config.js";
|
|
3
|
+
export function registerResume(program) {
|
|
4
|
+
program
|
|
5
|
+
.command("resume")
|
|
6
|
+
.description("Detect resumability for a run directory.")
|
|
7
|
+
.argument("<runDir>")
|
|
8
|
+
.action(async (runDir) => {
|
|
9
|
+
runDir = resolveCliPath(runDir);
|
|
10
|
+
const status = await detectResumeState(runDir);
|
|
11
|
+
console.log(JSON.stringify(status, null, 2));
|
|
12
|
+
if (status.status !== "completed" && status.safe_to_continue !== true)
|
|
13
|
+
process.exitCode = 1;
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=resume.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume.js","sourceRoot":"","sources":["../../src/commands/resume.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,0CAA0C,CAAC;SACvD,QAAQ,CAAC,UAAU,CAAC;SACpB,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,EAAE;QAC/B,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,gBAAgB,KAAK,IAAI;YAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { runDeepThonk } from "@deepthonk/core";
|
|
2
|
+
import { createDriver } from "@deepthonk/providers";
|
|
3
|
+
import { resolveRunConfig } from "../config.js";
|
|
4
|
+
export function registerRun(program) {
|
|
5
|
+
program
|
|
6
|
+
.command("run")
|
|
7
|
+
.description("Run DeepThonk search.")
|
|
8
|
+
.requiredOption("--task <path-or-inline>")
|
|
9
|
+
.option("--rubric <path-or-inline>")
|
|
10
|
+
.option("--config <yaml>")
|
|
11
|
+
.option("--profile <profile>", "quick|balanced|paper")
|
|
12
|
+
.option("--provider <provider>", "fake|deepseek|openrouter|openai-compatible or any OpenAI-compatible alias")
|
|
13
|
+
.option("--base-url <url>")
|
|
14
|
+
.option("--api-key-env <name>")
|
|
15
|
+
.option("--generator-model <model>")
|
|
16
|
+
.option("--mutator-model <model>")
|
|
17
|
+
.option("--judge-model <model>")
|
|
18
|
+
.option("--finalizer-model <model>")
|
|
19
|
+
.option("--seed <number>")
|
|
20
|
+
.option("--out <dir>")
|
|
21
|
+
.option("--max-concurrency <number>")
|
|
22
|
+
.option("--max-calls <number>")
|
|
23
|
+
.option("--max-input-tokens <number>")
|
|
24
|
+
.option("--max-output-tokens <number>")
|
|
25
|
+
.option("--max-usd <number>")
|
|
26
|
+
.option("--request-timeout-ms <number>")
|
|
27
|
+
.option("--n <number>", "Population size override (default: profile)")
|
|
28
|
+
.option("--k <number>", "Comparisons per candidate per generation override")
|
|
29
|
+
.option("--t <number>", "Number of mutation generations override")
|
|
30
|
+
.option("--m <number>", "Comparisons per candidate in the final dense ranking round")
|
|
31
|
+
.option("--lambda <number>", "Bradley-Terry L2 regularization override")
|
|
32
|
+
.option("--sample-temperature <number>", "Temperature for initial candidate generation")
|
|
33
|
+
.option("--mutate-temperature <number>", "Temperature for critique-guided mutation")
|
|
34
|
+
.option("--judge-temperature <number>", "Temperature for pairwise judging")
|
|
35
|
+
.option("--prompt-style <style>", "general|paper-programming")
|
|
36
|
+
.option("--prompts <yaml>", "YAML file with per-phase prompt overrides")
|
|
37
|
+
.option("--dry-run")
|
|
38
|
+
.action(async (options) => {
|
|
39
|
+
const resolved = await resolveRunConfig(options);
|
|
40
|
+
if (options.dryRun) {
|
|
41
|
+
console.log(JSON.stringify(redacted(withApiKeyPresence(resolved)), null, 2));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const result = await runDeepThonk(resolved.runConfig, createDriver(resolved.providerConfig));
|
|
45
|
+
console.log(JSON.stringify({
|
|
46
|
+
run_id: result.runId,
|
|
47
|
+
run_dir: result.runDir,
|
|
48
|
+
winner_id: result.winner.id,
|
|
49
|
+
calls: result.calls,
|
|
50
|
+
final_answer: result.finalAnswer
|
|
51
|
+
}, null, 2));
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
// Match keys that hold a secret value. Exclude metadata pointers like apiKeyEnv/apiKeyFile/apiKeyStdin
|
|
55
|
+
// which only name where the secret lives.
|
|
56
|
+
const SECRET_KEY_RE = /^(api[_-]?key|token|secret|password|authorization|bearer|cookie|credential)$/i;
|
|
57
|
+
function redacted(value) {
|
|
58
|
+
return JSON.parse(JSON.stringify(value, (key, inner) => {
|
|
59
|
+
if (SECRET_KEY_RE.test(key) && inner)
|
|
60
|
+
return "[redacted]";
|
|
61
|
+
return inner;
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
function withApiKeyPresence(value) {
|
|
65
|
+
const apiKeyEnv = value.providerConfig.apiKeyEnv;
|
|
66
|
+
return {
|
|
67
|
+
...value,
|
|
68
|
+
providerConfig: {
|
|
69
|
+
...value.providerConfig,
|
|
70
|
+
apiKeyPresent: Boolean(value.providerConfig.apiKey || (apiKeyEnv && process.env[apiKeyEnv]))
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { serveMcp } from "@deepthonk/mcp";
|
|
2
|
+
export function registerServeMcp(program) {
|
|
3
|
+
program
|
|
4
|
+
.command("serve-mcp")
|
|
5
|
+
.description("Start the DeepThonk MCP server.")
|
|
6
|
+
.option("--transport <transport>", "stdio|http", "stdio")
|
|
7
|
+
.option("--port <number>", "Port for HTTP transport.", "3333")
|
|
8
|
+
.action(async (options) => {
|
|
9
|
+
const port = Number(options.port);
|
|
10
|
+
if (!Number.isFinite(port) || port <= 0) {
|
|
11
|
+
throw new Error(`Invalid --port value: ${options.port}`);
|
|
12
|
+
}
|
|
13
|
+
await serveMcp({ transport: options.transport, port });
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=serveMcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serveMcp.js","sourceRoot":"","sources":["../../src/commands/serveMcp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,OAAO;SACJ,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,iCAAiC,CAAC;SAC9C,MAAM,CAAC,yBAAyB,EAAE,YAAY,EAAE,OAAO,CAAC;SACxD,MAAM,CAAC,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,CAAC;SAC7D,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;QACD,MAAM,QAAQ,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import YAML from "yaml";
|
|
4
|
+
import { defaultApiKeyEnv, resolveProviderConfig, resolveProviderModels } from "@deepthonk/providers";
|
|
5
|
+
import { defaultConfigPath, defaultEnvPath, resolveCliPath } from "../config.js";
|
|
6
|
+
export function registerSetup(program) {
|
|
7
|
+
program
|
|
8
|
+
.command("setup")
|
|
9
|
+
.description("Create a reusable DeepThonk provider config.")
|
|
10
|
+
.option("--config <yaml>", "Config path to write", defaultConfigPath)
|
|
11
|
+
.option("--key-file <path>", "DeepThonk env file path for --api-key", defaultEnvPath)
|
|
12
|
+
.option("--provider <provider>", "deepseek|openrouter|openai-compatible|fake or any OpenAI-compatible alias")
|
|
13
|
+
.option("--base-url <url>")
|
|
14
|
+
.option("--api-key-env <name>")
|
|
15
|
+
.option("--api-key <key>", "Store API key in the DeepThonk env file instead of the YAML config.")
|
|
16
|
+
.option("--api-key-file <path>", "Read the API key from a local file and store it in the DeepThonk env file.")
|
|
17
|
+
.option("--api-key-stdin", "Read the API key from stdin and store it in the DeepThonk env file.")
|
|
18
|
+
.option("--profile <profile>", "quick|balanced|paper", "balanced")
|
|
19
|
+
.option("--fast-model <model>", "Use one model for generator and mutator.")
|
|
20
|
+
.option("--generator-model <model>")
|
|
21
|
+
.option("--mutator-model <model>")
|
|
22
|
+
.option("--judge-model <model>")
|
|
23
|
+
.option("--finalizer-model <model>")
|
|
24
|
+
.option("--print", "Print config instead of writing files.")
|
|
25
|
+
.action(async (options) => {
|
|
26
|
+
const provider = options.provider ?? inferProvider();
|
|
27
|
+
const apiKeyEnv = options.apiKeyEnv ?? defaultApiKeyEnv(provider) ?? "DEEPTHONK_API_KEY";
|
|
28
|
+
const models = resolveProviderModels(provider, {
|
|
29
|
+
generator: options.generatorModel ?? options.fastModel,
|
|
30
|
+
mutator: options.mutatorModel ?? options.fastModel,
|
|
31
|
+
judge: options.judgeModel,
|
|
32
|
+
finalizer: options.finalizerModel
|
|
33
|
+
});
|
|
34
|
+
const providerConfig = resolveProviderConfig({ provider, baseUrl: options.baseUrl, apiKeyEnv, models });
|
|
35
|
+
const config = {
|
|
36
|
+
profile: options.profile,
|
|
37
|
+
provider,
|
|
38
|
+
base_url: providerConfig.baseUrl,
|
|
39
|
+
api_key_env: apiKeyEnv,
|
|
40
|
+
models
|
|
41
|
+
};
|
|
42
|
+
if (!config.base_url)
|
|
43
|
+
delete config.base_url;
|
|
44
|
+
if (!models.finalizer)
|
|
45
|
+
delete config.models.finalizer;
|
|
46
|
+
const yaml = YAML.stringify(config);
|
|
47
|
+
if (options.print) {
|
|
48
|
+
process.stdout.write(yaml);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const configPath = resolveCliPath(options.config);
|
|
52
|
+
await mkdir(dirname(configPath), { recursive: true });
|
|
53
|
+
await writeFile(configPath, yaml, "utf8");
|
|
54
|
+
let envMessage = process.env[apiKeyEnv] ? `Detected ${apiKeyEnv} in the current environment.` : `Set ${apiKeyEnv} before paid runs.`;
|
|
55
|
+
if (options.apiKey && !options.apiKeyStdin && !options.apiKeyFile) {
|
|
56
|
+
process.stderr.write("warning: --api-key exposes the secret via process arguments and shell history. Prefer --api-key-stdin or --api-key-file.\n");
|
|
57
|
+
}
|
|
58
|
+
const apiKey = await resolveApiKey(options);
|
|
59
|
+
if (apiKey) {
|
|
60
|
+
const envPath = resolveCliPath(options.keyFile);
|
|
61
|
+
await mkdir(dirname(envPath), { recursive: true });
|
|
62
|
+
// writeFile mode is only honored at file *creation* on POSIX; the explicit chmod handles
|
|
63
|
+
// the case where the file pre-existed with looser permissions. Do not remove either.
|
|
64
|
+
await writeFile(envPath, `export ${apiKeyEnv}=${shellQuote(apiKey)}\n`, { encoding: "utf8", mode: 0o600 });
|
|
65
|
+
await chmod(envPath, 0o600);
|
|
66
|
+
envMessage = `Stored ${apiKeyEnv} in ${envPath}.`;
|
|
67
|
+
}
|
|
68
|
+
console.log(JSON.stringify({
|
|
69
|
+
config_path: configPath,
|
|
70
|
+
provider,
|
|
71
|
+
api_key_env: apiKeyEnv,
|
|
72
|
+
models,
|
|
73
|
+
env: envMessage,
|
|
74
|
+
usage: `deepthonk run --task task.md --config ${configPath}`
|
|
75
|
+
}, null, 2));
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function inferProvider() {
|
|
79
|
+
if (process.env.DEEPSEEK_API_KEY)
|
|
80
|
+
return "deepseek";
|
|
81
|
+
if (process.env.OPENROUTER_API_KEY)
|
|
82
|
+
return "openrouter";
|
|
83
|
+
return "deepseek";
|
|
84
|
+
}
|
|
85
|
+
function shellQuote(value) {
|
|
86
|
+
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
87
|
+
}
|
|
88
|
+
async function resolveApiKey(options) {
|
|
89
|
+
const sources = [options.apiKey, options.apiKeyFile, options.apiKeyStdin ? "stdin" : undefined].filter(Boolean);
|
|
90
|
+
if (sources.length > 1)
|
|
91
|
+
throw new Error("Use only one of --api-key, --api-key-file, or --api-key-stdin.");
|
|
92
|
+
if (options.apiKeyFile)
|
|
93
|
+
return (await readFile(resolveCliPath(options.apiKeyFile), "utf8")).trim();
|
|
94
|
+
if (options.apiKeyStdin)
|
|
95
|
+
return readStdin();
|
|
96
|
+
return options.apiKey;
|
|
97
|
+
}
|
|
98
|
+
async function readStdin() {
|
|
99
|
+
const chunks = [];
|
|
100
|
+
for await (const chunk of process.stdin)
|
|
101
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
102
|
+
return Buffer.concat(chunks).toString("utf8").trim();
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { planBudget, type Profile, type RunConfig } from "@deepthonk/core";
|
|
2
|
+
import { type ProviderConfig } from "@deepthonk/providers";
|
|
3
|
+
export interface ResolvedCliConfig {
|
|
4
|
+
runConfig: RunConfig;
|
|
5
|
+
providerConfig: ProviderConfig;
|
|
6
|
+
plan: ReturnType<typeof planBudget>;
|
|
7
|
+
}
|
|
8
|
+
export interface ResolvedProviderConfig {
|
|
9
|
+
providerConfig: ProviderConfig;
|
|
10
|
+
models: ProviderConfig["models"];
|
|
11
|
+
}
|
|
12
|
+
export declare const defaultConfigPath: string;
|
|
13
|
+
export declare const defaultEnvPath: string;
|
|
14
|
+
export declare function resolveRunConfig(options: Record<string, unknown>): Promise<ResolvedCliConfig>;
|
|
15
|
+
export declare function resolveProviderOnlyConfig(options: Record<string, unknown>): Promise<ResolvedProviderConfig>;
|
|
16
|
+
export declare function profileFromOptions(options: Record<string, unknown>): Profile;
|
|
17
|
+
export declare function readPathOrInline(value: string): Promise<string>;
|
|
18
|
+
export declare function resolveCliPath(value: string): string;
|
|
19
|
+
export declare function loadDeepThonkEnv(path?: string): Promise<void>;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { basename, dirname, extname, join, resolve } from "node:path";
|
|
5
|
+
import YAML from "yaml";
|
|
6
|
+
import { ConfigError, getProfile, planBudget } from "@deepthonk/core";
|
|
7
|
+
import { defaultPricesForProviderConfig, resolveProviderConfig, resolveProviderModels } from "@deepthonk/providers";
|
|
8
|
+
export const defaultConfigPath = join(homedir(), ".config", "deepthonk", "config.yaml");
|
|
9
|
+
export const defaultEnvPath = join(dirname(defaultConfigPath), "env");
|
|
10
|
+
export async function resolveRunConfig(options) {
|
|
11
|
+
await loadDeepThonkEnv();
|
|
12
|
+
const configPath = resolveConfigPath(options);
|
|
13
|
+
const fileConfig = configPath ? await readConfig(configPath) : {};
|
|
14
|
+
const profileName = builtInProfileName(options.profile ?? fileConfig.profile ?? "quick");
|
|
15
|
+
const profile = mergeAlgorithmOverrides(getProfile(profileName), fileConfig.algorithm, options);
|
|
16
|
+
const task = await readPathOrInline(String(options.task ?? ""));
|
|
17
|
+
const rubric = options.rubric ? await readPathOrInline(String(options.rubric)) : undefined;
|
|
18
|
+
const provider = String(options.provider ?? fileConfig.provider ?? "fake");
|
|
19
|
+
const models = resolveProviderModels(provider, {
|
|
20
|
+
generator: stringOption(options.generatorModel) ?? fileConfig.models?.generator,
|
|
21
|
+
mutator: stringOption(options.mutatorModel) ?? fileConfig.models?.mutator,
|
|
22
|
+
judge: stringOption(options.judgeModel) ?? fileConfig.models?.judge,
|
|
23
|
+
finalizer: stringOption(options.finalizerModel) ?? fileConfig.models?.finalizer
|
|
24
|
+
});
|
|
25
|
+
const maxConcurrency = numberOption(options.maxConcurrency);
|
|
26
|
+
const retry = {
|
|
27
|
+
httpRetries: fileConfig.retry?.httpRetries ?? 2,
|
|
28
|
+
invalidJsonRetries: fileConfig.retry?.invalidJsonRetries ?? 1,
|
|
29
|
+
requestTimeoutMs: numberOption(options.requestTimeoutMs) ?? fileConfig.retry?.requestTimeoutMs
|
|
30
|
+
};
|
|
31
|
+
const providerConfig = resolveProviderConfig({
|
|
32
|
+
provider,
|
|
33
|
+
baseUrl: stringOption(options.baseUrl) ?? fileConfig.base_url,
|
|
34
|
+
apiKeyEnv: stringOption(options.apiKeyEnv) ?? fileConfig.api_key_env,
|
|
35
|
+
models,
|
|
36
|
+
roleProviders: normalizeRoleProviders(fileConfig.providers, models),
|
|
37
|
+
retry
|
|
38
|
+
});
|
|
39
|
+
const budget = mergeBudget(fileConfig.budget, {
|
|
40
|
+
maxCalls: numberOption(options.maxCalls),
|
|
41
|
+
maxInputTokens: numberOption(options.maxInputTokens),
|
|
42
|
+
maxOutputTokens: numberOption(options.maxOutputTokens),
|
|
43
|
+
maxUsd: numberOption(options.maxUsd)
|
|
44
|
+
}, defaultPricesForProviderConfig(providerConfig));
|
|
45
|
+
const promptOverrides = await loadPromptOverrides(options, fileConfig);
|
|
46
|
+
const runConfig = {
|
|
47
|
+
task,
|
|
48
|
+
rubric,
|
|
49
|
+
promptStyle: stringOption(options.promptStyle) ??
|
|
50
|
+
fileConfig.prompt_style ??
|
|
51
|
+
(profileName === "paper" ? "paper-programming" : "general"),
|
|
52
|
+
promptOverrides,
|
|
53
|
+
profile,
|
|
54
|
+
runDir: resolveCliPath(String(options.out ?? `runs/${new Date().toISOString().replace(/[:.]/g, "-")}`)),
|
|
55
|
+
seed: numberOption(options.seed) ?? 1,
|
|
56
|
+
provider,
|
|
57
|
+
generatorModel: models.generator,
|
|
58
|
+
mutatorModel: models.mutator,
|
|
59
|
+
judgeModel: models.judge,
|
|
60
|
+
finalizerModel: models.finalizer,
|
|
61
|
+
concurrency: {
|
|
62
|
+
generate: maxConcurrency ?? fileConfig.concurrency?.generate ?? profile.n,
|
|
63
|
+
judge: maxConcurrency ?? fileConfig.concurrency?.judge ?? Math.max(1, (profile.n * Math.max(profile.k, profile.m)) / 2),
|
|
64
|
+
mutate: maxConcurrency ?? fileConfig.concurrency?.mutate ?? profile.n - Math.floor(profile.n / 4)
|
|
65
|
+
},
|
|
66
|
+
retry,
|
|
67
|
+
budget,
|
|
68
|
+
output: {
|
|
69
|
+
includeRawModelOutputs: fileConfig.output?.includeRawModelOutputs ?? false,
|
|
70
|
+
includePrompts: fileConfig.output?.includePrompts ?? false
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
runConfig,
|
|
75
|
+
providerConfig,
|
|
76
|
+
plan: planBudget(profile)
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export async function resolveProviderOnlyConfig(options) {
|
|
80
|
+
await loadDeepThonkEnv();
|
|
81
|
+
const configPath = resolveConfigPath(options);
|
|
82
|
+
const fileConfig = configPath ? await readConfig(configPath) : {};
|
|
83
|
+
const provider = String(options.provider ?? fileConfig.provider ?? "fake");
|
|
84
|
+
const models = resolveProviderModels(provider, {
|
|
85
|
+
generator: stringOption(options.generatorModel) ?? fileConfig.models?.generator,
|
|
86
|
+
mutator: stringOption(options.mutatorModel) ?? fileConfig.models?.mutator,
|
|
87
|
+
judge: stringOption(options.judgeModel) ?? fileConfig.models?.judge,
|
|
88
|
+
finalizer: stringOption(options.finalizerModel) ?? fileConfig.models?.finalizer
|
|
89
|
+
});
|
|
90
|
+
return {
|
|
91
|
+
models,
|
|
92
|
+
providerConfig: resolveProviderConfig({
|
|
93
|
+
provider,
|
|
94
|
+
baseUrl: stringOption(options.baseUrl) ?? fileConfig.base_url,
|
|
95
|
+
apiKeyEnv: stringOption(options.apiKeyEnv) ?? fileConfig.api_key_env,
|
|
96
|
+
models,
|
|
97
|
+
roleProviders: normalizeRoleProviders(fileConfig.providers, models),
|
|
98
|
+
retry: {
|
|
99
|
+
httpRetries: fileConfig.retry?.httpRetries ?? 2,
|
|
100
|
+
requestTimeoutMs: numberOption(options.requestTimeoutMs) ?? fileConfig.retry?.requestTimeoutMs
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
export function profileFromOptions(options) {
|
|
106
|
+
const base = getProfile(builtInProfileName(options.profile ?? "quick"));
|
|
107
|
+
return mergeAlgorithmOverrides(base, undefined, options);
|
|
108
|
+
}
|
|
109
|
+
async function loadPromptOverrides(options, fileConfig) {
|
|
110
|
+
let fromFlag;
|
|
111
|
+
const path = stringOption(options.prompts);
|
|
112
|
+
if (path) {
|
|
113
|
+
const resolved = resolveCliPath(path);
|
|
114
|
+
if (!existsSync(resolved)) {
|
|
115
|
+
throw new ConfigError(`--prompts file does not exist: ${path}`, {
|
|
116
|
+
code: "config.prompts_file_missing",
|
|
117
|
+
retryable: false,
|
|
118
|
+
fix: "Pass a YAML file path. The file should map phase names to { system, user } templates."
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
fromFlag = YAML.parse(await readFile(resolved, "utf8"));
|
|
122
|
+
}
|
|
123
|
+
const merged = { ...(fileConfig.prompts ?? {}) };
|
|
124
|
+
if (fromFlag) {
|
|
125
|
+
for (const phase of ["generate", "compare", "mutate", "finalize"]) {
|
|
126
|
+
if (fromFlag[phase])
|
|
127
|
+
merged[phase] = { ...(merged[phase] ?? {}), ...fromFlag[phase] };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return Object.keys(merged).length ? merged : undefined;
|
|
131
|
+
}
|
|
132
|
+
function mergeAlgorithmOverrides(base, fileOverrides, cliOptions) {
|
|
133
|
+
return {
|
|
134
|
+
n: numberOption(cliOptions.n) ?? fileOverrides?.n ?? base.n,
|
|
135
|
+
k: numberOption(cliOptions.k) ?? fileOverrides?.k ?? base.k,
|
|
136
|
+
t: numberOption(cliOptions.t) ?? fileOverrides?.t ?? base.t,
|
|
137
|
+
m: numberOption(cliOptions.m) ?? fileOverrides?.m ?? base.m,
|
|
138
|
+
lambda: numberOption(cliOptions.lambda) ?? fileOverrides?.lambda ?? base.lambda,
|
|
139
|
+
sampleTemperature: numberOption(cliOptions.sampleTemperature) ?? fileOverrides?.sample_temperature ?? base.sampleTemperature,
|
|
140
|
+
mutateTemperature: numberOption(cliOptions.mutateTemperature) ?? fileOverrides?.mutate_temperature ?? base.mutateTemperature,
|
|
141
|
+
judgeTemperature: numberOption(cliOptions.judgeTemperature) ?? fileOverrides?.judge_temperature ?? base.judgeTemperature
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
export async function readPathOrInline(value) {
|
|
145
|
+
if (!value)
|
|
146
|
+
return "";
|
|
147
|
+
const candidates = candidatePaths(value);
|
|
148
|
+
const path = candidates.find((candidate) => existsSync(candidate));
|
|
149
|
+
if (path)
|
|
150
|
+
return readFile(path, "utf8");
|
|
151
|
+
if (looksPathLike(value))
|
|
152
|
+
throw new ConfigError(`Input path does not exist: ${value}. Use inline text without path separators, or fix the path.`);
|
|
153
|
+
return value;
|
|
154
|
+
}
|
|
155
|
+
export function resolveCliPath(value) {
|
|
156
|
+
return candidatePaths(value)[0];
|
|
157
|
+
}
|
|
158
|
+
function candidatePaths(value) {
|
|
159
|
+
if (value.startsWith("/"))
|
|
160
|
+
return [value];
|
|
161
|
+
return [
|
|
162
|
+
process.env.INIT_CWD ? resolve(process.env.INIT_CWD, value) : undefined,
|
|
163
|
+
resolve(value),
|
|
164
|
+
resolve(process.cwd(), "../..", value)
|
|
165
|
+
].filter((path) => Boolean(path));
|
|
166
|
+
}
|
|
167
|
+
async function readConfig(path) {
|
|
168
|
+
return YAML.parse(await readFile(resolveCliPath(path), "utf8"));
|
|
169
|
+
}
|
|
170
|
+
function resolveConfigPath(options) {
|
|
171
|
+
return stringOption(options.config) ?? process.env.DEEPTHONK_CONFIG ?? (existsSync(defaultConfigPath) ? defaultConfigPath : undefined);
|
|
172
|
+
}
|
|
173
|
+
export async function loadDeepThonkEnv(path = process.env.DEEPTHONK_ENV ?? defaultEnvPath) {
|
|
174
|
+
if (!existsSync(path))
|
|
175
|
+
return;
|
|
176
|
+
const text = await readFile(path, "utf8");
|
|
177
|
+
for (const line of text.split("\n")) {
|
|
178
|
+
const parsed = parseEnvLine(line);
|
|
179
|
+
if (!parsed)
|
|
180
|
+
continue;
|
|
181
|
+
const [key, value] = parsed;
|
|
182
|
+
if (process.env[key] === undefined || process.env[key] === "")
|
|
183
|
+
process.env[key] = value;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function parseEnvLine(line) {
|
|
187
|
+
const trimmed = line.trim();
|
|
188
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
189
|
+
return undefined;
|
|
190
|
+
const match = trimmed.match(/^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);
|
|
191
|
+
if (!match)
|
|
192
|
+
return undefined;
|
|
193
|
+
return [match[1], unquoteEnvValue(match[2].trim())];
|
|
194
|
+
}
|
|
195
|
+
function unquoteEnvValue(value) {
|
|
196
|
+
if ((value.startsWith("'") && value.endsWith("'")) || (value.startsWith('"') && value.endsWith('"'))) {
|
|
197
|
+
const inner = value.slice(1, -1);
|
|
198
|
+
return value.startsWith("'") ? inner.replace(/'\\''/g, "'") : inner.replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
199
|
+
}
|
|
200
|
+
return value;
|
|
201
|
+
}
|
|
202
|
+
function numberOption(value) {
|
|
203
|
+
if (value === undefined || value === null || value === "")
|
|
204
|
+
return undefined;
|
|
205
|
+
return Number(value);
|
|
206
|
+
}
|
|
207
|
+
function mergeBudget(fileBudget, overrides, defaultPrices = []) {
|
|
208
|
+
const prices = mergePrices(defaultPrices, fileBudget?.prices);
|
|
209
|
+
const definedOverrides = Object.fromEntries(Object.entries(overrides).filter(([, value]) => value !== undefined));
|
|
210
|
+
if (!fileBudget && !Object.keys(definedOverrides).length && prices.length === 0)
|
|
211
|
+
return undefined;
|
|
212
|
+
const merged = {
|
|
213
|
+
...(fileBudget ?? {}),
|
|
214
|
+
...definedOverrides,
|
|
215
|
+
prices
|
|
216
|
+
};
|
|
217
|
+
return merged && Object.keys(merged).length ? merged : undefined;
|
|
218
|
+
}
|
|
219
|
+
function mergePrices(defaults, overrides) {
|
|
220
|
+
const byKey = new Map(defaults.map((price) => [`${price.provider}/${price.model}`, price]));
|
|
221
|
+
for (const price of overrides ?? [])
|
|
222
|
+
byKey.set(`${price.provider}/${price.model}`, price);
|
|
223
|
+
return [...byKey.values()];
|
|
224
|
+
}
|
|
225
|
+
function stringOption(value) {
|
|
226
|
+
if (value === undefined || value === null || value === "")
|
|
227
|
+
return undefined;
|
|
228
|
+
return String(value);
|
|
229
|
+
}
|
|
230
|
+
function builtInProfileName(value) {
|
|
231
|
+
const profile = String(value);
|
|
232
|
+
if (profile === "quick" || profile === "balanced" || profile === "paper")
|
|
233
|
+
return profile;
|
|
234
|
+
throw new ConfigError(`Unknown profile: ${profile}. Use quick, balanced, or paper.`);
|
|
235
|
+
}
|
|
236
|
+
function looksPathLike(value) {
|
|
237
|
+
if (value.startsWith("/") || value.startsWith("./") || value.startsWith("../") || value.startsWith("~/"))
|
|
238
|
+
return true;
|
|
239
|
+
if (value.includes("/") || value.includes("\\"))
|
|
240
|
+
return true;
|
|
241
|
+
const extension = extname(basename(value)).toLowerCase();
|
|
242
|
+
return [".txt", ".md", ".json", ".jsonl", ".yaml", ".yml"].includes(extension);
|
|
243
|
+
}
|
|
244
|
+
function normalizeRoleProviders(providers, models) {
|
|
245
|
+
if (!providers)
|
|
246
|
+
return undefined;
|
|
247
|
+
const normalized = {};
|
|
248
|
+
for (const role of ["generator", "mutator", "judge", "finalizer"]) {
|
|
249
|
+
const provider = providers[role];
|
|
250
|
+
if (!provider)
|
|
251
|
+
continue;
|
|
252
|
+
const model = provider.model ?? models[role];
|
|
253
|
+
if (!model)
|
|
254
|
+
continue;
|
|
255
|
+
normalized[role] = {
|
|
256
|
+
provider: provider.provider,
|
|
257
|
+
baseUrl: provider.base_url,
|
|
258
|
+
apiKeyEnv: provider.api_key_env,
|
|
259
|
+
model,
|
|
260
|
+
supportsJsonMode: provider.supports_json_mode
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
return Object.keys(normalized).length ? normalized : undefined;
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { DeepThonkError } from "@deepthonk/core";
|
|
4
|
+
import { registerExport } from "./commands/export.js";
|
|
5
|
+
import { registerInspect } from "./commands/inspect.js";
|
|
6
|
+
import { registerMutate } from "./commands/mutate.js";
|
|
7
|
+
import { registerPlan } from "./commands/plan.js";
|
|
8
|
+
import { registerRank } from "./commands/rank.js";
|
|
9
|
+
import { registerResume } from "./commands/resume.js";
|
|
10
|
+
import { registerRun } from "./commands/run.js";
|
|
11
|
+
import { registerServeMcp } from "./commands/serveMcp.js";
|
|
12
|
+
import { registerSetup } from "./commands/setup.js";
|
|
13
|
+
process.on("unhandledRejection", (reason) => {
|
|
14
|
+
process.stderr.write(`deepthonk unhandledRejection: ${reason instanceof Error ? reason.message : String(reason)}\n`);
|
|
15
|
+
});
|
|
16
|
+
const program = new Command();
|
|
17
|
+
program.name("deepthonk").description("Thonk harder, not richer.").version("0.1.0").option("--json-errors", "Print machine-readable errors to stderr.");
|
|
18
|
+
registerPlan(program);
|
|
19
|
+
registerRun(program);
|
|
20
|
+
registerInspect(program);
|
|
21
|
+
registerResume(program);
|
|
22
|
+
registerExport(program);
|
|
23
|
+
registerRank(program);
|
|
24
|
+
registerMutate(program);
|
|
25
|
+
registerSetup(program);
|
|
26
|
+
registerServeMcp(program);
|
|
27
|
+
program.parseAsync(process.argv).catch((error) => {
|
|
28
|
+
const opts = program.opts();
|
|
29
|
+
if (opts.jsonErrors) {
|
|
30
|
+
console.error(JSON.stringify(serializeError(error), null, 2));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
34
|
+
}
|
|
35
|
+
process.exitCode = 1;
|
|
36
|
+
});
|
|
37
|
+
function serializeError(error) {
|
|
38
|
+
if (error instanceof DeepThonkError) {
|
|
39
|
+
return {
|
|
40
|
+
code: error.code,
|
|
41
|
+
message: error.message,
|
|
42
|
+
retryable: error.retryable,
|
|
43
|
+
fix: error.fix
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
code: "unexpected_error",
|
|
48
|
+
message: error instanceof Error ? error.message : String(error),
|
|
49
|
+
retryable: false
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;IAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACvH,CAAC,CAAC,CAAC;AAEH,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAC9B,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,2BAA2B,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,eAAe,EAAE,0CAA0C,CAAC,CAAC;AAExJ,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,eAAe,CAAC,OAAO,CAAC,CAAC;AACzB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAE1B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAA4B,CAAC;IACtD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,SAAS,cAAc,CAAC,KAAc;IACpC,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;QACpC,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,GAAG,EAAE,KAAK,CAAC,GAAG;SACf,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QAC/D,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "deepthonk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Provider-neutral OpenDeepThink CLI and MCP server. Population-based reasoning via pairwise judging and Bradley-Terry ranking.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Xule Lin",
|
|
7
|
+
"homepage": "https://github.com/linxule/deepthonk#readme",
|
|
8
|
+
"bugs": {
|
|
9
|
+
"url": "https://github.com/linxule/deepthonk/issues"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"mcp",
|
|
13
|
+
"model-context-protocol",
|
|
14
|
+
"opendeepthink",
|
|
15
|
+
"reasoning",
|
|
16
|
+
"bradley-terry",
|
|
17
|
+
"test-time-compute",
|
|
18
|
+
"deepseek",
|
|
19
|
+
"cli",
|
|
20
|
+
"llm",
|
|
21
|
+
"agent"
|
|
22
|
+
],
|
|
23
|
+
"type": "module",
|
|
24
|
+
"main": "dist/index.js",
|
|
25
|
+
"types": "dist/index.d.ts",
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"package.json",
|
|
29
|
+
"README.md",
|
|
30
|
+
"LICENSE"
|
|
31
|
+
],
|
|
32
|
+
"bin": {
|
|
33
|
+
"deepthonk": "dist/index.js",
|
|
34
|
+
"dt": "dist/index.js"
|
|
35
|
+
},
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/linxule/deepthonk.git",
|
|
39
|
+
"directory": "packages/cli"
|
|
40
|
+
},
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"commander": "^13.1.0",
|
|
46
|
+
"yaml": "^2.7.1",
|
|
47
|
+
"zod": "^3.25.28",
|
|
48
|
+
"@deepthonk/core": "0.1.0",
|
|
49
|
+
"@deepthonk/providers": "0.1.0",
|
|
50
|
+
"@deepthonk/mcp": "0.1.0"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "tsc -p tsconfig.json && chmod +x dist/index.js",
|
|
54
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
55
|
+
"deepthonk": "tsx src/index.ts"
|
|
56
|
+
}
|
|
57
|
+
}
|