deepseek-toolkit 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/dist/index.cjs +742 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +222 -0
- package/dist/index.d.ts +222 -0
- package/dist/index.js +717 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.cjs +21 -0
- package/dist/types/index.cjs.map +1 -0
- package/dist/types/index.d.cts +203 -0
- package/dist/types/index.d.ts +203 -0
- package/dist/types/index.js +14 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +65 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,742 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var OpenAI = require('openai');
|
|
4
|
+
|
|
5
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
6
|
+
|
|
7
|
+
var OpenAI__default = /*#__PURE__*/_interopDefault(OpenAI);
|
|
8
|
+
|
|
9
|
+
// src/client.ts
|
|
10
|
+
|
|
11
|
+
// src/errors.ts
|
|
12
|
+
var DeepSeekError = class extends Error {
|
|
13
|
+
constructor(message, status, code) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.status = status;
|
|
16
|
+
this.code = code;
|
|
17
|
+
this.name = "DeepSeekError";
|
|
18
|
+
}
|
|
19
|
+
status;
|
|
20
|
+
code;
|
|
21
|
+
};
|
|
22
|
+
var BraveSearchError = class extends Error {
|
|
23
|
+
constructor(message, status) {
|
|
24
|
+
super(message);
|
|
25
|
+
this.status = status;
|
|
26
|
+
this.name = "BraveSearchError";
|
|
27
|
+
}
|
|
28
|
+
status;
|
|
29
|
+
};
|
|
30
|
+
var ToolError = class extends Error {
|
|
31
|
+
constructor(message, toolName) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.toolName = toolName;
|
|
34
|
+
this.name = "ToolError";
|
|
35
|
+
}
|
|
36
|
+
toolName;
|
|
37
|
+
};
|
|
38
|
+
var ToolLoopError = class extends Error {
|
|
39
|
+
constructor(message, iterations) {
|
|
40
|
+
super(message);
|
|
41
|
+
this.iterations = iterations;
|
|
42
|
+
this.name = "ToolLoopError";
|
|
43
|
+
}
|
|
44
|
+
iterations;
|
|
45
|
+
};
|
|
46
|
+
var ConfigError = class extends Error {
|
|
47
|
+
constructor(message) {
|
|
48
|
+
super(message);
|
|
49
|
+
this.name = "ConfigError";
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// src/types/models.ts
|
|
54
|
+
var DEEPSEEK_MODELS = {
|
|
55
|
+
V4_PRO: "deepseek-v4-pro",
|
|
56
|
+
V4_FLASH: "deepseek-v4-flash"
|
|
57
|
+
};
|
|
58
|
+
var DEEPSEEK_BASE_URL = "https://api.deepseek.com";
|
|
59
|
+
var DEEPSEEK_BETA_BASE_URL = "https://api.deepseek.com/beta";
|
|
60
|
+
var BRAVE_WEB_SEARCH_URL = "https://api.search.brave.com/res/v1/web/search";
|
|
61
|
+
var BRAVE_LLM_CONTEXT_URL = "https://api.search.brave.com/res/v1/llm/context";
|
|
62
|
+
var DEFAULT_MAX_TOOL_LOOP_ITERATIONS = 10;
|
|
63
|
+
|
|
64
|
+
// src/brave-search.ts
|
|
65
|
+
var BraveSearchClient = class {
|
|
66
|
+
constructor(apiKey) {
|
|
67
|
+
this.apiKey = apiKey;
|
|
68
|
+
}
|
|
69
|
+
apiKey;
|
|
70
|
+
async webSearch(query, options = {}) {
|
|
71
|
+
const params = new URLSearchParams();
|
|
72
|
+
params.set("q", query);
|
|
73
|
+
if (options.country) params.set("country", options.country);
|
|
74
|
+
if (options.searchLang) params.set("search_lang", options.searchLang);
|
|
75
|
+
if (options.safesearch) params.set("safesearch", options.safesearch);
|
|
76
|
+
if (options.freshness) params.set("freshness", options.freshness);
|
|
77
|
+
if (options.count !== void 0)
|
|
78
|
+
params.set("count", String(options.count));
|
|
79
|
+
if (options.offset !== void 0)
|
|
80
|
+
params.set("offset", String(options.offset));
|
|
81
|
+
if (options.extraSnippets)
|
|
82
|
+
params.set("extra_snippets", "true");
|
|
83
|
+
const url = `${BRAVE_WEB_SEARCH_URL}?${params.toString()}`;
|
|
84
|
+
const response = await fetch(url, {
|
|
85
|
+
headers: {
|
|
86
|
+
"X-Subscription-Token": this.apiKey,
|
|
87
|
+
Accept: "application/json"
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
throw new BraveSearchError(
|
|
92
|
+
`Brave Web Search failed: ${response.status} ${response.statusText}`,
|
|
93
|
+
response.status
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
return response.json();
|
|
97
|
+
}
|
|
98
|
+
async llmContext(query, options = {}) {
|
|
99
|
+
const params = new URLSearchParams();
|
|
100
|
+
params.set("q", query);
|
|
101
|
+
if (options.country) params.set("country", options.country);
|
|
102
|
+
if (options.searchLang) params.set("search_lang", options.searchLang);
|
|
103
|
+
if (options.freshness) params.set("freshness", options.freshness);
|
|
104
|
+
if (options.count !== void 0)
|
|
105
|
+
params.set("count", String(options.count));
|
|
106
|
+
if (options.maxUrls !== void 0)
|
|
107
|
+
params.set("maximum_number_of_urls", String(options.maxUrls));
|
|
108
|
+
if (options.maxTokens !== void 0)
|
|
109
|
+
params.set("maximum_number_of_tokens", String(options.maxTokens));
|
|
110
|
+
if (options.maxSnippets !== void 0)
|
|
111
|
+
params.set("maximum_number_of_snippets", String(options.maxSnippets));
|
|
112
|
+
if (options.maxTokensPerUrl !== void 0)
|
|
113
|
+
params.set(
|
|
114
|
+
"maximum_number_of_tokens_per_url",
|
|
115
|
+
String(options.maxTokensPerUrl)
|
|
116
|
+
);
|
|
117
|
+
if (options.maxSnippetsPerUrl !== void 0)
|
|
118
|
+
params.set(
|
|
119
|
+
"maximum_number_of_snippets_per_url",
|
|
120
|
+
String(options.maxSnippetsPerUrl)
|
|
121
|
+
);
|
|
122
|
+
if (options.contextThresholdMode)
|
|
123
|
+
params.set("context_threshold_mode", options.contextThresholdMode);
|
|
124
|
+
if (options.enableLocal !== void 0 && options.enableLocal !== null)
|
|
125
|
+
params.set("enable_local", String(options.enableLocal));
|
|
126
|
+
if (options.safesearch) params.set("safesearch", options.safesearch);
|
|
127
|
+
const url = `${BRAVE_LLM_CONTEXT_URL}?${params.toString()}`;
|
|
128
|
+
const response = await fetch(url, {
|
|
129
|
+
headers: {
|
|
130
|
+
"X-Subscription-Token": this.apiKey,
|
|
131
|
+
Accept: "application/json"
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
if (!response.ok) {
|
|
135
|
+
throw new BraveSearchError(
|
|
136
|
+
`Brave LLM Context failed: ${response.status} ${response.statusText}`,
|
|
137
|
+
response.status
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
return response.json();
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// src/tool-manager.ts
|
|
145
|
+
var ToolManager = class {
|
|
146
|
+
tools = /* @__PURE__ */ new Map();
|
|
147
|
+
addTool(definition, handler) {
|
|
148
|
+
const name = definition.function.name;
|
|
149
|
+
if (this.tools.has(name)) {
|
|
150
|
+
throw new ToolError(`Tool "${name}" is already registered`, name);
|
|
151
|
+
}
|
|
152
|
+
this.tools.set(name, { definition, handler });
|
|
153
|
+
}
|
|
154
|
+
addTools(tools) {
|
|
155
|
+
for (const tool of tools) {
|
|
156
|
+
this.addTool(tool.definition, tool.handler);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
removeTool(name) {
|
|
160
|
+
return this.tools.delete(name);
|
|
161
|
+
}
|
|
162
|
+
getTool(name) {
|
|
163
|
+
return this.tools.get(name);
|
|
164
|
+
}
|
|
165
|
+
hasTool(name) {
|
|
166
|
+
return this.tools.has(name);
|
|
167
|
+
}
|
|
168
|
+
getToolDefinitions() {
|
|
169
|
+
return Array.from(this.tools.values()).map((t) => t.definition);
|
|
170
|
+
}
|
|
171
|
+
getHandler(name) {
|
|
172
|
+
return this.tools.get(name)?.handler;
|
|
173
|
+
}
|
|
174
|
+
hasHandler(name) {
|
|
175
|
+
const tool = this.tools.get(name);
|
|
176
|
+
return tool !== void 0 && tool.handler !== void 0;
|
|
177
|
+
}
|
|
178
|
+
async executeToolCall(name, args, toolCallId) {
|
|
179
|
+
const handler = this.getHandler(name);
|
|
180
|
+
if (!handler) {
|
|
181
|
+
throw new ToolError(
|
|
182
|
+
`No handler registered for tool "${name}". Provide a handler via addTool() to enable automatic execution.`,
|
|
183
|
+
name
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
const result = await handler(args);
|
|
187
|
+
return {
|
|
188
|
+
tool_call_id: toolCallId,
|
|
189
|
+
role: "tool",
|
|
190
|
+
content: typeof result === "string" ? result : JSON.stringify(result)
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
get registeredCount() {
|
|
194
|
+
return this.tools.size;
|
|
195
|
+
}
|
|
196
|
+
get registeredNames() {
|
|
197
|
+
return Array.from(this.tools.keys());
|
|
198
|
+
}
|
|
199
|
+
clear() {
|
|
200
|
+
this.tools.clear();
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
// src/reasoning.ts
|
|
205
|
+
var ReasoningState = class {
|
|
206
|
+
activeToolCall = false;
|
|
207
|
+
startToolCallTurn() {
|
|
208
|
+
this.activeToolCall = true;
|
|
209
|
+
}
|
|
210
|
+
endToolCallTurn() {
|
|
211
|
+
this.activeToolCall = false;
|
|
212
|
+
}
|
|
213
|
+
shouldIncludeReasoning() {
|
|
214
|
+
return this.activeToolCall;
|
|
215
|
+
}
|
|
216
|
+
reset() {
|
|
217
|
+
this.activeToolCall = false;
|
|
218
|
+
}
|
|
219
|
+
cleanMessageForContext(message) {
|
|
220
|
+
if (this.activeToolCall) {
|
|
221
|
+
return message;
|
|
222
|
+
}
|
|
223
|
+
if (message.reasoning_content && !message.tool_calls?.length) {
|
|
224
|
+
const { reasoning_content: _, ...rest } = message;
|
|
225
|
+
return rest;
|
|
226
|
+
}
|
|
227
|
+
return message;
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
// src/tool-loop.ts
|
|
232
|
+
var ToolLoop = class {
|
|
233
|
+
constructor(openai, config, toolManager) {
|
|
234
|
+
this.openai = openai;
|
|
235
|
+
this.config = config;
|
|
236
|
+
this.toolManager = toolManager;
|
|
237
|
+
this.reasoning = new ReasoningState();
|
|
238
|
+
}
|
|
239
|
+
openai;
|
|
240
|
+
config;
|
|
241
|
+
toolManager;
|
|
242
|
+
reasoning;
|
|
243
|
+
async run(messages, tools, toolChoice, callbacks) {
|
|
244
|
+
const allTools = [
|
|
245
|
+
...this.toolManager.getToolDefinitions(),
|
|
246
|
+
...tools ?? []
|
|
247
|
+
];
|
|
248
|
+
let response = await this.makeRequest(messages, allTools, toolChoice);
|
|
249
|
+
let iterations = 0;
|
|
250
|
+
while (this.hasToolCalls(response) && iterations < this.config.maxToolLoopIterations) {
|
|
251
|
+
iterations++;
|
|
252
|
+
this.reasoning.startToolCallTurn();
|
|
253
|
+
const choice = response.choices[0];
|
|
254
|
+
if (!choice) break;
|
|
255
|
+
const toolCalls = choice.message.tool_calls ?? [];
|
|
256
|
+
const toolResults = await this.executeToolCalls(toolCalls, callbacks);
|
|
257
|
+
messages.push(choice.message);
|
|
258
|
+
for (const tr of toolResults) {
|
|
259
|
+
messages.push(tr);
|
|
260
|
+
}
|
|
261
|
+
response = await this.makeRequest(messages, allTools, toolChoice);
|
|
262
|
+
this.reasoning.endToolCallTurn();
|
|
263
|
+
}
|
|
264
|
+
if (iterations >= this.config.maxToolLoopIterations) {
|
|
265
|
+
const lastChoice = response.choices[0];
|
|
266
|
+
if (lastChoice && this.hasToolCallsInChoice(response)) {
|
|
267
|
+
throw new ToolLoopError(
|
|
268
|
+
`Tool call loop exceeded maximum iterations (${this.config.maxToolLoopIterations})`,
|
|
269
|
+
iterations
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return response;
|
|
274
|
+
}
|
|
275
|
+
async runStream(messages, tools, toolChoice, callbacks) {
|
|
276
|
+
const allTools = [
|
|
277
|
+
...this.toolManager.getToolDefinitions(),
|
|
278
|
+
...tools ?? []
|
|
279
|
+
];
|
|
280
|
+
let streamResult = await this.makeStreamRequest(messages, allTools, toolChoice);
|
|
281
|
+
let iterations = 0;
|
|
282
|
+
let accumulatedToolCalls = [];
|
|
283
|
+
let finalChunks = [];
|
|
284
|
+
for await (const chunk of streamResult) {
|
|
285
|
+
const delta = chunk.choices[0]?.delta;
|
|
286
|
+
if (delta?.tool_calls) {
|
|
287
|
+
for (const tc of delta.tool_calls) {
|
|
288
|
+
if (tc.id) {
|
|
289
|
+
accumulatedToolCalls.push({
|
|
290
|
+
id: tc.id,
|
|
291
|
+
name: tc.function?.name ?? "",
|
|
292
|
+
arguments: tc.function?.arguments ?? ""
|
|
293
|
+
});
|
|
294
|
+
} else if (tc.function?.arguments) {
|
|
295
|
+
const existing = accumulatedToolCalls[accumulatedToolCalls.length - 1];
|
|
296
|
+
if (existing) {
|
|
297
|
+
existing.arguments += tc.function.arguments;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
finalChunks.push(chunk);
|
|
303
|
+
}
|
|
304
|
+
if (accumulatedToolCalls.length > 0 && iterations < this.config.maxToolLoopIterations) {
|
|
305
|
+
this.reasoning.startToolCallTurn();
|
|
306
|
+
const toolResults = await this.executeToolCalls(
|
|
307
|
+
accumulatedToolCalls.map((tc) => ({
|
|
308
|
+
id: tc.id,
|
|
309
|
+
type: "function",
|
|
310
|
+
function: { name: tc.name, arguments: tc.arguments }
|
|
311
|
+
})),
|
|
312
|
+
callbacks
|
|
313
|
+
);
|
|
314
|
+
const assistantMsg = {
|
|
315
|
+
role: "assistant",
|
|
316
|
+
content: null,
|
|
317
|
+
tool_calls: accumulatedToolCalls.map((tc) => ({
|
|
318
|
+
id: tc.id,
|
|
319
|
+
type: "function",
|
|
320
|
+
function: { name: tc.name, arguments: tc.arguments }
|
|
321
|
+
}))
|
|
322
|
+
};
|
|
323
|
+
messages.push(assistantMsg);
|
|
324
|
+
for (const tr of toolResults) {
|
|
325
|
+
messages.push(tr);
|
|
326
|
+
}
|
|
327
|
+
const nextResponse = await this.makeStreamRequest(messages, allTools, toolChoice);
|
|
328
|
+
this.reasoning.endToolCallTurn();
|
|
329
|
+
return nextResponse;
|
|
330
|
+
}
|
|
331
|
+
return this.chunksToAsyncIterable(finalChunks);
|
|
332
|
+
}
|
|
333
|
+
async makeRequest(messages, tools, toolChoice) {
|
|
334
|
+
const params = {
|
|
335
|
+
model: this.config.model,
|
|
336
|
+
messages,
|
|
337
|
+
reasoning_effort: this.config.reasoningEffort,
|
|
338
|
+
thinking: this.config.thinking
|
|
339
|
+
};
|
|
340
|
+
if (tools && tools.length > 0) {
|
|
341
|
+
params.tools = tools;
|
|
342
|
+
params.tool_choice = toolChoice ?? "auto";
|
|
343
|
+
}
|
|
344
|
+
if (this.config.maxTokens !== void 0) params.max_tokens = this.config.maxTokens;
|
|
345
|
+
if (this.config.temperature !== void 0) params.temperature = this.config.temperature;
|
|
346
|
+
if (this.config.topP !== void 0) params.top_p = this.config.topP;
|
|
347
|
+
const result = await this.openai.chat.completions.create(params);
|
|
348
|
+
return result;
|
|
349
|
+
}
|
|
350
|
+
async makeStreamRequest(messages, tools, toolChoice) {
|
|
351
|
+
const params = {
|
|
352
|
+
model: this.config.model,
|
|
353
|
+
messages,
|
|
354
|
+
stream: true,
|
|
355
|
+
reasoning_effort: this.config.reasoningEffort,
|
|
356
|
+
thinking: this.config.thinking
|
|
357
|
+
};
|
|
358
|
+
if (tools && tools.length > 0) {
|
|
359
|
+
params.tools = tools;
|
|
360
|
+
params.tool_choice = toolChoice ?? "auto";
|
|
361
|
+
}
|
|
362
|
+
if (this.config.maxTokens !== void 0) params.max_tokens = this.config.maxTokens;
|
|
363
|
+
if (this.config.temperature !== void 0) params.temperature = this.config.temperature;
|
|
364
|
+
if (this.config.topP !== void 0) params.top_p = this.config.topP;
|
|
365
|
+
const stream = await this.openai.chat.completions.create(params);
|
|
366
|
+
return stream;
|
|
367
|
+
}
|
|
368
|
+
async executeToolCalls(toolCalls, callbacks) {
|
|
369
|
+
const results = [];
|
|
370
|
+
for (const tc of toolCalls) {
|
|
371
|
+
const name = tc.function.name;
|
|
372
|
+
let args = {};
|
|
373
|
+
try {
|
|
374
|
+
args = JSON.parse(tc.function.arguments);
|
|
375
|
+
} catch {
|
|
376
|
+
args = {};
|
|
377
|
+
}
|
|
378
|
+
if (callbacks?.onToolCall) {
|
|
379
|
+
const result = await callbacks.onToolCall(name, args, tc.id);
|
|
380
|
+
results.push({
|
|
381
|
+
tool_call_id: tc.id,
|
|
382
|
+
role: "tool",
|
|
383
|
+
content: result
|
|
384
|
+
});
|
|
385
|
+
callbacks.onToolResult?.(name, result);
|
|
386
|
+
} else if (this.toolManager.hasHandler(name)) {
|
|
387
|
+
const tr = await this.toolManager.executeToolCall(name, args, tc.id);
|
|
388
|
+
results.push(tr);
|
|
389
|
+
callbacks?.onToolResult?.(name, tr.content);
|
|
390
|
+
} else {
|
|
391
|
+
results.push({
|
|
392
|
+
tool_call_id: tc.id,
|
|
393
|
+
role: "tool",
|
|
394
|
+
content: `Tool "${name}" has no handler registered. Register a handler to enable automatic execution.`
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
return results;
|
|
399
|
+
}
|
|
400
|
+
hasToolCalls(response) {
|
|
401
|
+
return this.hasToolCallsInChoice(response);
|
|
402
|
+
}
|
|
403
|
+
hasToolCallsInChoice(response) {
|
|
404
|
+
const choice = response.choices[0];
|
|
405
|
+
if (!choice) return false;
|
|
406
|
+
return choice.finish_reason === "tool_calls" && (choice.message.tool_calls?.length ?? 0) > 0;
|
|
407
|
+
}
|
|
408
|
+
async *chunksToAsyncIterable(chunks) {
|
|
409
|
+
for (const chunk of chunks) {
|
|
410
|
+
yield chunk;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
get reasoningState() {
|
|
414
|
+
return this.reasoning;
|
|
415
|
+
}
|
|
416
|
+
resetReasoning() {
|
|
417
|
+
this.reasoning.reset();
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
// src/defaults.ts
|
|
422
|
+
var DEFAULT_CONFIG = {
|
|
423
|
+
model: DEEPSEEK_MODELS.V4_PRO,
|
|
424
|
+
baseURL: DEEPSEEK_BASE_URL,
|
|
425
|
+
thinking: { type: "enabled" },
|
|
426
|
+
reasoningEffort: "high",
|
|
427
|
+
braveSearch: {
|
|
428
|
+
safesearch: "off",
|
|
429
|
+
freshness: void 0,
|
|
430
|
+
country: "US",
|
|
431
|
+
searchLang: "en",
|
|
432
|
+
count: 10
|
|
433
|
+
},
|
|
434
|
+
maxToolLoopIterations: DEFAULT_MAX_TOOL_LOOP_ITERATIONS
|
|
435
|
+
};
|
|
436
|
+
var BRAVE_WEB_SEARCH_TOOL_DEFINITION = {
|
|
437
|
+
type: "function",
|
|
438
|
+
function: {
|
|
439
|
+
name: "brave_web_search",
|
|
440
|
+
description: "Search the web using Brave Search. Returns web page results with titles, URLs, and descriptions. Use this to find current information, news, documentation, or any web content.",
|
|
441
|
+
parameters: {
|
|
442
|
+
type: "object",
|
|
443
|
+
properties: {
|
|
444
|
+
query: {
|
|
445
|
+
type: "string",
|
|
446
|
+
description: "The search query"
|
|
447
|
+
},
|
|
448
|
+
freshness: {
|
|
449
|
+
type: "string",
|
|
450
|
+
enum: ["pd", "pw", "pm", "py"],
|
|
451
|
+
description: "Filter results by freshness: pd (24h), pw (7 days), pm (month), py (year)"
|
|
452
|
+
},
|
|
453
|
+
count: {
|
|
454
|
+
type: "integer",
|
|
455
|
+
minimum: 1,
|
|
456
|
+
maximum: 20,
|
|
457
|
+
description: "Number of results (max 20)"
|
|
458
|
+
},
|
|
459
|
+
safesearch: {
|
|
460
|
+
type: "string",
|
|
461
|
+
enum: ["off", "moderate", "strict"],
|
|
462
|
+
description: "Content filter level"
|
|
463
|
+
}
|
|
464
|
+
},
|
|
465
|
+
required: ["query"]
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
var BRAVE_LLM_CONTEXT_TOOL_DEFINITION = {
|
|
470
|
+
type: "function",
|
|
471
|
+
function: {
|
|
472
|
+
name: "brave_llm_context",
|
|
473
|
+
description: "Search the web and get content optimized for AI consumption. Returns pre-extracted text snippets from web pages, ideal for grounding responses in current information.",
|
|
474
|
+
parameters: {
|
|
475
|
+
type: "object",
|
|
476
|
+
properties: {
|
|
477
|
+
query: {
|
|
478
|
+
type: "string",
|
|
479
|
+
description: "The search query"
|
|
480
|
+
},
|
|
481
|
+
freshness: {
|
|
482
|
+
type: "string",
|
|
483
|
+
enum: ["pd", "pw", "pm", "py"],
|
|
484
|
+
description: "Filter results by freshness: pd (24h), pw (7 days), pm (month), py (year)"
|
|
485
|
+
},
|
|
486
|
+
maxTokens: {
|
|
487
|
+
type: "integer",
|
|
488
|
+
minimum: 1024,
|
|
489
|
+
maximum: 32768,
|
|
490
|
+
description: "Max tokens in context (default 8192)"
|
|
491
|
+
},
|
|
492
|
+
maxUrls: {
|
|
493
|
+
type: "integer",
|
|
494
|
+
minimum: 1,
|
|
495
|
+
maximum: 50,
|
|
496
|
+
description: "Maximum URLs to include (default 20)"
|
|
497
|
+
}
|
|
498
|
+
},
|
|
499
|
+
required: ["query"]
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
function resolveConfig(config) {
|
|
504
|
+
return {
|
|
505
|
+
deepseekApiKey: config.deepseekApiKey,
|
|
506
|
+
braveSearchApiKey: config.braveSearchApiKey,
|
|
507
|
+
model: config.model ?? DEFAULT_CONFIG.model,
|
|
508
|
+
baseURL: config.baseURL ?? DEFAULT_CONFIG.baseURL,
|
|
509
|
+
thinking: config.thinking ?? DEFAULT_CONFIG.thinking,
|
|
510
|
+
reasoningEffort: config.reasoningEffort ?? DEFAULT_CONFIG.reasoningEffort,
|
|
511
|
+
braveSearch: {
|
|
512
|
+
safesearch: config.braveSearch?.safesearch ?? DEFAULT_CONFIG.braveSearch.safesearch,
|
|
513
|
+
freshness: config.braveSearch?.freshness ?? DEFAULT_CONFIG.braveSearch.freshness,
|
|
514
|
+
country: config.braveSearch?.country ?? DEFAULT_CONFIG.braveSearch.country,
|
|
515
|
+
searchLang: config.braveSearch?.searchLang ?? DEFAULT_CONFIG.braveSearch.searchLang,
|
|
516
|
+
count: config.braveSearch?.count ?? DEFAULT_CONFIG.braveSearch.count
|
|
517
|
+
},
|
|
518
|
+
maxTokens: config.maxTokens,
|
|
519
|
+
temperature: config.temperature,
|
|
520
|
+
topP: config.topP,
|
|
521
|
+
maxToolLoopIterations: config.maxToolLoopIterations ?? DEFAULT_CONFIG.maxToolLoopIterations
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// src/client.ts
|
|
526
|
+
var DeepSeekClient = class {
|
|
527
|
+
config;
|
|
528
|
+
openai;
|
|
529
|
+
braveSearch;
|
|
530
|
+
toolManager;
|
|
531
|
+
toolLoop;
|
|
532
|
+
constructor(config) {
|
|
533
|
+
if (!config.deepseekApiKey) {
|
|
534
|
+
throw new ConfigError("deepseekApiKey is required");
|
|
535
|
+
}
|
|
536
|
+
this.config = resolveConfig(config);
|
|
537
|
+
this.openai = new OpenAI__default.default({
|
|
538
|
+
apiKey: this.config.deepseekApiKey,
|
|
539
|
+
baseURL: this.config.baseURL
|
|
540
|
+
});
|
|
541
|
+
if (config.braveSearchApiKey) {
|
|
542
|
+
this.braveSearch = new BraveSearchClient(config.braveSearchApiKey);
|
|
543
|
+
}
|
|
544
|
+
this.toolManager = new ToolManager();
|
|
545
|
+
this.toolLoop = new ToolLoop(this.openai, this.config, this.toolManager);
|
|
546
|
+
this.registerBuiltinTools();
|
|
547
|
+
}
|
|
548
|
+
registerBuiltinTools() {
|
|
549
|
+
if (this.braveSearch) {
|
|
550
|
+
this.toolManager.addTool(
|
|
551
|
+
BRAVE_WEB_SEARCH_TOOL_DEFINITION,
|
|
552
|
+
async (args) => {
|
|
553
|
+
const result = await this.braveSearch.webSearch(
|
|
554
|
+
args.query,
|
|
555
|
+
{
|
|
556
|
+
freshness: args.freshness,
|
|
557
|
+
safesearch: args.safesearch ?? this.config.braveSearch.safesearch,
|
|
558
|
+
count: args.count ?? this.config.braveSearch.count,
|
|
559
|
+
country: this.config.braveSearch.country,
|
|
560
|
+
searchLang: this.config.braveSearch.searchLang
|
|
561
|
+
}
|
|
562
|
+
);
|
|
563
|
+
return JSON.stringify(result);
|
|
564
|
+
}
|
|
565
|
+
);
|
|
566
|
+
this.toolManager.addTool(
|
|
567
|
+
BRAVE_LLM_CONTEXT_TOOL_DEFINITION,
|
|
568
|
+
async (args) => {
|
|
569
|
+
const result = await this.braveSearch.llmContext(
|
|
570
|
+
args.query,
|
|
571
|
+
{
|
|
572
|
+
freshness: args.freshness,
|
|
573
|
+
maxTokens: args.maxTokens,
|
|
574
|
+
maxUrls: args.maxUrls,
|
|
575
|
+
country: this.config.braveSearch.country,
|
|
576
|
+
searchLang: this.config.braveSearch.searchLang,
|
|
577
|
+
safesearch: this.config.braveSearch.safesearch
|
|
578
|
+
}
|
|
579
|
+
);
|
|
580
|
+
return JSON.stringify(result);
|
|
581
|
+
}
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
async chat(messages, options) {
|
|
586
|
+
const prevModel = this.config.model;
|
|
587
|
+
const prevThinking = this.config.thinking;
|
|
588
|
+
const prevEffort = this.config.reasoningEffort;
|
|
589
|
+
const prevMaxTokens = this.config.maxTokens;
|
|
590
|
+
const prevTemp = this.config.temperature;
|
|
591
|
+
const prevTopP = this.config.topP;
|
|
592
|
+
if (options?.model) this.config.model = options.model;
|
|
593
|
+
if (options?.thinking) this.config.thinking = options.thinking;
|
|
594
|
+
if (options?.reasoningEffort)
|
|
595
|
+
this.config.reasoningEffort = options.reasoningEffort;
|
|
596
|
+
if (options?.maxTokens !== void 0)
|
|
597
|
+
this.config.maxTokens = options.maxTokens;
|
|
598
|
+
if (options?.temperature !== void 0)
|
|
599
|
+
this.config.temperature = options.temperature;
|
|
600
|
+
if (options?.topP !== void 0) this.config.topP = options.topP;
|
|
601
|
+
try {
|
|
602
|
+
return await this.toolLoop.run(
|
|
603
|
+
messages,
|
|
604
|
+
options?.tools,
|
|
605
|
+
options?.toolChoice,
|
|
606
|
+
{
|
|
607
|
+
onToolCall: options?.onToolCall,
|
|
608
|
+
onToolResult: options?.onToolResult
|
|
609
|
+
}
|
|
610
|
+
);
|
|
611
|
+
} finally {
|
|
612
|
+
this.config.model = prevModel;
|
|
613
|
+
this.config.thinking = prevThinking;
|
|
614
|
+
this.config.reasoningEffort = prevEffort;
|
|
615
|
+
this.config.maxTokens = prevMaxTokens;
|
|
616
|
+
this.config.temperature = prevTemp;
|
|
617
|
+
this.config.topP = prevTopP;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
async chatStream(messages, options) {
|
|
621
|
+
const prevModel = this.config.model;
|
|
622
|
+
const prevThinking = this.config.thinking;
|
|
623
|
+
const prevEffort = this.config.reasoningEffort;
|
|
624
|
+
const prevMaxTokens = this.config.maxTokens;
|
|
625
|
+
const prevTemp = this.config.temperature;
|
|
626
|
+
const prevTopP = this.config.topP;
|
|
627
|
+
if (options?.model) this.config.model = options.model;
|
|
628
|
+
if (options?.thinking) this.config.thinking = options.thinking;
|
|
629
|
+
if (options?.reasoningEffort)
|
|
630
|
+
this.config.reasoningEffort = options.reasoningEffort;
|
|
631
|
+
if (options?.maxTokens !== void 0)
|
|
632
|
+
this.config.maxTokens = options.maxTokens;
|
|
633
|
+
if (options?.temperature !== void 0)
|
|
634
|
+
this.config.temperature = options.temperature;
|
|
635
|
+
if (options?.topP !== void 0) this.config.topP = options.topP;
|
|
636
|
+
try {
|
|
637
|
+
return await this.toolLoop.runStream(
|
|
638
|
+
messages,
|
|
639
|
+
options?.tools,
|
|
640
|
+
options?.toolChoice,
|
|
641
|
+
{
|
|
642
|
+
onToolCall: options?.onToolCall,
|
|
643
|
+
onToolResult: options?.onToolResult
|
|
644
|
+
}
|
|
645
|
+
);
|
|
646
|
+
} finally {
|
|
647
|
+
this.config.model = prevModel;
|
|
648
|
+
this.config.thinking = prevThinking;
|
|
649
|
+
this.config.reasoningEffort = prevEffort;
|
|
650
|
+
this.config.maxTokens = prevMaxTokens;
|
|
651
|
+
this.config.temperature = prevTemp;
|
|
652
|
+
this.config.topP = prevTopP;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
addTool(definition, handler) {
|
|
656
|
+
this.toolManager.addTool(definition, handler);
|
|
657
|
+
}
|
|
658
|
+
addTools(tools) {
|
|
659
|
+
this.toolManager.addTools(tools);
|
|
660
|
+
}
|
|
661
|
+
removeTool(name) {
|
|
662
|
+
return this.toolManager.removeTool(name);
|
|
663
|
+
}
|
|
664
|
+
getTools() {
|
|
665
|
+
return this.toolManager.getToolDefinitions().map((d) => {
|
|
666
|
+
const registered = this.toolManager.getTool(d.function.name);
|
|
667
|
+
return registered;
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
hasTool(name) {
|
|
671
|
+
return this.toolManager.hasTool(name);
|
|
672
|
+
}
|
|
673
|
+
async executeToolCall(name, args, toolCallId) {
|
|
674
|
+
return this.toolManager.executeToolCall(name, args, toolCallId);
|
|
675
|
+
}
|
|
676
|
+
async search(query, options) {
|
|
677
|
+
if (!this.braveSearch) {
|
|
678
|
+
throw new ConfigError(
|
|
679
|
+
"Brave Search is not configured. Provide braveSearchApiKey in config."
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
return this.braveSearch.webSearch(query, options ?? {});
|
|
683
|
+
}
|
|
684
|
+
async searchAsContext(query, options) {
|
|
685
|
+
if (!this.braveSearch) {
|
|
686
|
+
throw new ConfigError(
|
|
687
|
+
"Brave Search is not configured. Provide braveSearchApiKey in config."
|
|
688
|
+
);
|
|
689
|
+
}
|
|
690
|
+
return this.braveSearch.llmContext(query, options ?? {});
|
|
691
|
+
}
|
|
692
|
+
get model() {
|
|
693
|
+
return this.config.model;
|
|
694
|
+
}
|
|
695
|
+
set model(m) {
|
|
696
|
+
this.config.model = m;
|
|
697
|
+
}
|
|
698
|
+
get thinking() {
|
|
699
|
+
return this.config.thinking;
|
|
700
|
+
}
|
|
701
|
+
set thinking(t) {
|
|
702
|
+
this.config.thinking = t;
|
|
703
|
+
}
|
|
704
|
+
get reasoningEffort() {
|
|
705
|
+
return this.config.reasoningEffort;
|
|
706
|
+
}
|
|
707
|
+
set reasoningEffort(r) {
|
|
708
|
+
this.config.reasoningEffort = r;
|
|
709
|
+
}
|
|
710
|
+
get braveSearchDefaults() {
|
|
711
|
+
return this.config.braveSearch;
|
|
712
|
+
}
|
|
713
|
+
set braveSearchDefaults(d) {
|
|
714
|
+
this.config.braveSearch = { ...this.config.braveSearch, ...d };
|
|
715
|
+
}
|
|
716
|
+
get openaiClient() {
|
|
717
|
+
return this.openai;
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
exports.BRAVE_LLM_CONTEXT_TOOL_DEFINITION = BRAVE_LLM_CONTEXT_TOOL_DEFINITION;
|
|
722
|
+
exports.BRAVE_LLM_CONTEXT_URL = BRAVE_LLM_CONTEXT_URL;
|
|
723
|
+
exports.BRAVE_WEB_SEARCH_TOOL_DEFINITION = BRAVE_WEB_SEARCH_TOOL_DEFINITION;
|
|
724
|
+
exports.BRAVE_WEB_SEARCH_URL = BRAVE_WEB_SEARCH_URL;
|
|
725
|
+
exports.BraveSearchClient = BraveSearchClient;
|
|
726
|
+
exports.BraveSearchError = BraveSearchError;
|
|
727
|
+
exports.ConfigError = ConfigError;
|
|
728
|
+
exports.DEEPSEEK_BASE_URL = DEEPSEEK_BASE_URL;
|
|
729
|
+
exports.DEEPSEEK_BETA_BASE_URL = DEEPSEEK_BETA_BASE_URL;
|
|
730
|
+
exports.DEEPSEEK_MODELS = DEEPSEEK_MODELS;
|
|
731
|
+
exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
|
|
732
|
+
exports.DEFAULT_MAX_TOOL_LOOP_ITERATIONS = DEFAULT_MAX_TOOL_LOOP_ITERATIONS;
|
|
733
|
+
exports.DeepSeekClient = DeepSeekClient;
|
|
734
|
+
exports.DeepSeekError = DeepSeekError;
|
|
735
|
+
exports.ReasoningState = ReasoningState;
|
|
736
|
+
exports.ToolError = ToolError;
|
|
737
|
+
exports.ToolLoop = ToolLoop;
|
|
738
|
+
exports.ToolLoopError = ToolLoopError;
|
|
739
|
+
exports.ToolManager = ToolManager;
|
|
740
|
+
exports.resolveConfig = resolveConfig;
|
|
741
|
+
//# sourceMappingURL=index.cjs.map
|
|
742
|
+
//# sourceMappingURL=index.cjs.map
|