@dcrays/web-search 0.1.3 → 0.1.4-beta.2
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/package.json +2 -2
- package/plugin/index.js +17 -33
- package/src/api-client.js +11 -28
- package/src/tools.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dcrays/web-search",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4-beta.2",
|
|
4
4
|
"description": "DeepSeek Harness web search plugin for Mobook",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "plugin/index.js",
|
|
@@ -38,4 +38,4 @@
|
|
|
38
38
|
"publishConfig": {
|
|
39
39
|
"access": "public"
|
|
40
40
|
}
|
|
41
|
-
}
|
|
41
|
+
}
|
package/plugin/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { createRequire as __mobookCreateRequire } from 'node:module'; const require = __mobookCreateRequire(import.meta.url);
|
|
2
2
|
|
|
3
|
-
// dist
|
|
3
|
+
// dist/plugin/index.js
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
5
|
import { Service } from "@deepseek-ai/cordis";
|
|
6
6
|
import { resolveDshHome } from "@deepseek-ai/dsh-home-paths";
|
|
7
7
|
import z from "@deepseek-ai/schemastery";
|
|
8
8
|
|
|
9
|
-
// dist
|
|
9
|
+
// dist/src/api-client.js
|
|
10
10
|
import { createHmac, randomUUID } from "node:crypto";
|
|
11
11
|
import { readFile } from "node:fs/promises";
|
|
12
12
|
var WebSearchApiError = class extends Error {
|
|
@@ -24,35 +24,19 @@ function searchServiceLabel(service) {
|
|
|
24
24
|
function record(value) {
|
|
25
25
|
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
26
26
|
}
|
|
27
|
-
var LEGACY_ACCOUNT_PLUGIN_KEYS = [
|
|
28
|
-
"mbh-chat",
|
|
29
|
-
"mbh-chat-test",
|
|
30
|
-
"mbhchat",
|
|
31
|
-
"mbhchat-test",
|
|
32
|
-
"mbh-chat-uat",
|
|
33
|
-
"mbhchat-uat"
|
|
34
|
-
];
|
|
35
27
|
function nonEmptyString(value) {
|
|
36
28
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
37
29
|
}
|
|
38
|
-
function credentialUserId(value) {
|
|
39
|
-
return typeof value === "number" && Number.isSafeInteger(value) ? String(value) : nonEmptyString(value);
|
|
40
|
-
}
|
|
41
|
-
function credentialsFrom(source, deviceId) {
|
|
42
|
-
const userId = credentialUserId(source?.userId);
|
|
43
|
-
const botToken = nonEmptyString(source?.botToken);
|
|
44
|
-
if (userId && botToken && deviceId)
|
|
45
|
-
return { userId, botToken, deviceId };
|
|
46
|
-
return void 0;
|
|
47
|
-
}
|
|
48
30
|
function resolveSearchCredentials(metadata) {
|
|
49
31
|
const root = record(metadata);
|
|
50
32
|
const hardware = record(root?.hardware);
|
|
51
|
-
const
|
|
33
|
+
const account = record(root?.account);
|
|
52
34
|
const deviceId = nonEmptyString(hardware?.fingerprint);
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
35
|
+
const userIdValue = account?.userId;
|
|
36
|
+
const userId = typeof userIdValue === "number" && Number.isSafeInteger(userIdValue) ? String(userIdValue) : nonEmptyString(userIdValue);
|
|
37
|
+
const botToken = nonEmptyString(account?.botToken);
|
|
38
|
+
if (userId && botToken && deviceId)
|
|
39
|
+
return { userId, botToken, deviceId };
|
|
56
40
|
throw new WebSearchApiError("MISSING_CREDENTIALS", "\u641C\u7D22\u670D\u52A1\u5C1A\u672A\u51C6\u5907\u597D\uFF0C\u8BF7\u786E\u8BA4\u5DF2\u767B\u5F55\u58A8\u5B9D\u5E76\u5B8C\u6210\u5BA2\u6237\u7AEF\u521D\u59CB\u5316\u540E\u91CD\u8BD5\u3002");
|
|
57
41
|
}
|
|
58
42
|
function resolveSearchEndpoint(metadata) {
|
|
@@ -249,7 +233,7 @@ ${nonce}`;
|
|
|
249
233
|
cause: error
|
|
250
234
|
});
|
|
251
235
|
}
|
|
252
|
-
throw new WebSearchApiError("NETWORK_ERROR", `\u6682\u65F6\u65E0\u6CD5\u8FDE\u63A5${searchServiceLabel(service)}\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5\u3002`, {
|
|
236
|
+
throw new WebSearchApiError("NETWORK_ERROR", `\u6682\u65F6\u65E0\u6CD5\u8FDE\u63A5 ${searchServiceLabel(service)}\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5\u3002`, {
|
|
253
237
|
cause: error
|
|
254
238
|
});
|
|
255
239
|
}
|
|
@@ -260,23 +244,23 @@ ${nonce}`;
|
|
|
260
244
|
return parseResponse(text, query, service);
|
|
261
245
|
};
|
|
262
246
|
try {
|
|
263
|
-
const
|
|
264
|
-
if (
|
|
265
|
-
return
|
|
247
|
+
const bocha = await call("bocha_search");
|
|
248
|
+
if (bocha.results.length > 0)
|
|
249
|
+
return bocha;
|
|
266
250
|
} catch (error) {
|
|
267
251
|
if (signal?.aborted)
|
|
268
252
|
throw error;
|
|
269
253
|
}
|
|
270
|
-
return call("
|
|
254
|
+
return call("tavily_search");
|
|
271
255
|
}
|
|
272
256
|
};
|
|
273
257
|
|
|
274
|
-
// dist
|
|
258
|
+
// dist/src/tools.js
|
|
275
259
|
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
276
260
|
function createWebSearchTool(search) {
|
|
277
261
|
return defineTool({
|
|
278
262
|
name: "web_search",
|
|
279
|
-
description: "Search the public web with
|
|
263
|
+
description: "Search the public web with Mobook search services. Use Bocha first and fall back to Tavily when Bocha fails or returns no results. Use this for current information, source discovery, fact verification, news, weather, prices, schedules, or any question that requires internet access. In the final answer, summarize first, then present useful sources as a numbered list with Markdown links in the form [title | siteName](url), followed by a concise snippet-based explanation. Never expose the raw JSON or internal provider fields.",
|
|
280
264
|
parameters: {
|
|
281
265
|
query: { type: "string", required: true, description: "A focused web search query." },
|
|
282
266
|
count: { type: "integer", description: "Number of results to return. Defaults to 5; maximum 20." },
|
|
@@ -304,10 +288,10 @@ function createWebSearchTool(search) {
|
|
|
304
288
|
});
|
|
305
289
|
}
|
|
306
290
|
|
|
307
|
-
// dist
|
|
291
|
+
// dist/src/index.js
|
|
308
292
|
var MBH_WEB_SEARCH_SERVICE_KEY = "mbhWebSearch";
|
|
309
293
|
|
|
310
|
-
// dist
|
|
294
|
+
// dist/plugin/index.js
|
|
311
295
|
var name = "@dcrays/web-search";
|
|
312
296
|
var inject = ["tools"];
|
|
313
297
|
var Config = z.object({
|
package/src/api-client.js
CHANGED
|
@@ -15,36 +15,19 @@ function searchServiceLabel(service) {
|
|
|
15
15
|
function record(value) {
|
|
16
16
|
return value && typeof value === 'object' && !Array.isArray(value) ? value : undefined;
|
|
17
17
|
}
|
|
18
|
-
const LEGACY_ACCOUNT_PLUGIN_KEYS = [
|
|
19
|
-
'mbh-chat',
|
|
20
|
-
'mbh-chat-test',
|
|
21
|
-
'mbhchat',
|
|
22
|
-
'mbhchat-test',
|
|
23
|
-
'mbh-chat-uat',
|
|
24
|
-
'mbhchat-uat'
|
|
25
|
-
];
|
|
26
18
|
function nonEmptyString(value) {
|
|
27
19
|
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
28
20
|
}
|
|
29
|
-
function credentialUserId(value) {
|
|
30
|
-
return typeof value === 'number' && Number.isSafeInteger(value) ? String(value) : nonEmptyString(value);
|
|
31
|
-
}
|
|
32
|
-
function credentialsFrom(source, deviceId) {
|
|
33
|
-
const userId = credentialUserId(source?.userId);
|
|
34
|
-
const botToken = nonEmptyString(source?.botToken);
|
|
35
|
-
if (userId && botToken && deviceId)
|
|
36
|
-
return { userId, botToken, deviceId };
|
|
37
|
-
return undefined;
|
|
38
|
-
}
|
|
39
21
|
export function resolveSearchCredentials(metadata) {
|
|
40
22
|
const root = record(metadata);
|
|
41
23
|
const hardware = record(root?.hardware);
|
|
42
|
-
const
|
|
24
|
+
const account = record(root?.account);
|
|
43
25
|
const deviceId = nonEmptyString(hardware?.fingerprint);
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
26
|
+
const userIdValue = account?.userId;
|
|
27
|
+
const userId = typeof userIdValue === 'number' && Number.isSafeInteger(userIdValue) ? String(userIdValue) : nonEmptyString(userIdValue);
|
|
28
|
+
const botToken = nonEmptyString(account?.botToken);
|
|
29
|
+
if (userId && botToken && deviceId)
|
|
30
|
+
return { userId, botToken, deviceId };
|
|
48
31
|
throw new WebSearchApiError('MISSING_CREDENTIALS', '搜索服务尚未准备好,请确认已登录墨宝并完成客户端初始化后重试。');
|
|
49
32
|
}
|
|
50
33
|
export function resolveSearchEndpoint(metadata) {
|
|
@@ -243,7 +226,7 @@ export class WebSearchApiClient {
|
|
|
243
226
|
cause: error
|
|
244
227
|
});
|
|
245
228
|
}
|
|
246
|
-
throw new WebSearchApiError('NETWORK_ERROR',
|
|
229
|
+
throw new WebSearchApiError('NETWORK_ERROR', `暂时无法连接 ${searchServiceLabel(service)},请检查网络后重试。`, {
|
|
247
230
|
cause: error
|
|
248
231
|
});
|
|
249
232
|
}
|
|
@@ -254,14 +237,14 @@ export class WebSearchApiClient {
|
|
|
254
237
|
return parseResponse(text, query, service);
|
|
255
238
|
};
|
|
256
239
|
try {
|
|
257
|
-
const
|
|
258
|
-
if (
|
|
259
|
-
return
|
|
240
|
+
const bocha = await call('bocha_search');
|
|
241
|
+
if (bocha.results.length > 0)
|
|
242
|
+
return bocha;
|
|
260
243
|
}
|
|
261
244
|
catch (error) {
|
|
262
245
|
if (signal?.aborted)
|
|
263
246
|
throw error;
|
|
264
247
|
}
|
|
265
|
-
return call('
|
|
248
|
+
return call('tavily_search');
|
|
266
249
|
}
|
|
267
250
|
}
|
package/src/tools.js
CHANGED
|
@@ -2,7 +2,7 @@ import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
|
2
2
|
export function createWebSearchTool(search) {
|
|
3
3
|
return defineTool({
|
|
4
4
|
name: 'web_search',
|
|
5
|
-
description: 'Search the public web with
|
|
5
|
+
description: 'Search the public web with Mobook search services. Use Bocha first and fall back to Tavily when Bocha fails or returns no results. Use this for current information, source discovery, fact verification, news, weather, prices, schedules, or any question that requires internet access. In the final answer, summarize first, then present useful sources as a numbered list with Markdown links in the form [title | siteName](url), followed by a concise snippet-based explanation. Never expose the raw JSON or internal provider fields.',
|
|
6
6
|
parameters: {
|
|
7
7
|
query: { type: 'string', required: true, description: 'A focused web search query.' },
|
|
8
8
|
count: { type: 'integer', description: 'Number of results to return. Defaults to 5; maximum 20.' },
|