@este.systems/dsc 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 +408 -0
- package/bin/dsc.mjs +29 -0
- package/dist/agent.js +259 -0
- package/dist/agent.js.map +1 -0
- package/dist/api.js +333 -0
- package/dist/api.js.map +1 -0
- package/dist/approval.js +79 -0
- package/dist/approval.js.map +1 -0
- package/dist/audit.js +26 -0
- package/dist/audit.js.map +1 -0
- package/dist/compact.js +100 -0
- package/dist/compact.js.map +1 -0
- package/dist/history.js +212 -0
- package/dist/history.js.map +1 -0
- package/dist/index.js +830 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown.js +543 -0
- package/dist/markdown.js.map +1 -0
- package/dist/prompt.js +44 -0
- package/dist/prompt.js.map +1 -0
- package/dist/repl_history.js +55 -0
- package/dist/repl_history.js.map +1 -0
- package/dist/search.js +215 -0
- package/dist/search.js.map +1 -0
- package/dist/tools.js +670 -0
- package/dist/tools.js.map +1 -0
- package/dist/ui.js +165 -0
- package/dist/ui.js.map +1 -0
- package/package.json +57 -0
package/dist/agent.js
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { chatStream, computeCostUsd, recordUsage, } from "./api.js";
|
|
2
|
+
import { READ_ONLY_TOOLS, TOOL_SCHEMAS, executeTool } from "./tools.js";
|
|
3
|
+
import { Spinner } from "./ui.js";
|
|
4
|
+
import { MarkdownRenderer } from "./markdown.js";
|
|
5
|
+
import { buildSystemPrompt } from "./prompt.js";
|
|
6
|
+
// How many tool calls we let the agent chain in one user turn before we stop
|
|
7
|
+
// it. Set high enough that real coding tasks (read several files, search, run
|
|
8
|
+
// tests, write a patch, run tests again, commit) can finish in one turn; low
|
|
9
|
+
// enough to catch runaway loops where the model fails to converge.
|
|
10
|
+
export const MAX_TOOL_DEPTH = 24;
|
|
11
|
+
const DIM = "\x1b[2m";
|
|
12
|
+
const BOLD = "\x1b[1m";
|
|
13
|
+
const ITALIC = "\x1b[3m";
|
|
14
|
+
const RED = "\x1b[31m";
|
|
15
|
+
const RESET = "\x1b[0m";
|
|
16
|
+
function streamHandlers(spinner, showReasoning, assistantLabel) {
|
|
17
|
+
let contentStarted = false;
|
|
18
|
+
let reasoningStarted = false;
|
|
19
|
+
const renderer = new MarkdownRenderer();
|
|
20
|
+
return {
|
|
21
|
+
onContent: (text) => {
|
|
22
|
+
spinner.bump();
|
|
23
|
+
if (!contentStarted) {
|
|
24
|
+
spinner.stop();
|
|
25
|
+
if (reasoningStarted) {
|
|
26
|
+
// Close the reasoning block (reset styling, blank line) before the answer.
|
|
27
|
+
process.stdout.write(`${RESET}\n\n`);
|
|
28
|
+
}
|
|
29
|
+
process.stdout.write(`${BOLD}${assistantLabel}${RESET} `);
|
|
30
|
+
contentStarted = true;
|
|
31
|
+
}
|
|
32
|
+
process.stdout.write(renderer.push(text));
|
|
33
|
+
},
|
|
34
|
+
onReasoning: (text) => {
|
|
35
|
+
spinner.bump();
|
|
36
|
+
if (!showReasoning)
|
|
37
|
+
return; // hidden — keep the spinner alive though
|
|
38
|
+
if (contentStarted)
|
|
39
|
+
return; // ignore stray reasoning after content has started
|
|
40
|
+
if (!reasoningStarted) {
|
|
41
|
+
spinner.stop();
|
|
42
|
+
process.stdout.write(`${DIM}reasoning${RESET}\n${DIM}${ITALIC} `);
|
|
43
|
+
reasoningStarted = true;
|
|
44
|
+
}
|
|
45
|
+
// Indent every newline within the chunk so multi-line reasoning aligns.
|
|
46
|
+
process.stdout.write(text.replace(/\n/g, "\n "));
|
|
47
|
+
},
|
|
48
|
+
flush: () => {
|
|
49
|
+
if (contentStarted) {
|
|
50
|
+
process.stdout.write(renderer.flush());
|
|
51
|
+
process.stdout.write("\n");
|
|
52
|
+
}
|
|
53
|
+
else if (reasoningStarted) {
|
|
54
|
+
process.stdout.write(`${RESET}\n`);
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export async function runAgent(opts) {
|
|
60
|
+
const { messages, model, stats, toolCtx, signal, onTurn } = opts;
|
|
61
|
+
const showReasoning = opts.showReasoning ?? true;
|
|
62
|
+
const assistantLabel = opts.assistantLabel ?? "assistant:";
|
|
63
|
+
// Build the message list to send: drop any leading system entry the caller
|
|
64
|
+
// may have stashed (e.g. from an older session) and prepend a freshly-built
|
|
65
|
+
// one so cwd/date/status reflect the current turn.
|
|
66
|
+
const conversationMessages = () => messages[0]?.role === "system" ? messages.slice(1) : messages.slice();
|
|
67
|
+
const buildApi = () => [
|
|
68
|
+
{
|
|
69
|
+
role: "system",
|
|
70
|
+
content: buildSystemPrompt({
|
|
71
|
+
cwd: toolCtx.cwd,
|
|
72
|
+
date: new Date(),
|
|
73
|
+
statusLine: opts.getStatusLine?.(),
|
|
74
|
+
summary: opts.getSummary?.(),
|
|
75
|
+
}),
|
|
76
|
+
},
|
|
77
|
+
...repairToolCallPairing(conversationMessages()),
|
|
78
|
+
];
|
|
79
|
+
for (let depth = 0; depth < MAX_TOOL_DEPTH; depth++) {
|
|
80
|
+
stats.prompts += 1;
|
|
81
|
+
const spinner = new Spinner("thinking");
|
|
82
|
+
spinner.start();
|
|
83
|
+
const handlers = streamHandlers(spinner, showReasoning, assistantLabel);
|
|
84
|
+
let resp;
|
|
85
|
+
try {
|
|
86
|
+
resp = await chatStream({
|
|
87
|
+
model,
|
|
88
|
+
messages: buildApi(),
|
|
89
|
+
tools: TOOL_SCHEMAS,
|
|
90
|
+
signal,
|
|
91
|
+
onContent: handlers.onContent,
|
|
92
|
+
onReasoning: handlers.onReasoning,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
spinner.stop();
|
|
97
|
+
}
|
|
98
|
+
handlers.flush();
|
|
99
|
+
recordUsage(stats, resp.usage);
|
|
100
|
+
const choice = resp.choices[0];
|
|
101
|
+
const msg = choice.message;
|
|
102
|
+
const content = msg.content ?? "";
|
|
103
|
+
const assistantMsg = { role: "assistant", content };
|
|
104
|
+
if (msg.reasoning_content)
|
|
105
|
+
assistantMsg.reasoning_content = msg.reasoning_content;
|
|
106
|
+
if (msg.tool_calls && msg.tool_calls.length)
|
|
107
|
+
assistantMsg.tool_calls = msg.tool_calls;
|
|
108
|
+
messages.push(assistantMsg);
|
|
109
|
+
onTurn?.(); // status reflects the just-pushed assistant message
|
|
110
|
+
if (!msg.tool_calls || msg.tool_calls.length === 0) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const toolCalls = msg.tool_calls;
|
|
114
|
+
for (let i = 0; i < toolCalls.length; i++) {
|
|
115
|
+
const call = toolCalls[i];
|
|
116
|
+
const name = call.function.name;
|
|
117
|
+
const argsRaw = call.function.arguments ?? "{}";
|
|
118
|
+
process.stdout.write(`${DIM}→ ${name}(${truncate(argsRaw, 200)})${RESET}\n`);
|
|
119
|
+
stats.tool_calls_total += 1;
|
|
120
|
+
stats.tool_calls_by_name[name] = (stats.tool_calls_by_name[name] ?? 0) + 1;
|
|
121
|
+
const toolSpinner = new Spinner(`running ${name}`);
|
|
122
|
+
// Don't spin tools that need approval (interactive prompt).
|
|
123
|
+
const interactive = !READ_ONLY_TOOLS.has(name) && !toolCtx.yolo;
|
|
124
|
+
if (!interactive)
|
|
125
|
+
toolSpinner.start();
|
|
126
|
+
let result;
|
|
127
|
+
let throwAfter = null;
|
|
128
|
+
try {
|
|
129
|
+
result = await executeTool(name, argsRaw, toolCtx, signal);
|
|
130
|
+
}
|
|
131
|
+
catch (e) {
|
|
132
|
+
// Convert the throw into a synthetic tool result so the assistant's
|
|
133
|
+
// tool_call gets a corresponding tool message — without that, the
|
|
134
|
+
// next API call 400s with "tool_calls must be followed by tool
|
|
135
|
+
// messages". The original error is re-thrown after we record it.
|
|
136
|
+
throwAfter = e;
|
|
137
|
+
const isAbort = e instanceof Error &&
|
|
138
|
+
(e.name === "AbortError" || e.code === "ABORT_ERR");
|
|
139
|
+
result = {
|
|
140
|
+
content: isAbort ? "interrupted" : `error: ${e.message ?? "tool failed"}`,
|
|
141
|
+
rejected: isAbort,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
toolSpinner.stop();
|
|
146
|
+
}
|
|
147
|
+
messages.push({
|
|
148
|
+
role: "tool",
|
|
149
|
+
tool_call_id: call.id,
|
|
150
|
+
content: result.content,
|
|
151
|
+
});
|
|
152
|
+
onTurn?.(); // status reflects the tool result we just recorded
|
|
153
|
+
const lead = result.content.startsWith("error:") || result.rejected ? RED : DIM;
|
|
154
|
+
process.stdout.write(`${lead} ${truncate(result.content, 400)}${RESET}\n`);
|
|
155
|
+
if (throwAfter) {
|
|
156
|
+
// Stub-fill any remaining tool_calls before propagating, otherwise
|
|
157
|
+
// the persisted history will still 400 on the next turn.
|
|
158
|
+
for (let j = i + 1; j < toolCalls.length; j++) {
|
|
159
|
+
messages.push({
|
|
160
|
+
role: "tool",
|
|
161
|
+
tool_call_id: toolCalls[j].id,
|
|
162
|
+
content: "skipped: previous tool was interrupted",
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
throw throwAfter;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Out of tool-call budget. We used to call the API again with `tools:
|
|
170
|
+
// undefined` and a "no more tools, summarize" user message — but the model
|
|
171
|
+
// routinely ignored that and emitted raw tool-call markup as plain text,
|
|
172
|
+
// which printed verbatim and looked broken. Better to stop cleanly here:
|
|
173
|
+
// the conversation history is consistent, the user can ask "continue" if
|
|
174
|
+
// they want to give it another budget.
|
|
175
|
+
process.stdout.write(`${DIM}(reached MAX_TOOL_DEPTH=${MAX_TOOL_DEPTH}; stopping. Send 'continue' if you want to give the agent another budget.)${RESET}\n`);
|
|
176
|
+
onTurn?.();
|
|
177
|
+
}
|
|
178
|
+
export function formatCost(stats, model) {
|
|
179
|
+
const cost = computeCostUsd(stats, model);
|
|
180
|
+
return `cost: $${cost.toFixed(4)} in: ${stats.prompt_tokens} (hit ${stats.cache_hit_tokens} / miss ${stats.cache_miss_tokens}) out: ${stats.completion_tokens} tools: ${stats.tool_calls_total}`;
|
|
181
|
+
}
|
|
182
|
+
export function formatStatus(stats, model, opts) {
|
|
183
|
+
const cost = computeCostUsd(stats, model);
|
|
184
|
+
const flags = (opts.yolo ? " yolo" : "") +
|
|
185
|
+
(opts.reasoning === false ? " no-reasoning" : "") +
|
|
186
|
+
(opts.compacted ? " compacted" : "");
|
|
187
|
+
const ctx = opts.contextTokens !== undefined ? ` ctx:${formatCount(opts.contextTokens)}` : "";
|
|
188
|
+
const session = opts.sessionSeconds !== undefined ? ` ${formatDuration(opts.sessionSeconds)}` : "";
|
|
189
|
+
return `${model}${flags} · $${cost.toFixed(4)} in: ${stats.prompt_tokens} (hit ${stats.cache_hit_tokens} / miss ${stats.cache_miss_tokens}) out: ${stats.completion_tokens} tools: ${stats.tool_calls_total}${ctx}${session}`;
|
|
190
|
+
}
|
|
191
|
+
// Rough estimate based on stored message bodies; 1 token ≈ 4 chars.
|
|
192
|
+
export function estimateContextTokens(messages) {
|
|
193
|
+
let total = 0;
|
|
194
|
+
for (const m of messages) {
|
|
195
|
+
if (typeof m.content === "string")
|
|
196
|
+
total += Math.ceil(m.content.length / 4);
|
|
197
|
+
if (typeof m.reasoning_content === "string")
|
|
198
|
+
total += Math.ceil(m.reasoning_content.length / 4);
|
|
199
|
+
}
|
|
200
|
+
return total;
|
|
201
|
+
}
|
|
202
|
+
function formatCount(n) {
|
|
203
|
+
if (n >= 1_000_000)
|
|
204
|
+
return (n / 1_000_000).toFixed(1) + "M";
|
|
205
|
+
if (n >= 1_000)
|
|
206
|
+
return (n / 1_000).toFixed(1) + "K";
|
|
207
|
+
return String(n);
|
|
208
|
+
}
|
|
209
|
+
function formatDuration(s) {
|
|
210
|
+
const h = Math.floor(s / 3600);
|
|
211
|
+
const m = Math.floor((s % 3600) / 60);
|
|
212
|
+
const sec = s % 60;
|
|
213
|
+
if (h > 0)
|
|
214
|
+
return `${h}:${String(m).padStart(2, "0")}:${String(sec).padStart(2, "0")}`;
|
|
215
|
+
return `${m}:${String(sec).padStart(2, "0")}`;
|
|
216
|
+
}
|
|
217
|
+
function truncate(s, n) {
|
|
218
|
+
return s.length <= n ? s : s.slice(0, n) + "…";
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Synthesize stub tool messages for any assistant.tool_calls that don't have
|
|
222
|
+
* a corresponding tool response further in the message list.
|
|
223
|
+
*
|
|
224
|
+
* Without this, a session that was previously interrupted after the assistant
|
|
225
|
+
* called a tool (but before the tool message landed) will keep 400-ing on
|
|
226
|
+
* every subsequent turn: the API enforces "an assistant message with
|
|
227
|
+
* 'tool_calls' must be followed by tool messages responding to each
|
|
228
|
+
* 'tool_call_id'". This recovers transparently per call.
|
|
229
|
+
*/
|
|
230
|
+
function repairToolCallPairing(messages) {
|
|
231
|
+
const out = [];
|
|
232
|
+
for (let i = 0; i < messages.length; i++) {
|
|
233
|
+
const m = messages[i];
|
|
234
|
+
out.push(m);
|
|
235
|
+
if (m.role !== "assistant" || !m.tool_calls || !m.tool_calls.length)
|
|
236
|
+
continue;
|
|
237
|
+
const seen = new Set();
|
|
238
|
+
let j = i + 1;
|
|
239
|
+
while (j < messages.length && messages[j].role === "tool") {
|
|
240
|
+
out.push(messages[j]);
|
|
241
|
+
const id = messages[j].tool_call_id;
|
|
242
|
+
if (id)
|
|
243
|
+
seen.add(id);
|
|
244
|
+
j++;
|
|
245
|
+
}
|
|
246
|
+
for (const tc of m.tool_calls) {
|
|
247
|
+
if (!seen.has(tc.id)) {
|
|
248
|
+
out.push({
|
|
249
|
+
role: "tool",
|
|
250
|
+
tool_call_id: tc.id,
|
|
251
|
+
content: "(no response — recovered from interrupted turn)",
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
i = j - 1; // skip the tool messages we already consumed
|
|
256
|
+
}
|
|
257
|
+
return out;
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
export const API_URL = "https://api.deepseek.com/chat/completions";
|
|
2
|
+
export const AVAILABLE_MODELS = ["deepseek-v4-pro", "deepseek-v4-flash"];
|
|
3
|
+
export const DEFAULT_MODEL = "deepseek-v4-pro";
|
|
4
|
+
// USD per token. v4-pro figures are discounted (valid through 2026-05-31), copied from godot-assistant.
|
|
5
|
+
export const MODEL_RATES = {
|
|
6
|
+
"deepseek-v4-pro": { in_hit: 0.0034e-6, in_miss: 0.414e-6, out: 0.828e-6 },
|
|
7
|
+
"deepseek-v4-flash": { in_hit: 0.0028e-6, in_miss: 0.138e-6, out: 0.276e-6 },
|
|
8
|
+
};
|
|
9
|
+
export class DeepSeekError extends Error {
|
|
10
|
+
status;
|
|
11
|
+
body;
|
|
12
|
+
constructor(message, status, body) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.status = status;
|
|
15
|
+
this.body = body;
|
|
16
|
+
this.name = "DeepSeekError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
import { readFileSync } from "node:fs";
|
|
20
|
+
import { homedir } from "node:os";
|
|
21
|
+
import * as nodePath from "node:path";
|
|
22
|
+
export function configPath() {
|
|
23
|
+
const xdg = process.env.XDG_CONFIG_HOME;
|
|
24
|
+
const base = xdg && xdg.length ? xdg : nodePath.join(homedir(), ".config");
|
|
25
|
+
return nodePath.join(base, "deepseek", "deepseek.json");
|
|
26
|
+
}
|
|
27
|
+
let _cachedKey;
|
|
28
|
+
let _cachedConfig;
|
|
29
|
+
// Returns the parsed deepseek.json (cached). null when the file doesn't exist;
|
|
30
|
+
// throws DeepSeekError on invalid JSON. Shared by getApiKey and the search
|
|
31
|
+
// module so secrets and provider config can live in one place.
|
|
32
|
+
export function getConfig() {
|
|
33
|
+
if (_cachedConfig !== undefined)
|
|
34
|
+
return _cachedConfig;
|
|
35
|
+
const p = configPath();
|
|
36
|
+
let text;
|
|
37
|
+
try {
|
|
38
|
+
text = readFileSync(p, "utf8");
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
_cachedConfig = null;
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
let data;
|
|
45
|
+
try {
|
|
46
|
+
data = JSON.parse(text);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
throw new DeepSeekError(`config file is not valid JSON: ${p}`);
|
|
50
|
+
}
|
|
51
|
+
if (!data || typeof data !== "object") {
|
|
52
|
+
_cachedConfig = null;
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
_cachedConfig = data;
|
|
56
|
+
return _cachedConfig;
|
|
57
|
+
}
|
|
58
|
+
function readKeyFromFile() {
|
|
59
|
+
const obj = getConfig();
|
|
60
|
+
if (!obj)
|
|
61
|
+
return null;
|
|
62
|
+
// Accept several shapes:
|
|
63
|
+
// {"api_key": "sk-..."}
|
|
64
|
+
// {"DEEPSEEK_API_KEY": "sk-..."}
|
|
65
|
+
// {"env": {"DEEPSEEK_API_KEY": "sk-..."}} (dsc-style env block)
|
|
66
|
+
// {"env": {"ANTHROPIC_AUTH_TOKEN": "sk-..."}} (claude-switcher compatible)
|
|
67
|
+
const env = (obj.env && typeof obj.env === "object" ? obj.env : {});
|
|
68
|
+
const candidate = obj.api_key ??
|
|
69
|
+
obj.DEEPSEEK_API_KEY ??
|
|
70
|
+
env.DEEPSEEK_API_KEY ??
|
|
71
|
+
env.ANTHROPIC_AUTH_TOKEN;
|
|
72
|
+
if (typeof candidate === "string" && candidate.length)
|
|
73
|
+
return candidate;
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
export function getApiKey() {
|
|
77
|
+
if (_cachedKey)
|
|
78
|
+
return _cachedKey;
|
|
79
|
+
const envKey = process.env.DEEPSEEK_API_KEY;
|
|
80
|
+
if (envKey) {
|
|
81
|
+
_cachedKey = envKey;
|
|
82
|
+
return envKey;
|
|
83
|
+
}
|
|
84
|
+
const fileKey = readKeyFromFile();
|
|
85
|
+
if (fileKey) {
|
|
86
|
+
_cachedKey = fileKey;
|
|
87
|
+
return fileKey;
|
|
88
|
+
}
|
|
89
|
+
throw new DeepSeekError(`DEEPSEEK_API_KEY is not set and no key found in ${configPath()}.\n` +
|
|
90
|
+
` Either export DEEPSEEK_API_KEY, or create that file containing:\n` +
|
|
91
|
+
` {"api_key": "sk-..."}\n` +
|
|
92
|
+
` (also accepts {"env": {"ANTHROPIC_AUTH_TOKEN": "sk-..."}} for claude-switcher compat).`);
|
|
93
|
+
}
|
|
94
|
+
export function hasApiKey() {
|
|
95
|
+
if (process.env.DEEPSEEK_API_KEY)
|
|
96
|
+
return true;
|
|
97
|
+
try {
|
|
98
|
+
return readKeyFromFile() !== null;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export async function chat(opts) {
|
|
105
|
+
const apiKey = getApiKey();
|
|
106
|
+
const body = {
|
|
107
|
+
model: opts.model,
|
|
108
|
+
messages: opts.messages,
|
|
109
|
+
stream: false,
|
|
110
|
+
};
|
|
111
|
+
if (opts.tools && opts.tools.length)
|
|
112
|
+
body.tools = opts.tools;
|
|
113
|
+
const res = await fetch(API_URL, {
|
|
114
|
+
method: "POST",
|
|
115
|
+
headers: {
|
|
116
|
+
"Content-Type": "application/json",
|
|
117
|
+
Authorization: `Bearer ${apiKey}`,
|
|
118
|
+
},
|
|
119
|
+
body: JSON.stringify(body),
|
|
120
|
+
signal: opts.signal,
|
|
121
|
+
});
|
|
122
|
+
const text = await res.text();
|
|
123
|
+
if (!res.ok) {
|
|
124
|
+
throw new DeepSeekError(`HTTP ${res.status}`, res.status, text);
|
|
125
|
+
}
|
|
126
|
+
let parsed;
|
|
127
|
+
try {
|
|
128
|
+
parsed = JSON.parse(text);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
throw new DeepSeekError(`Invalid JSON response: ${text.slice(0, 200)}`);
|
|
132
|
+
}
|
|
133
|
+
if (!parsed.choices || parsed.choices.length === 0) {
|
|
134
|
+
throw new DeepSeekError("Empty choices in response");
|
|
135
|
+
}
|
|
136
|
+
return parsed;
|
|
137
|
+
}
|
|
138
|
+
const RETRY_STATUSES = new Set([429, 502, 503, 504]);
|
|
139
|
+
const MAX_RETRY_ATTEMPTS = 3;
|
|
140
|
+
const DIM = "\x1b[2m";
|
|
141
|
+
const RESET = "\x1b[0m";
|
|
142
|
+
function isAbortError(e) {
|
|
143
|
+
return e instanceof Error && (e.name === "AbortError" || e.code === "ABORT_ERR");
|
|
144
|
+
}
|
|
145
|
+
function isRetriableNetworkError(e) {
|
|
146
|
+
// fetch() throws TypeError for network errors in undici (Node 18+).
|
|
147
|
+
if (!(e instanceof Error))
|
|
148
|
+
return false;
|
|
149
|
+
if (e.name === "TypeError")
|
|
150
|
+
return true;
|
|
151
|
+
const code = e.cause?.code;
|
|
152
|
+
return code === "ECONNRESET" || code === "ETIMEDOUT" || code === "ECONNREFUSED" || code === "ENOTFOUND";
|
|
153
|
+
}
|
|
154
|
+
function sleep(ms, signal) {
|
|
155
|
+
return new Promise((resolve, reject) => {
|
|
156
|
+
if (signal?.aborted)
|
|
157
|
+
return reject(new DOMException("Aborted", "AbortError"));
|
|
158
|
+
const t = setTimeout(resolve, ms);
|
|
159
|
+
signal?.addEventListener("abort", () => {
|
|
160
|
+
clearTimeout(t);
|
|
161
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
162
|
+
}, { once: true });
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
export async function chatStream(opts) {
|
|
166
|
+
for (let attempt = 1;; attempt++) {
|
|
167
|
+
try {
|
|
168
|
+
return await streamOnce(opts);
|
|
169
|
+
}
|
|
170
|
+
catch (e) {
|
|
171
|
+
if (isAbortError(e))
|
|
172
|
+
throw e;
|
|
173
|
+
const transient = (e instanceof DeepSeekError && e.status !== undefined && RETRY_STATUSES.has(e.status)) ||
|
|
174
|
+
isRetriableNetworkError(e);
|
|
175
|
+
if (!transient || attempt >= MAX_RETRY_ATTEMPTS)
|
|
176
|
+
throw e;
|
|
177
|
+
const delay = 1000 * Math.pow(2, attempt - 1);
|
|
178
|
+
const reason = e instanceof DeepSeekError && e.status ? `HTTP ${e.status}` : e.message;
|
|
179
|
+
process.stderr.write(`${DIM}(${reason}; retrying in ${Math.round(delay / 1000)}s, attempt ${attempt + 1}/${MAX_RETRY_ATTEMPTS})${RESET}\n`);
|
|
180
|
+
await sleep(delay, opts.signal);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
async function streamOnce(opts) {
|
|
185
|
+
const apiKey = getApiKey();
|
|
186
|
+
const body = {
|
|
187
|
+
model: opts.model,
|
|
188
|
+
messages: opts.messages,
|
|
189
|
+
stream: true,
|
|
190
|
+
stream_options: { include_usage: true },
|
|
191
|
+
};
|
|
192
|
+
if (opts.tools && opts.tools.length)
|
|
193
|
+
body.tools = opts.tools;
|
|
194
|
+
const res = await fetch(API_URL, {
|
|
195
|
+
method: "POST",
|
|
196
|
+
headers: {
|
|
197
|
+
"Content-Type": "application/json",
|
|
198
|
+
Authorization: `Bearer ${apiKey}`,
|
|
199
|
+
Accept: "text/event-stream",
|
|
200
|
+
},
|
|
201
|
+
body: JSON.stringify(body),
|
|
202
|
+
signal: opts.signal,
|
|
203
|
+
});
|
|
204
|
+
if (!res.ok) {
|
|
205
|
+
const text = await res.text();
|
|
206
|
+
throw new DeepSeekError(`HTTP ${res.status}`, res.status, text);
|
|
207
|
+
}
|
|
208
|
+
if (!res.body) {
|
|
209
|
+
throw new DeepSeekError("No response body for stream");
|
|
210
|
+
}
|
|
211
|
+
let content = "";
|
|
212
|
+
let reasoning = "";
|
|
213
|
+
const toolCalls = [];
|
|
214
|
+
let finishReason;
|
|
215
|
+
let usage;
|
|
216
|
+
const reader = res.body.getReader();
|
|
217
|
+
const decoder = new TextDecoder("utf-8");
|
|
218
|
+
let buf = "";
|
|
219
|
+
while (true) {
|
|
220
|
+
const { done, value } = await reader.read();
|
|
221
|
+
if (done)
|
|
222
|
+
break;
|
|
223
|
+
buf += decoder.decode(value, { stream: true });
|
|
224
|
+
let nl;
|
|
225
|
+
while ((nl = buf.indexOf("\n")) >= 0) {
|
|
226
|
+
const rawLine = buf.slice(0, nl).replace(/\r$/, "");
|
|
227
|
+
buf = buf.slice(nl + 1);
|
|
228
|
+
if (!rawLine || rawLine.startsWith(":"))
|
|
229
|
+
continue;
|
|
230
|
+
if (!rawLine.startsWith("data:"))
|
|
231
|
+
continue;
|
|
232
|
+
const data = rawLine.slice(5).trim();
|
|
233
|
+
if (data === "[DONE]")
|
|
234
|
+
continue;
|
|
235
|
+
let evt;
|
|
236
|
+
try {
|
|
237
|
+
evt = JSON.parse(data);
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (evt.usage)
|
|
243
|
+
usage = evt.usage;
|
|
244
|
+
const choice = evt.choices?.[0];
|
|
245
|
+
if (!choice)
|
|
246
|
+
continue;
|
|
247
|
+
if (choice.finish_reason)
|
|
248
|
+
finishReason = choice.finish_reason;
|
|
249
|
+
const delta = choice.delta;
|
|
250
|
+
if (!delta)
|
|
251
|
+
continue;
|
|
252
|
+
if (typeof delta.content === "string" && delta.content.length) {
|
|
253
|
+
content += delta.content;
|
|
254
|
+
opts.onContent?.(delta.content);
|
|
255
|
+
}
|
|
256
|
+
if (typeof delta.reasoning_content === "string" && delta.reasoning_content.length) {
|
|
257
|
+
reasoning += delta.reasoning_content;
|
|
258
|
+
opts.onReasoning?.(delta.reasoning_content);
|
|
259
|
+
}
|
|
260
|
+
if (Array.isArray(delta.tool_calls)) {
|
|
261
|
+
for (const tc of delta.tool_calls) {
|
|
262
|
+
const idx = tc.index ?? 0;
|
|
263
|
+
if (!toolCalls[idx])
|
|
264
|
+
toolCalls[idx] = { function: { name: "", arguments: "" } };
|
|
265
|
+
const acc = toolCalls[idx];
|
|
266
|
+
if (tc.id)
|
|
267
|
+
acc.id = tc.id;
|
|
268
|
+
if (tc.type)
|
|
269
|
+
acc.type = tc.type;
|
|
270
|
+
if (tc.function?.name)
|
|
271
|
+
acc.function.name += tc.function.name;
|
|
272
|
+
if (tc.function?.arguments)
|
|
273
|
+
acc.function.arguments += tc.function.arguments;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
const finalToolCalls = toolCalls
|
|
279
|
+
.filter((t) => t && t.function?.name)
|
|
280
|
+
.map((t, i) => ({
|
|
281
|
+
id: t.id ?? `call_${i}`,
|
|
282
|
+
type: "function",
|
|
283
|
+
function: { name: t.function.name, arguments: t.function.arguments || "{}" },
|
|
284
|
+
}));
|
|
285
|
+
return {
|
|
286
|
+
choices: [
|
|
287
|
+
{
|
|
288
|
+
message: {
|
|
289
|
+
role: "assistant",
|
|
290
|
+
content: content || null,
|
|
291
|
+
tool_calls: finalToolCalls.length ? finalToolCalls : undefined,
|
|
292
|
+
reasoning_content: reasoning || undefined,
|
|
293
|
+
},
|
|
294
|
+
finish_reason: finishReason,
|
|
295
|
+
},
|
|
296
|
+
],
|
|
297
|
+
usage,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
export function newStats() {
|
|
301
|
+
return {
|
|
302
|
+
prompts: 0,
|
|
303
|
+
responses: 0,
|
|
304
|
+
prompt_tokens: 0,
|
|
305
|
+
completion_tokens: 0,
|
|
306
|
+
total_tokens: 0,
|
|
307
|
+
cache_hit_tokens: 0,
|
|
308
|
+
cache_miss_tokens: 0,
|
|
309
|
+
tool_calls_total: 0,
|
|
310
|
+
tool_calls_by_name: {},
|
|
311
|
+
files_touched: new Set(),
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
export function recordUsage(stats, usage) {
|
|
315
|
+
stats.responses += 1;
|
|
316
|
+
if (!usage)
|
|
317
|
+
return;
|
|
318
|
+
stats.prompt_tokens += usage.prompt_tokens ?? 0;
|
|
319
|
+
stats.completion_tokens += usage.completion_tokens ?? 0;
|
|
320
|
+
stats.total_tokens += usage.total_tokens ?? 0;
|
|
321
|
+
stats.cache_hit_tokens += usage.prompt_cache_hit_tokens ?? 0;
|
|
322
|
+
stats.cache_miss_tokens += usage.prompt_cache_miss_tokens ?? 0;
|
|
323
|
+
}
|
|
324
|
+
export function computeCostUsd(stats, model) {
|
|
325
|
+
const rates = MODEL_RATES[model] ?? MODEL_RATES[DEFAULT_MODEL];
|
|
326
|
+
const hit = stats.cache_hit_tokens;
|
|
327
|
+
const miss = stats.cache_miss_tokens;
|
|
328
|
+
const out = stats.completion_tokens;
|
|
329
|
+
// Prompt tokens not categorized as hit/miss (older API responses) bill at miss rate.
|
|
330
|
+
const unaccounted = Math.max(0, stats.prompt_tokens - hit - miss);
|
|
331
|
+
return hit * rates.in_hit + miss * rates.in_miss + unaccounted * rates.in_miss + out * rates.out;
|
|
332
|
+
}
|
|
333
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|