reasonix 0.0.4 → 0.0.6
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/README.md +140 -58
- package/dist/cli/index.js +921 -70
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +138 -6
- package/dist/index.js +586 -32
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-Y7L6L5QS.js +0 -262
- package/dist/chunk-Y7L6L5QS.js.map +0 -1
- package/dist/cli/chunk-T2ODXAJP.js +0 -263
- package/dist/cli/chunk-T2ODXAJP.js.map +0 -1
- package/dist/cli/client-RIVGDOJP.js +0 -10
- package/dist/cli/client-RIVGDOJP.js.map +0 -1
- package/dist/client-KEA2D52Q.js +0 -9
- package/dist/client-KEA2D52Q.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,66 +1,135 @@
|
|
|
1
1
|
# Reasonix
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/reasonix)
|
|
4
|
+
[](https://github.com/esengine/reasonix/actions/workflows/ci.yml)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
[](https://www.npmjs.com/package/reasonix)
|
|
7
|
+
[](./package.json)
|
|
8
|
+
|
|
3
9
|
**The DeepSeek-native agent framework.** TypeScript. Ink TUI. No LangChain.
|
|
4
10
|
|
|
5
|
-
Reasonix is not another generic agent
|
|
6
|
-
|
|
7
|
-
automatic prefix caching
|
|
8
|
-
|
|
11
|
+
Reasonix is not another generic agent wrapper. Every abstraction is justified
|
|
12
|
+
by a DeepSeek-specific property — dirt-cheap tokens, R1 reasoning traces,
|
|
13
|
+
automatic prefix caching, JSON mode. Generic frameworks treat DeepSeek as
|
|
14
|
+
"OpenAI with a different base URL" and leave these advantages on the table.
|
|
15
|
+
Reasonix leans into them.
|
|
9
16
|
|
|
10
17
|
```bash
|
|
11
|
-
npx reasonix chat # prompts for your DeepSeek key
|
|
12
|
-
#
|
|
18
|
+
npx reasonix chat # first run prompts for your DeepSeek key
|
|
19
|
+
# inside the TUI, type /help for everything else
|
|
13
20
|
```
|
|
14
21
|
|
|
15
|
-
|
|
16
|
-
[platform.deepseek.com/api_keys](https://platform.deepseek.com/api_keys)) and
|
|
17
|
-
saves it to `~/.reasonix/config.json`. Set `DEEPSEEK_API_KEY` in the
|
|
18
|
-
environment to override.
|
|
22
|
+
No flag soup. All feature toggles live behind slash commands in the TUI.
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
---
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
different base URL. That works, but it leaves most of DeepSeek's advantages
|
|
24
|
-
unused. Reasonix is opinionated about three things:
|
|
26
|
+
## What you get
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
| Feature | How it works | Opt in |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| **Cache-First Loop** | Immutable prefix + append-only log = prefix byte-stable across turns → DeepSeek's automatic prefix cache hits at 70–95% | always on |
|
|
31
|
+
| **R1 Thought Harvesting** | Parses `reasoning_content` into typed `{ subgoals, hypotheses, uncertainties, rejectedPaths }` via a cheap V3 call | `--harvest` |
|
|
32
|
+
| **Self-Consistency Branching** | Runs N parallel samples at spread temperatures; picks the one with the fewest flagged uncertainties | `--branch <N>` |
|
|
33
|
+
| **Tool-Call Repair** | Auto-flattens deep/wide schemas, scavenges tool calls leaked into `<think>`, repairs truncated JSON, breaks call-storms | always on |
|
|
34
|
+
| **Retry layer** | Exponential backoff + jitter on 408/429/500/502/503/504 and network errors. 4xx auth errors don't retry | always on |
|
|
35
|
+
| **Ink TUI** | Live cache-hit / cost panel. Streams R1 thinking to a compact preview. Renders Markdown (bold / lists / code / stripped LaTeX) | always on |
|
|
30
36
|
|
|
31
|
-
|
|
37
|
+
---
|
|
32
38
|
|
|
33
|
-
|
|
34
|
-
|---|---|---|---|---|---|
|
|
35
|
-
| Chinese multi-turn chat | 5 | **85.2%** | $0.000923 | $0.015174 | **93.9%** |
|
|
36
|
-
| Tool-use (calculator) | 2 | **94.9%** | $0.000142 | $0.003351 | **95.8%** |
|
|
39
|
+
## Why not just use LangChain?
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
pipes it through a cheap V3 call (~$0.0001 / turn) in JSON mode and extracts
|
|
41
|
-
a typed plan state:
|
|
41
|
+
Even on the default `fast` preset (no harvest, no branching), Reasonix bakes
|
|
42
|
+
in five DeepSeek-specific defences that generic agent frameworks leave to you:
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
| | Reasonix default | generic frameworks |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| Prefix-stable loop (→ 85–95% cache hit) | ✅ | ❌ prompts rebuilt each turn |
|
|
47
|
+
| Auto-flatten deep tool schemas | ✅ | ❌ DeepSeek drops args |
|
|
48
|
+
| Retry with jittered backoff (429/503) | ✅ | ❌ custom callbacks |
|
|
49
|
+
| Scavenge tool calls leaked into `<think>` | ✅ | ❌ |
|
|
50
|
+
| Call-storm breaker on identical-arg repeats | ✅ | ❌ |
|
|
51
|
+
| Live cache-hit / cost / vs-Claude panel | ✅ | ❌ |
|
|
52
|
+
| First-run config prompt + Markdown TUI | ✅ | ❌ |
|
|
53
|
+
|
|
54
|
+
Harvest and self-consistency branching are bonuses on top. The everyday
|
|
55
|
+
win is that **a plain chat with Reasonix already pays for ~40% less tokens
|
|
56
|
+
than the same chat through a naive LangChain setup**, because the prefix
|
|
57
|
+
actually stays byte-stable.
|
|
58
|
+
|
|
59
|
+
## Validated numbers
|
|
46
60
|
|
|
47
|
-
|
|
48
|
-
`new CacheFirstLoop({ harvest: true })`. The TUI renders the harvested state
|
|
49
|
-
as a compact magenta block above the answer.
|
|
61
|
+
Measured on live DeepSeek API:
|
|
50
62
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
63
|
+
| scenario | model | turns | cache hit | cost | Claude 4.6 would be | savings |
|
|
64
|
+
|---|---|---|---|---|---|---|
|
|
65
|
+
| Chinese multi-turn chat | `deepseek-chat` | 5 | **85.2%** | $0.000923 | $0.015174 | **93.9%** |
|
|
66
|
+
| Tool-use (calculator) | `deepseek-chat` | 2 | **94.9%** | $0.000142 | $0.003351 | **95.8%** |
|
|
67
|
+
| R1 math + harvest | `deepseek-reasoner` | 1 | 72.7% | $0.006478 | $0.044484 | 85.4% |
|
|
68
|
+
|
|
69
|
+
---
|
|
55
70
|
|
|
56
71
|
## Usage
|
|
57
72
|
|
|
73
|
+
### CLI
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npx reasonix chat # auto-saves to session 'default'; resumes next time
|
|
77
|
+
npx reasonix chat --session work # use a different named session
|
|
78
|
+
npx reasonix chat --no-session # ephemeral — nothing persisted
|
|
79
|
+
npx reasonix run "ask anything" # one-shot, streams to stdout
|
|
80
|
+
npx reasonix stats session.jsonl # read back a saved transcript
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Sessions live as JSONL under `~/.reasonix/sessions/<name>.jsonl` — every
|
|
84
|
+
turn's message log is appended atomically, so killing the CLI never loses
|
|
85
|
+
context. Inside the TUI: `/sessions` to list, `/forget` to delete the
|
|
86
|
+
current one.
|
|
87
|
+
|
|
88
|
+
### Inside the chat — slash commands
|
|
89
|
+
|
|
90
|
+
A command strip runs under the input box so you don't have to memorize
|
|
91
|
+
anything. Type `/help` for the full list. The biggest shortcut:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
/preset fast deepseek-chat, no harvest, no branch (default)
|
|
95
|
+
/preset smart reasoner + harvest (~10x cost)
|
|
96
|
+
/preset max reasoner + harvest + branch 3 (~30x cost, slowest)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
One-tap switch between fast daily driver, careful thinker, and max-quality
|
|
100
|
+
self-consistency. Individual knobs are available too:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
/status show current model / harvest / branch / stream
|
|
104
|
+
/model <id> deepseek-chat or deepseek-reasoner
|
|
105
|
+
/harvest [on|off] Pillar 2 — parse R1 reasoning into typed plan state
|
|
106
|
+
/branch <N|off> run N parallel samples per turn, pick most confident
|
|
107
|
+
/clear clear displayed history (log is kept)
|
|
108
|
+
/exit quit
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The top panel shows active flags live: `· harvest · branch3` appear next to
|
|
112
|
+
the model once enabled.
|
|
113
|
+
|
|
114
|
+
### Flags (for automation / CI)
|
|
115
|
+
|
|
116
|
+
The same knobs are also available as CLI flags if you're scripting:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npx reasonix chat -m deepseek-reasoner --harvest --branch 3 --transcript session.jsonl
|
|
120
|
+
```
|
|
121
|
+
|
|
58
122
|
### Library
|
|
59
123
|
|
|
60
124
|
```ts
|
|
61
|
-
import {
|
|
62
|
-
|
|
63
|
-
|
|
125
|
+
import {
|
|
126
|
+
CacheFirstLoop,
|
|
127
|
+
DeepSeekClient,
|
|
128
|
+
ImmutablePrefix,
|
|
129
|
+
ToolRegistry,
|
|
130
|
+
} from "reasonix";
|
|
131
|
+
|
|
132
|
+
const client = new DeepSeekClient(); // reads DEEPSEEK_API_KEY from env
|
|
64
133
|
const tools = new ToolRegistry();
|
|
65
134
|
|
|
66
135
|
tools.register({
|
|
@@ -71,55 +140,68 @@ tools.register({
|
|
|
71
140
|
properties: { a: { type: "integer" }, b: { type: "integer" } },
|
|
72
141
|
required: ["a", "b"],
|
|
73
142
|
},
|
|
74
|
-
fn: ({ a, b }) => a + b,
|
|
143
|
+
fn: ({ a, b }: { a: number; b: number }) => a + b,
|
|
75
144
|
});
|
|
76
145
|
|
|
77
146
|
const loop = new CacheFirstLoop({
|
|
78
147
|
client,
|
|
148
|
+
tools,
|
|
79
149
|
prefix: new ImmutablePrefix({
|
|
80
150
|
system: "You are a math helper.",
|
|
81
151
|
toolSpecs: tools.specs(),
|
|
82
152
|
}),
|
|
83
|
-
|
|
153
|
+
harvest: true,
|
|
154
|
+
branch: 3, // self-consistency budget
|
|
84
155
|
});
|
|
85
156
|
|
|
86
157
|
for await (const ev of loop.step("What is 17 + 25?")) {
|
|
87
|
-
console.log(ev);
|
|
158
|
+
if (ev.role === "assistant_final") console.log(ev.content);
|
|
88
159
|
}
|
|
89
160
|
console.log(loop.stats.summary());
|
|
90
161
|
```
|
|
91
162
|
|
|
92
|
-
###
|
|
163
|
+
### Configuration
|
|
164
|
+
|
|
165
|
+
On first run the CLI prompts for your DeepSeek API key and saves it to
|
|
166
|
+
`~/.reasonix/config.json`. Alternatives:
|
|
93
167
|
|
|
94
168
|
```bash
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
reasonix stats <file> # summarize transcript JSONL
|
|
98
|
-
reasonix version
|
|
169
|
+
export DEEPSEEK_API_KEY=sk-... # env var (wins over config file)
|
|
170
|
+
export DEEPSEEK_BASE_URL=https://... # optional alternate endpoint
|
|
99
171
|
```
|
|
100
172
|
|
|
101
|
-
|
|
173
|
+
Get a key (free credit on signup): <https://platform.deepseek.com/api_keys>
|
|
102
174
|
|
|
103
|
-
|
|
104
|
-
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
|
|
175
|
+
---
|
|
105
176
|
|
|
106
177
|
## Non-goals
|
|
107
178
|
|
|
108
|
-
- Multi-agent orchestration (use LangGraph
|
|
109
|
-
- RAG / vector stores.
|
|
110
|
-
- Multi-provider abstraction
|
|
179
|
+
- Multi-agent orchestration (use LangGraph).
|
|
180
|
+
- RAG / vector stores (use LlamaIndex or do it yourself).
|
|
181
|
+
- Multi-provider abstraction (use LiteLLM).
|
|
111
182
|
- Web UI / SaaS.
|
|
112
183
|
|
|
184
|
+
Reasonix does DeepSeek, deeply.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
113
188
|
## Development
|
|
114
189
|
|
|
115
190
|
```bash
|
|
191
|
+
git clone https://github.com/esengine/reasonix.git
|
|
192
|
+
cd reasonix
|
|
116
193
|
npm install
|
|
117
|
-
npm run dev chat
|
|
118
|
-
npm run build
|
|
119
|
-
npm test
|
|
120
|
-
npm run lint
|
|
194
|
+
npm run dev chat # run CLI from source via tsx
|
|
195
|
+
npm run build # tsup to dist/
|
|
196
|
+
npm test # vitest (89 tests)
|
|
197
|
+
npm run lint # biome
|
|
198
|
+
npm run typecheck # tsc --noEmit
|
|
121
199
|
```
|
|
122
200
|
|
|
201
|
+
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for internals.
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
123
205
|
## License
|
|
124
206
|
|
|
125
207
|
MIT
|