reasonix 0.4.28 → 0.5.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/README.md +8 -0
- package/data/deepseek-tokenizer.json.gz +0 -0
- package/dist/cli/index.js +580 -47
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +26 -0
- package/dist/index.js +48 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -138,6 +138,21 @@ interface UserBalance {
|
|
|
138
138
|
is_available: boolean;
|
|
139
139
|
balance_infos: BalanceInfo[];
|
|
140
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* Response shape for DeepSeek's `/models` endpoint. Mirrors the OpenAI
|
|
143
|
+
* models list shape DeepSeek copied — `id` is the model name to pass to
|
|
144
|
+
* `/chat/completions`, `owned_by` is the provider string (always
|
|
145
|
+
* `"deepseek"` today).
|
|
146
|
+
*/
|
|
147
|
+
interface ModelInfo {
|
|
148
|
+
id: string;
|
|
149
|
+
object: "model";
|
|
150
|
+
owned_by: string;
|
|
151
|
+
}
|
|
152
|
+
interface ModelList {
|
|
153
|
+
object: "list";
|
|
154
|
+
data: ModelInfo[];
|
|
155
|
+
}
|
|
141
156
|
interface DeepSeekClientOptions {
|
|
142
157
|
apiKey?: string;
|
|
143
158
|
baseUrl?: string;
|
|
@@ -163,6 +178,16 @@ declare class DeepSeekClient {
|
|
|
163
178
|
getBalance(opts?: {
|
|
164
179
|
signal?: AbortSignal;
|
|
165
180
|
}): Promise<UserBalance | null>;
|
|
181
|
+
/**
|
|
182
|
+
* Fetch the model catalog DeepSeek currently exposes. Today this is
|
|
183
|
+
* `deepseek-chat` (V3) and `deepseek-reasoner` (R1), but querying is
|
|
184
|
+
* the only way to learn about new ones without a Reasonix release.
|
|
185
|
+
* Returns null on any network/auth failure so callers can degrade
|
|
186
|
+
* gracefully — e.g. `/models` falls back to the hardcoded hint.
|
|
187
|
+
*/
|
|
188
|
+
listModels(opts?: {
|
|
189
|
+
signal?: AbortSignal;
|
|
190
|
+
}): Promise<ModelList | null>;
|
|
166
191
|
chat(opts: ChatRequestOptions): Promise<ChatResponse>;
|
|
167
192
|
stream(opts: ChatRequestOptions): AsyncGenerator<StreamChunk>;
|
|
168
193
|
}
|
|
@@ -708,6 +733,7 @@ declare class ToolRegistry {
|
|
|
708
733
|
specs(): ToolSpec[];
|
|
709
734
|
dispatch(name: string, argumentsRaw: string | Record<string, unknown>, opts?: {
|
|
710
735
|
signal?: AbortSignal;
|
|
736
|
+
maxResultChars?: number;
|
|
711
737
|
}): Promise<string>;
|
|
712
738
|
}
|
|
713
739
|
|
package/dist/index.js
CHANGED
|
@@ -154,6 +154,28 @@ var DeepSeekClient = class {
|
|
|
154
154
|
return null;
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Fetch the model catalog DeepSeek currently exposes. Today this is
|
|
159
|
+
* `deepseek-chat` (V3) and `deepseek-reasoner` (R1), but querying is
|
|
160
|
+
* the only way to learn about new ones without a Reasonix release.
|
|
161
|
+
* Returns null on any network/auth failure so callers can degrade
|
|
162
|
+
* gracefully — e.g. `/models` falls back to the hardcoded hint.
|
|
163
|
+
*/
|
|
164
|
+
async listModels(opts = {}) {
|
|
165
|
+
try {
|
|
166
|
+
const resp = await this._fetch(`${this.baseUrl}/models`, {
|
|
167
|
+
method: "GET",
|
|
168
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
169
|
+
signal: opts.signal
|
|
170
|
+
});
|
|
171
|
+
if (!resp.ok) return null;
|
|
172
|
+
const data = await resp.json();
|
|
173
|
+
if (!data || !Array.isArray(data.data)) return null;
|
|
174
|
+
return data;
|
|
175
|
+
} catch {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
157
179
|
async chat(opts) {
|
|
158
180
|
const ctrl = new AbortController();
|
|
159
181
|
const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
|
|
@@ -744,7 +766,8 @@ var ToolRegistry = class {
|
|
|
744
766
|
}
|
|
745
767
|
try {
|
|
746
768
|
const result = await tool.fn(args, { signal: opts.signal });
|
|
747
|
-
|
|
769
|
+
const str = typeof result === "string" ? result : JSON.stringify(result);
|
|
770
|
+
return opts.maxResultChars ? truncateForModel(str, opts.maxResultChars) : str;
|
|
748
771
|
} catch (err) {
|
|
749
772
|
const e = err;
|
|
750
773
|
if (typeof e.toToolResult === "function") {
|
|
@@ -1314,8 +1337,8 @@ function countLines(path) {
|
|
|
1314
1337
|
|
|
1315
1338
|
// src/telemetry.ts
|
|
1316
1339
|
var DEEPSEEK_PRICING = {
|
|
1317
|
-
"deepseek-chat": { inputCacheHit: 0.
|
|
1318
|
-
"deepseek-reasoner": { inputCacheHit: 0.
|
|
1340
|
+
"deepseek-chat": { inputCacheHit: 0.028, inputCacheMiss: 0.28, output: 0.42 },
|
|
1341
|
+
"deepseek-reasoner": { inputCacheHit: 0.028, inputCacheMiss: 0.28, output: 0.42 }
|
|
1319
1342
|
};
|
|
1320
1343
|
var CLAUDE_SONNET_PRICING = { input: 3, output: 15 };
|
|
1321
1344
|
var DEEPSEEK_CONTEXT_TOKENS = {
|
|
@@ -1870,6 +1893,24 @@ var CacheFirstLoop = class {
|
|
|
1870
1893
|
return;
|
|
1871
1894
|
}
|
|
1872
1895
|
const ctxMax = DEEPSEEK_CONTEXT_TOKENS[this.model] ?? DEFAULT_CONTEXT_TOKENS;
|
|
1896
|
+
if (usage) {
|
|
1897
|
+
const ratio = usage.promptTokens / ctxMax;
|
|
1898
|
+
if (ratio > 0.6 && ratio <= 0.8) {
|
|
1899
|
+
const before = usage.promptTokens;
|
|
1900
|
+
const soft = this.compact(16e3);
|
|
1901
|
+
if (soft.healedCount > 0) {
|
|
1902
|
+
const approxSaved = Math.round(soft.charsSaved / 4);
|
|
1903
|
+
const after = Math.max(0, before - approxSaved);
|
|
1904
|
+
yield {
|
|
1905
|
+
turn: this._turn,
|
|
1906
|
+
role: "warning",
|
|
1907
|
+
content: `context ${before.toLocaleString()}/${ctxMax.toLocaleString()} (${Math.round(
|
|
1908
|
+
ratio * 100
|
|
1909
|
+
)}%) \u2014 proactively compacted ${soft.healedCount} tool result(s) to 16k, saved ~${approxSaved.toLocaleString()} tokens (now ~${after.toLocaleString()}). Staying ahead of the 80% guard.`
|
|
1910
|
+
};
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1873
1914
|
if (usage && usage.promptTokens / ctxMax > 0.8) {
|
|
1874
1915
|
const before = usage.promptTokens;
|
|
1875
1916
|
const compactResult = this.compact(4e3);
|
|
@@ -1932,7 +1973,10 @@ var CacheFirstLoop = class {
|
|
|
1932
1973
|
result = `[hook block] ${blocking?.hook.command ?? "<unknown>"}
|
|
1933
1974
|
${reason}`;
|
|
1934
1975
|
} else {
|
|
1935
|
-
result = await this.tools.dispatch(name, args, {
|
|
1976
|
+
result = await this.tools.dispatch(name, args, {
|
|
1977
|
+
signal,
|
|
1978
|
+
maxResultChars: DEFAULT_MAX_RESULT_CHARS
|
|
1979
|
+
});
|
|
1936
1980
|
const postReport = await runHooks({
|
|
1937
1981
|
hooks: this.hooks,
|
|
1938
1982
|
payload: {
|