@zhin.js/agent 0.1.14 → 0.1.16
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 +80 -43
- package/lib/builtin/activate-skill-tool.d.ts +21 -0
- package/lib/builtin/activate-skill-tool.d.ts.map +1 -0
- package/lib/builtin/activate-skill-tool.js +57 -0
- package/lib/builtin/activate-skill-tool.js.map +1 -0
- package/lib/builtin/ask-user-tool.d.ts +28 -0
- package/lib/builtin/ask-user-tool.d.ts.map +1 -0
- package/lib/builtin/ask-user-tool.js +182 -0
- package/lib/builtin/ask-user-tool.js.map +1 -0
- package/lib/builtin/bash-tool.d.ts +23 -0
- package/lib/builtin/bash-tool.d.ts.map +1 -0
- package/lib/builtin/bash-tool.js +64 -0
- package/lib/builtin/bash-tool.js.map +1 -0
- package/lib/builtin/bing-search-html.d.ts +37 -0
- package/lib/builtin/bing-search-html.d.ts.map +1 -0
- package/lib/builtin/bing-search-html.js +116 -0
- package/lib/builtin/bing-search-html.js.map +1 -0
- package/lib/builtin/builtin-base-tool.d.ts +25 -0
- package/lib/builtin/builtin-base-tool.d.ts.map +1 -0
- package/lib/builtin/builtin-base-tool.js +30 -0
- package/lib/builtin/builtin-base-tool.js.map +1 -0
- package/lib/builtin/edit-file-tool.d.ts +13 -0
- package/lib/builtin/edit-file-tool.d.ts.map +1 -0
- package/lib/builtin/edit-file-tool.js +81 -0
- package/lib/builtin/edit-file-tool.js.map +1 -0
- package/lib/builtin/file-edit-quote-utils.d.ts +24 -0
- package/lib/builtin/file-edit-quote-utils.d.ts.map +1 -0
- package/lib/builtin/file-edit-quote-utils.js +81 -0
- package/lib/builtin/file-edit-quote-utils.js.map +1 -0
- package/lib/builtin/glob-tool.d.ts +23 -0
- package/lib/builtin/glob-tool.d.ts.map +1 -0
- package/lib/builtin/glob-tool.js +54 -0
- package/lib/builtin/glob-tool.js.map +1 -0
- package/lib/builtin/grep-tool.d.ts +23 -0
- package/lib/builtin/grep-tool.d.ts.map +1 -0
- package/lib/builtin/grep-tool.js +118 -0
- package/lib/builtin/grep-tool.js.map +1 -0
- package/lib/builtin/install-skill-tool.d.ts +24 -0
- package/lib/builtin/install-skill-tool.d.ts.map +1 -0
- package/lib/builtin/install-skill-tool.js +76 -0
- package/lib/builtin/install-skill-tool.js.map +1 -0
- package/lib/builtin/list-dir-tool.d.ts +13 -0
- package/lib/builtin/list-dir-tool.d.ts.map +1 -0
- package/lib/builtin/list-dir-tool.js +59 -0
- package/lib/builtin/list-dir-tool.js.map +1 -0
- package/lib/builtin/read-file-tool.d.ts +14 -0
- package/lib/builtin/read-file-tool.d.ts.map +1 -0
- package/lib/builtin/read-file-tool.js +77 -0
- package/lib/builtin/read-file-tool.js.map +1 -0
- package/lib/builtin/read-memory-tool.d.ts +14 -0
- package/lib/builtin/read-memory-tool.d.ts.map +1 -0
- package/lib/builtin/read-memory-tool.js +49 -0
- package/lib/builtin/read-memory-tool.js.map +1 -0
- package/lib/builtin/spawn-task-tool.d.ts +20 -0
- package/lib/builtin/spawn-task-tool.d.ts.map +1 -0
- package/lib/builtin/spawn-task-tool.js +57 -0
- package/lib/builtin/spawn-task-tool.js.map +1 -0
- package/lib/builtin/todo-read-tool.d.ts +14 -0
- package/lib/builtin/todo-read-tool.d.ts.map +1 -0
- package/lib/builtin/todo-read-tool.js +56 -0
- package/lib/builtin/todo-read-tool.js.map +1 -0
- package/lib/builtin/todo-write-tool.d.ts +14 -0
- package/lib/builtin/todo-write-tool.d.ts.map +1 -0
- package/lib/builtin/todo-write-tool.js +54 -0
- package/lib/builtin/todo-write-tool.js.map +1 -0
- package/lib/builtin/web-fetch-tool.d.ts +19 -0
- package/lib/builtin/web-fetch-tool.d.ts.map +1 -0
- package/lib/builtin/web-fetch-tool.js +89 -0
- package/lib/builtin/web-fetch-tool.js.map +1 -0
- package/lib/builtin/web-search-locale.d.ts +16 -0
- package/lib/builtin/web-search-locale.d.ts.map +1 -0
- package/lib/builtin/web-search-locale.js +73 -0
- package/lib/builtin/web-search-locale.js.map +1 -0
- package/lib/builtin/web-search-tool.d.ts +20 -0
- package/lib/builtin/web-search-tool.d.ts.map +1 -0
- package/lib/builtin/web-search-tool.js +105 -0
- package/lib/builtin/web-search-tool.js.map +1 -0
- package/lib/builtin/web-tool-utils.d.ts +4 -0
- package/lib/builtin/web-tool-utils.d.ts.map +1 -0
- package/lib/builtin/web-tool-utils.js +4 -0
- package/lib/builtin/web-tool-utils.js.map +1 -0
- package/lib/builtin/write-file-tool.d.ts +13 -0
- package/lib/builtin/write-file-tool.d.ts.map +1 -0
- package/lib/builtin/write-file-tool.js +51 -0
- package/lib/builtin/write-file-tool.js.map +1 -0
- package/lib/builtin/write-memory-tool.d.ts +14 -0
- package/lib/builtin/write-memory-tool.d.ts.map +1 -0
- package/lib/builtin/write-memory-tool.js +50 -0
- package/lib/builtin/write-memory-tool.js.map +1 -0
- package/lib/builtin-tools.d.ts +10 -11
- package/lib/builtin-tools.d.ts.map +1 -1
- package/lib/builtin-tools.js +44 -862
- package/lib/builtin-tools.js.map +1 -1
- package/lib/defaults/tools.d.ts +3 -6
- package/lib/defaults/tools.d.ts.map +1 -1
- package/lib/defaults/tools.js +3 -11
- package/lib/defaults/tools.js.map +1 -1
- package/lib/index.d.ts +25 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +24 -3
- package/lib/index.js.map +1 -1
- package/lib/init/create-zhin-agent.d.ts.map +1 -1
- package/lib/init/create-zhin-agent.js +4 -3
- package/lib/init/create-zhin-agent.js.map +1 -1
- package/lib/init/message-media.d.ts +8 -0
- package/lib/init/message-media.d.ts.map +1 -0
- package/lib/init/message-media.js +75 -0
- package/lib/init/message-media.js.map +1 -0
- package/lib/init/output-renderer.d.ts +3 -0
- package/lib/init/output-renderer.d.ts.map +1 -0
- package/lib/init/output-renderer.js +38 -0
- package/lib/init/output-renderer.js.map +1 -0
- package/lib/init/register-ai-trigger.d.ts +1 -1
- package/lib/init/register-ai-trigger.d.ts.map +1 -1
- package/lib/init/register-ai-trigger.js +35 -159
- package/lib/init/register-ai-trigger.js.map +1 -1
- package/lib/init/register-builtin-tools.d.ts.map +1 -1
- package/lib/init/register-builtin-tools.js +9 -5
- package/lib/init/register-builtin-tools.js.map +1 -1
- package/lib/orchestrator/index.d.ts +2 -0
- package/lib/orchestrator/index.d.ts.map +1 -1
- package/lib/orchestrator/index.js +1 -0
- package/lib/orchestrator/index.js.map +1 -1
- package/lib/orchestrator/resource-registry.d.ts +1 -0
- package/lib/orchestrator/resource-registry.d.ts.map +1 -1
- package/lib/orchestrator/resource-registry.js +6 -0
- package/lib/orchestrator/resource-registry.js.map +1 -1
- package/lib/orchestrator/tool-registry.d.ts +5 -11
- package/lib/orchestrator/tool-registry.d.ts.map +1 -1
- package/lib/orchestrator/tool-registry.js +30 -75
- package/lib/orchestrator/tool-registry.js.map +1 -1
- package/lib/orchestrator/tool-selection.d.ts +39 -0
- package/lib/orchestrator/tool-selection.d.ts.map +1 -0
- package/lib/orchestrator/tool-selection.js +319 -0
- package/lib/orchestrator/tool-selection.js.map +1 -0
- package/lib/orchestrator/types.d.ts +2 -0
- package/lib/orchestrator/types.d.ts.map +1 -1
- package/lib/reserved-tools.d.ts +3 -0
- package/lib/reserved-tools.d.ts.map +1 -0
- package/lib/reserved-tools.js +30 -0
- package/lib/reserved-tools.js.map +1 -0
- package/lib/service.d.ts +9 -5
- package/lib/service.d.ts.map +1 -1
- package/lib/service.js +42 -36
- package/lib/service.js.map +1 -1
- package/lib/subagent.d.ts +6 -0
- package/lib/subagent.d.ts.map +1 -1
- package/lib/subagent.js +33 -15
- package/lib/subagent.js.map +1 -1
- package/lib/task-executor.d.ts +1 -0
- package/lib/task-executor.d.ts.map +1 -1
- package/lib/task-executor.js +15 -8
- package/lib/task-executor.js.map +1 -1
- package/lib/zhin-agent/builtin-tools.d.ts +1 -3
- package/lib/zhin-agent/builtin-tools.d.ts.map +1 -1
- package/lib/zhin-agent/builtin-tools.js +4 -41
- package/lib/zhin-agent/builtin-tools.js.map +1 -1
- package/lib/zhin-agent/config.d.ts +7 -0
- package/lib/zhin-agent/config.d.ts.map +1 -1
- package/lib/zhin-agent/config.js +12 -7
- package/lib/zhin-agent/config.js.map +1 -1
- package/lib/zhin-agent/context-budget.d.ts +27 -0
- package/lib/zhin-agent/context-budget.d.ts.map +1 -0
- package/lib/zhin-agent/context-budget.js +50 -0
- package/lib/zhin-agent/context-budget.js.map +1 -0
- package/lib/zhin-agent/index.d.ts +10 -0
- package/lib/zhin-agent/index.d.ts.map +1 -1
- package/lib/zhin-agent/index.js +120 -84
- package/lib/zhin-agent/index.js.map +1 -1
- package/lib/zhin-agent/model-harness.d.ts +29 -0
- package/lib/zhin-agent/model-harness.d.ts.map +1 -0
- package/lib/zhin-agent/model-harness.js +67 -0
- package/lib/zhin-agent/model-harness.js.map +1 -0
- package/lib/zhin-agent/pre-exec.d.ts +7 -0
- package/lib/zhin-agent/pre-exec.d.ts.map +1 -0
- package/lib/zhin-agent/pre-exec.js +25 -0
- package/lib/zhin-agent/pre-exec.js.map +1 -0
- package/lib/zhin-agent/prompt.d.ts +10 -8
- package/lib/zhin-agent/prompt.d.ts.map +1 -1
- package/lib/zhin-agent/prompt.js +37 -30
- package/lib/zhin-agent/prompt.js.map +1 -1
- package/lib/zhin-agent/text-sanitize.d.ts +8 -0
- package/lib/zhin-agent/text-sanitize.d.ts.map +1 -0
- package/lib/zhin-agent/text-sanitize.js +19 -0
- package/lib/zhin-agent/text-sanitize.js.map +1 -0
- package/lib/zhin-agent/tool-runtime.d.ts +31 -0
- package/lib/zhin-agent/tool-runtime.d.ts.map +1 -0
- package/lib/zhin-agent/tool-runtime.js +49 -0
- package/lib/zhin-agent/tool-runtime.js.map +1 -0
- package/package.json +8 -6
- package/lib/tools.d.ts +0 -45
- package/lib/tools.d.ts.map +0 -1
- package/lib/tools.js +0 -205
- package/lib/tools.js.map +0 -1
- package/lib/zhin-agent/tool-collector.d.ts +0 -22
- package/lib/zhin-agent/tool-collector.d.ts.map +0 -1
- package/lib/zhin-agent/tool-collector.js +0 -225
- package/lib/zhin-agent/tool-collector.js.map +0 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* todo_read — 读取当前任务计划列表(BuiltinBaseTool)
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
import { errMsg } from '../discovery/utils.js';
|
|
7
|
+
import { BuiltinBaseTool } from './builtin-base-tool.js';
|
|
8
|
+
export const TODO_READ_PARAMETERS = {
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
chat_id: {
|
|
12
|
+
type: 'string',
|
|
13
|
+
description: '聊天范围(传 "global" 表示全局,或传具体聊天 ID)',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
required: ['chat_id'],
|
|
17
|
+
};
|
|
18
|
+
export class TodoReadBuiltinTool extends BuiltinBaseTool {
|
|
19
|
+
dataDir;
|
|
20
|
+
name = 'todo_read';
|
|
21
|
+
description = '读取当前任务计划列表,用于查看进度和待办事项';
|
|
22
|
+
parameters = TODO_READ_PARAMETERS;
|
|
23
|
+
kind = 'plan';
|
|
24
|
+
constructor(dataDir) {
|
|
25
|
+
super();
|
|
26
|
+
this.dataDir = dataDir;
|
|
27
|
+
this.tags.push('plan', 'todo');
|
|
28
|
+
this.keywords.push('任务', '计划', '进度', 'todo', '待办');
|
|
29
|
+
}
|
|
30
|
+
async run(args, _context) {
|
|
31
|
+
try {
|
|
32
|
+
const chatId = args.chat_id;
|
|
33
|
+
const dir = chatId && chatId !== 'global'
|
|
34
|
+
? path.join(this.dataDir, 'groups', chatId)
|
|
35
|
+
: this.dataDir;
|
|
36
|
+
const todoPath = path.join(dir, 'TODO.json');
|
|
37
|
+
if (!fs.existsSync(todoPath))
|
|
38
|
+
return 'No tasks found. Use todo_write to create a plan.';
|
|
39
|
+
const data = JSON.parse(await fs.promises.readFile(todoPath, 'utf-8'));
|
|
40
|
+
if (!data.items || data.items.length === 0)
|
|
41
|
+
return 'Task list is empty.';
|
|
42
|
+
const lines = data.items.map((item, i) => {
|
|
43
|
+
const status = item.status === 'done' ? '✅' : item.status === 'in-progress' ? '🔄' : '⬜';
|
|
44
|
+
return `${status} ${i + 1}. ${item.title}${item.detail ? ' — ' + item.detail : ''}`;
|
|
45
|
+
});
|
|
46
|
+
return `📋 Tasks (${data.items.filter((i) => i.status === 'done').length}/${data.items.length} done):\n${lines.join('\n')}`;
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
return `Error: ${errMsg(e)}`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export function createTodoReadTool(dataDir) {
|
|
54
|
+
return new TodoReadBuiltinTool(dataDir).toTool();
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=todo-read-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"todo-read-tool.js","sourceRoot":"","sources":["../../src/builtin/todo-read-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Tool, ToolContext, ToolParametersSchema, ToolResult } from '@zhin.js/core';
|
|
2
|
+
import { BuiltinBaseTool } from './builtin-base-tool.js';
|
|
3
|
+
export declare const TODO_WRITE_PARAMETERS: ToolParametersSchema;
|
|
4
|
+
export declare class TodoWriteBuiltinTool extends BuiltinBaseTool {
|
|
5
|
+
private readonly dataDir;
|
|
6
|
+
readonly name = "todo_write";
|
|
7
|
+
readonly description = "\u521B\u5EFA\u6216\u66F4\u65B0\u4EFB\u52A1\u8BA1\u5212\uFF0C\u7528\u4E8E\u5206\u89E3\u590D\u6742\u4EFB\u52A1\u5E76\u8DDF\u8E2A\u8FDB\u5EA6";
|
|
8
|
+
readonly parameters: ToolParametersSchema<Record<string, any>>;
|
|
9
|
+
readonly kind = "plan";
|
|
10
|
+
constructor(dataDir: string);
|
|
11
|
+
run(args: Record<string, unknown>, _context?: ToolContext): Promise<ToolResult>;
|
|
12
|
+
}
|
|
13
|
+
export declare function createTodoWriteTool(dataDir: string): Tool;
|
|
14
|
+
//# sourceMappingURL=todo-write-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"todo-write-tool.d.ts","sourceRoot":"","sources":["../../src/builtin/todo-write-tool.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEzF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,eAAO,MAAM,qBAAqB,EAAE,oBAanC,CAAC;AAEF,qBAAa,oBAAqB,SAAQ,eAAe;IAM3C,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,WAAW,gJAA6B;IACjD,QAAQ,CAAC,UAAU,4CAAyB;IAC5C,QAAQ,CAAC,IAAI,UAAU;gBAEM,OAAO,EAAE,MAAM;IAMtC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAetF;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEzD"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* todo_write — 创建或更新任务计划(BuiltinBaseTool)
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'node:fs/promises';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
import { errMsg } from '../discovery/utils.js';
|
|
7
|
+
import { BuiltinBaseTool } from './builtin-base-tool.js';
|
|
8
|
+
export const TODO_WRITE_PARAMETERS = {
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
items: {
|
|
12
|
+
type: 'array',
|
|
13
|
+
description: '任务列表 [{title, detail?, status: pending|in-progress|done}]',
|
|
14
|
+
},
|
|
15
|
+
chat_id: {
|
|
16
|
+
type: 'string',
|
|
17
|
+
description: '聊天范围(可选)',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
required: ['items'],
|
|
21
|
+
};
|
|
22
|
+
export class TodoWriteBuiltinTool extends BuiltinBaseTool {
|
|
23
|
+
dataDir;
|
|
24
|
+
name = 'todo_write';
|
|
25
|
+
description = '创建或更新任务计划,用于分解复杂任务并跟踪进度';
|
|
26
|
+
parameters = TODO_WRITE_PARAMETERS;
|
|
27
|
+
kind = 'plan';
|
|
28
|
+
constructor(dataDir) {
|
|
29
|
+
super();
|
|
30
|
+
this.dataDir = dataDir;
|
|
31
|
+
this.tags.push('plan', 'todo');
|
|
32
|
+
this.keywords.push('创建计划', '更新任务', '标记完成', 'todo');
|
|
33
|
+
}
|
|
34
|
+
async run(args, _context) {
|
|
35
|
+
try {
|
|
36
|
+
const chatId = args.chat_id;
|
|
37
|
+
const dir = chatId ? path.join(this.dataDir, 'groups', chatId) : this.dataDir;
|
|
38
|
+
const todoPath = path.join(dir, 'TODO.json');
|
|
39
|
+
await fs.mkdir(path.dirname(todoPath), { recursive: true });
|
|
40
|
+
const items = args.items;
|
|
41
|
+
const data = { updated_at: new Date().toISOString(), items };
|
|
42
|
+
await fs.writeFile(todoPath, JSON.stringify(data, null, 2), 'utf-8');
|
|
43
|
+
const done = items.filter((i) => i.status === 'done').length;
|
|
44
|
+
return `✅ Tasks updated (${done}/${items.length} done)`;
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
return `Error: ${errMsg(e)}`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export function createTodoWriteTool(dataDir) {
|
|
52
|
+
return new TodoWriteBuiltinTool(dataDir).toTool();
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=todo-write-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"todo-write-tool.js","sourceRoot":"","sources":["../../src/builtin/todo-write-tool.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,CAAC,MAAM,qBAAqB,GAAyB;IACzD,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,KAAK,EAAE;YACL,IAAI,EAAE,OAAO;YACb,WAAW,EAAE,2DAA2D;SACzE;QACD,OAAO,EAAE;YACP,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,UAAU;SACxB;KACF;IACD,QAAQ,EAAE,CAAC,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,OAAO,oBAAqB,SAAQ,eAAe;IAM1B;IALpB,IAAI,GAAG,YAAY,CAAC;IACpB,WAAW,GAAG,yBAAyB,CAAC;IACxC,UAAU,GAAG,qBAAqB,CAAC;IACnC,IAAI,GAAG,MAAM,CAAC;IAEvB,YAA6B,OAAe;QAC1C,KAAK,EAAE,CAAC;QADmB,YAAO,GAAP,OAAO,CAAQ;QAE1C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAA6B,EAAE,QAAsB;QAC7D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;YAC5B,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;YACxF,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;YAC7C,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAc,CAAC;YAClC,MAAM,IAAI,GAAG,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC;YAC7D,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACrE,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;YAClE,OAAO,oBAAoB,IAAI,IAAI,KAAK,CAAC,MAAM,QAAQ,CAAC;QAC1D,CAAC;QAAC,OAAO,CAAU,EAAE,CAAC;YACpB,OAAO,UAAU,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/B,CAAC;IACH,CAAC;CACF;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,OAAO,IAAI,oBAAoB,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* web_fetch — HTTP(S) 抓取、SSRF 防护、HTML 去标签与长度截断
|
|
3
|
+
*/
|
|
4
|
+
import type { Tool, ToolContext, ToolParametersSchema, ToolResult } from '@zhin.js/core';
|
|
5
|
+
import { BuiltinBaseTool } from './builtin-base-tool.js';
|
|
6
|
+
export declare const WEB_FETCH_DEFAULT_MAX_LENGTH: number;
|
|
7
|
+
export declare const WEB_FETCH_PARAMETERS: ToolParametersSchema;
|
|
8
|
+
/** 与原先 builtin-tools 中 web_fetch 一致的正文提取链 */
|
|
9
|
+
export declare function stripFetchedHtmlToText(html: string): string;
|
|
10
|
+
export declare class WebFetchBuiltinTool extends BuiltinBaseTool {
|
|
11
|
+
readonly name = "web_fetch";
|
|
12
|
+
readonly description = "\u6293\u53D6\u6307\u5B9A URL \u7684\u7F51\u9875\u5185\u5BB9\u5E76\u63D0\u53D6\u6B63\u6587\uFF08\u53BB\u9664\u5E7F\u544A\u3001\u811A\u672C\u7B49\uFF09\uFF0C\u8FD4\u56DE\u53EF\u8BFB\u6587\u672C\u3002\u4EC5\u652F\u6301 http/https \u534F\u8BAE\u3002";
|
|
13
|
+
readonly parameters: ToolParametersSchema<Record<string, any>>;
|
|
14
|
+
readonly kind = "web";
|
|
15
|
+
constructor();
|
|
16
|
+
run(args: Record<string, unknown>, _context?: ToolContext): Promise<ToolResult>;
|
|
17
|
+
}
|
|
18
|
+
export declare function createWebFetchTool(): Tool;
|
|
19
|
+
//# sourceMappingURL=web-fetch-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-fetch-tool.d.ts","sourceRoot":"","sources":["../../src/builtin/web-fetch-tool.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEzF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,eAAO,MAAM,4BAA4B,QAAY,CAAC;AAEtD,eAAO,MAAM,oBAAoB,EAAE,oBAOlC,CAAC;AAEF,6CAA6C;AAC7C,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiB3D;AAgBD,qBAAa,mBAAoB,SAAQ,eAAe;IACtD,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,WAAW,2PACwC;IAC5D,QAAQ,CAAC,UAAU,4CAAwB;IAC3C,QAAQ,CAAC,IAAI,SAAS;;IAiBhB,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CA8BtF;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { errMsg } from '../discovery/utils.js';
|
|
2
|
+
import { BuiltinBaseTool } from './builtin-base-tool.js';
|
|
3
|
+
import { WEB_TOOL_FETCH_TIMEOUT_MS, ZHIN_WEB_USER_AGENT } from './web-tool-utils.js';
|
|
4
|
+
export const WEB_FETCH_DEFAULT_MAX_LENGTH = 20 * 1024;
|
|
5
|
+
export const WEB_FETCH_PARAMETERS = {
|
|
6
|
+
type: 'object',
|
|
7
|
+
properties: {
|
|
8
|
+
url: { type: 'string', description: '要抓取的完整 URL(需 http 或 https)' },
|
|
9
|
+
max_length: { type: 'number', description: '最大返回字符数(默认 20480)' },
|
|
10
|
+
},
|
|
11
|
+
required: ['url'],
|
|
12
|
+
};
|
|
13
|
+
/** 与原先 builtin-tools 中 web_fetch 一致的正文提取链 */
|
|
14
|
+
export function stripFetchedHtmlToText(html) {
|
|
15
|
+
return html
|
|
16
|
+
.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
|
|
17
|
+
.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
|
|
18
|
+
.replace(/<nav[^>]*>[\s\S]*?<\/nav>/gi, '')
|
|
19
|
+
.replace(/<footer[^>]*>[\s\S]*?<\/footer>/gi, '')
|
|
20
|
+
.replace(/<header[^>]*>[\s\S]*?<\/header>/gi, ' ')
|
|
21
|
+
.replace(/<form[^>]*>[\s\S]*?<\/form>/gi, '')
|
|
22
|
+
.replace(/<!--[\s\S]*?-->/g, '')
|
|
23
|
+
.replace(/<[^>]+>/g, ' ')
|
|
24
|
+
.replace(/ /gi, ' ')
|
|
25
|
+
.replace(/&/g, '&')
|
|
26
|
+
.replace(/</g, '<')
|
|
27
|
+
.replace(/>/g, '>')
|
|
28
|
+
.replace(/"/g, '"')
|
|
29
|
+
.replace(/\s+/g, ' ')
|
|
30
|
+
.trim();
|
|
31
|
+
}
|
|
32
|
+
function isBlockedSsrfHostname(hostname) {
|
|
33
|
+
const h = hostname.toLowerCase();
|
|
34
|
+
return (h === 'localhost' ||
|
|
35
|
+
h === '127.0.0.1' ||
|
|
36
|
+
h === '::1' ||
|
|
37
|
+
h === '0.0.0.0' ||
|
|
38
|
+
h.endsWith('.local') ||
|
|
39
|
+
h.startsWith('10.') ||
|
|
40
|
+
h.startsWith('192.168.') ||
|
|
41
|
+
/^172\.(1[6-9]|2\d|3[01])\./.test(h));
|
|
42
|
+
}
|
|
43
|
+
export class WebFetchBuiltinTool extends BuiltinBaseTool {
|
|
44
|
+
name = 'web_fetch';
|
|
45
|
+
description = '抓取指定 URL 的网页内容并提取正文(去除广告、脚本等),返回可读文本。仅支持 http/https 协议。';
|
|
46
|
+
parameters = WEB_FETCH_PARAMETERS;
|
|
47
|
+
kind = 'web';
|
|
48
|
+
constructor() {
|
|
49
|
+
super();
|
|
50
|
+
this.tags.push('web', 'fetch');
|
|
51
|
+
this.keywords.push('抓取网页', '打开链接', '获取网页', '读网页', 'fetch', 'url', '链接内容', '网页内容');
|
|
52
|
+
}
|
|
53
|
+
async run(args, _context) {
|
|
54
|
+
try {
|
|
55
|
+
let parsedUrl;
|
|
56
|
+
try {
|
|
57
|
+
parsedUrl = new URL(String(args.url ?? ''));
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return `Error: 无效的 URL 格式`;
|
|
61
|
+
}
|
|
62
|
+
if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
|
|
63
|
+
return `Error: 仅支持 http/https 协议,拒绝 ${parsedUrl.protocol}`;
|
|
64
|
+
}
|
|
65
|
+
const hostname = parsedUrl.hostname.toLowerCase();
|
|
66
|
+
if (isBlockedSsrfHostname(hostname)) {
|
|
67
|
+
return `Error: 禁止访问内网地址 ${hostname}(SSRF 防护)`;
|
|
68
|
+
}
|
|
69
|
+
const response = await fetch(String(args.url ?? ''), {
|
|
70
|
+
headers: { 'User-Agent': ZHIN_WEB_USER_AGENT },
|
|
71
|
+
signal: AbortSignal.timeout(WEB_TOOL_FETCH_TIMEOUT_MS),
|
|
72
|
+
redirect: 'follow',
|
|
73
|
+
});
|
|
74
|
+
if (!response.ok)
|
|
75
|
+
return `HTTP ${response.status}: ${response.statusText}`;
|
|
76
|
+
const html = await response.text();
|
|
77
|
+
const text = stripFetchedHtmlToText(html);
|
|
78
|
+
const maxLen = typeof args.max_length === 'number' ? args.max_length : WEB_FETCH_DEFAULT_MAX_LENGTH;
|
|
79
|
+
return text.length > maxLen ? text.slice(0, maxLen) + '\n...(truncated)' : text;
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
return `Error: ${errMsg(e)}`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export function createWebFetchTool() {
|
|
87
|
+
return new WebFetchBuiltinTool().toTool();
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=web-fetch-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-fetch-tool.js","sourceRoot":"","sources":["../../src/builtin/web-fetch-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* web_search 的 Bing 市场/语言:优先 ToolContext.extra,其次用户档案,默认中文。
|
|
3
|
+
*/
|
|
4
|
+
import type { ToolContext } from '@zhin.js/core';
|
|
5
|
+
/** 写入 ToolContext.extra 的键(集成方也可直接设置以覆盖档案) */
|
|
6
|
+
export declare const WEB_SEARCH_LOCALE_EXTRA_KEY: "web_search_locale";
|
|
7
|
+
/** 无用户设置时的 Bing setmkt / 界面语言 */
|
|
8
|
+
export declare const DEFAULT_WEB_SEARCH_MARKET = "zh-CN";
|
|
9
|
+
/**
|
|
10
|
+
* 将 user_profile 中的自然语言或简写规范为 `xx-YY`(Bing setmkt 常用形式)。
|
|
11
|
+
*/
|
|
12
|
+
export declare function normalizeWebSearchLocaleHint(raw: string): string;
|
|
13
|
+
/** 随 Bing 市场生成 Accept-Language,与 setmkt 一致 */
|
|
14
|
+
export declare function acceptLanguageForMarket(market: string): string;
|
|
15
|
+
export declare function resolveWebSearchMarketFromContext(context?: ToolContext): string;
|
|
16
|
+
//# sourceMappingURL=web-search-locale.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-search-locale.d.ts","sourceRoot":"","sources":["../../src/builtin/web-search-locale.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,8CAA8C;AAC9C,eAAO,MAAM,2BAA2B,EAAG,mBAA4B,CAAC;AAExE,iCAAiC;AACjC,eAAO,MAAM,yBAAyB,UAAU,CAAC;AAEjD;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAgDhE;AAED,8CAA8C;AAC9C,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQ9D;AAED,wBAAgB,iCAAiC,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,MAAM,CAM/E"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/** 写入 ToolContext.extra 的键(集成方也可直接设置以覆盖档案) */
|
|
2
|
+
export const WEB_SEARCH_LOCALE_EXTRA_KEY = 'web_search_locale';
|
|
3
|
+
/** 无用户设置时的 Bing setmkt / 界面语言 */
|
|
4
|
+
export const DEFAULT_WEB_SEARCH_MARKET = 'zh-CN';
|
|
5
|
+
/**
|
|
6
|
+
* 将 user_profile 中的自然语言或简写规范为 `xx-YY`(Bing setmkt 常用形式)。
|
|
7
|
+
*/
|
|
8
|
+
export function normalizeWebSearchLocaleHint(raw) {
|
|
9
|
+
const s = raw.trim().replace(/_/g, '-');
|
|
10
|
+
if (!s)
|
|
11
|
+
return DEFAULT_WEB_SEARCH_MARKET;
|
|
12
|
+
const lower = s.toLowerCase();
|
|
13
|
+
const aliases = {
|
|
14
|
+
中文: 'zh-CN',
|
|
15
|
+
简体: 'zh-CN',
|
|
16
|
+
简体中文: 'zh-CN',
|
|
17
|
+
繁体: 'zh-TW',
|
|
18
|
+
繁中: 'zh-TW',
|
|
19
|
+
繁體中文: 'zh-TW',
|
|
20
|
+
english: 'en-US',
|
|
21
|
+
英文: 'en-US',
|
|
22
|
+
英語: 'en-US',
|
|
23
|
+
ja: 'ja-JP',
|
|
24
|
+
日语: 'ja-JP',
|
|
25
|
+
日本語: 'ja-JP',
|
|
26
|
+
ko: 'ko-KR',
|
|
27
|
+
韩语: 'ko-KR',
|
|
28
|
+
한국어: 'ko-KR',
|
|
29
|
+
de: 'de-DE',
|
|
30
|
+
fr: 'fr-FR',
|
|
31
|
+
es: 'es-ES',
|
|
32
|
+
zh: 'zh-CN',
|
|
33
|
+
en: 'en-US',
|
|
34
|
+
};
|
|
35
|
+
if (aliases[lower])
|
|
36
|
+
return aliases[lower];
|
|
37
|
+
if (/^[a-z]{2}-[a-z]{2}$/i.test(s)) {
|
|
38
|
+
const [a, b] = s.split('-');
|
|
39
|
+
return `${a.toLowerCase()}-${b.toUpperCase()}`;
|
|
40
|
+
}
|
|
41
|
+
if (/^[a-z]{2}$/i.test(s)) {
|
|
42
|
+
const two = lower;
|
|
43
|
+
const byTwo = {
|
|
44
|
+
zh: 'zh-CN',
|
|
45
|
+
en: 'en-US',
|
|
46
|
+
ja: 'ja-JP',
|
|
47
|
+
ko: 'ko-KR',
|
|
48
|
+
de: 'de-DE',
|
|
49
|
+
fr: 'fr-FR',
|
|
50
|
+
es: 'es-ES',
|
|
51
|
+
};
|
|
52
|
+
return byTwo[two] ?? `${two}-${two.toUpperCase()}`;
|
|
53
|
+
}
|
|
54
|
+
return DEFAULT_WEB_SEARCH_MARKET;
|
|
55
|
+
}
|
|
56
|
+
/** 随 Bing 市场生成 Accept-Language,与 setmkt 一致 */
|
|
57
|
+
export function acceptLanguageForMarket(market) {
|
|
58
|
+
const m = market.trim();
|
|
59
|
+
const parts = m.split('-');
|
|
60
|
+
if (parts.length >= 2) {
|
|
61
|
+
const lang = parts[0].toLowerCase();
|
|
62
|
+
return `${m},${lang};q=0.9,en;q=0.8`;
|
|
63
|
+
}
|
|
64
|
+
return `${m},${m};q=0.9,en;q=0.8`;
|
|
65
|
+
}
|
|
66
|
+
export function resolveWebSearchMarketFromContext(context) {
|
|
67
|
+
const raw = context?.extra?.[WEB_SEARCH_LOCALE_EXTRA_KEY];
|
|
68
|
+
if (typeof raw === 'string' && raw.trim()) {
|
|
69
|
+
return normalizeWebSearchLocaleHint(raw);
|
|
70
|
+
}
|
|
71
|
+
return DEFAULT_WEB_SEARCH_MARKET;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=web-search-locale.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-search-locale.js","sourceRoot":"","sources":["../../src/builtin/web-search-locale.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* web_search — Bing HTML 搜索、域名过滤、会话内次数上限
|
|
3
|
+
* (DuckDuckGo HTML 接口已易触发人机验证,故改用 Bing;解析逻辑对齐
|
|
4
|
+
* claude-code bingAdapter)
|
|
5
|
+
*/
|
|
6
|
+
import type { Tool, ToolContext, ToolParametersSchema, ToolResult } from '@zhin.js/core';
|
|
7
|
+
import { BuiltinBaseTool } from './builtin-base-tool.js';
|
|
8
|
+
export declare const MAX_WEB_SEARCH_COUNT = 20;
|
|
9
|
+
export declare const WEB_SEARCH_PARAMETERS: ToolParametersSchema;
|
|
10
|
+
export declare class WebSearchBuiltinTool extends BuiltinBaseTool {
|
|
11
|
+
readonly name = "web_search";
|
|
12
|
+
readonly description = "\u5728\u4E92\u8054\u7F51\u4E0A\u641C\u7D22\uFF08Bing\uFF09\uFF0C\u8FD4\u56DE\u5339\u914D\u7684\u6807\u9898\u3001URL \u548C\u6458\u8981\u7247\u6BB5\u3002\u7528\u4E8E\u67E5\u8D44\u6599\u3001\u627E\u7F51\u9875\u3002\u652F\u6301\u57DF\u540D\u8FC7\u6EE4\u3002\u9ED8\u8BA4\u4E2D\u6587\u7ED3\u679C\uFF1B\u7528\u6237\u53EF\u5728 user_profile \u4E2D\u8BBE\u7F6E language \u6216 preferred_language \u8986\u76D6\uFF1B\u4E5F\u53EF\u7531\u96C6\u6210\u65B9\u8BBE\u7F6E ToolContext.extra.web_search_locale\u3002";
|
|
13
|
+
readonly parameters: ToolParametersSchema<Record<string, any>>;
|
|
14
|
+
readonly kind = "web";
|
|
15
|
+
private searchCount;
|
|
16
|
+
constructor();
|
|
17
|
+
run(args: Record<string, unknown>, _context?: ToolContext): Promise<ToolResult>;
|
|
18
|
+
}
|
|
19
|
+
export declare function createWebSearchTool(): Tool;
|
|
20
|
+
//# sourceMappingURL=web-search-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-search-tool.d.ts","sourceRoot":"","sources":["../../src/builtin/web-search-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEzF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAWzD,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,eAAO,MAAM,qBAAqB,EAAE,oBAiBnC,CAAC;AAqCF,qBAAa,oBAAqB,SAAQ,eAAe;IACvD,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,WAAW,sfAC6I;IACjK,QAAQ,CAAC,UAAU,4CAAyB;IAC5C,QAAQ,CAAC,IAAI,SAAS;IAEtB,OAAO,CAAC,WAAW,CAAK;;IAmBlB,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CA6CtF;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { errMsg } from '../discovery/utils.js';
|
|
2
|
+
import { BuiltinBaseTool } from './builtin-base-tool.js';
|
|
3
|
+
import { BING_SEARCH_FETCH_TIMEOUT_MS, bingSearchFetchHeaders, buildBingSearchUrl, extractBingResults, hostnameMatchesList, } from './bing-search-html.js';
|
|
4
|
+
import { resolveWebSearchMarketFromContext } from './web-search-locale.js';
|
|
5
|
+
export const MAX_WEB_SEARCH_COUNT = 20;
|
|
6
|
+
export const WEB_SEARCH_PARAMETERS = {
|
|
7
|
+
type: 'object',
|
|
8
|
+
properties: {
|
|
9
|
+
query: { type: 'string', description: '搜索关键词或完整查询语句' },
|
|
10
|
+
limit: { type: 'number', description: '返回结果数量(默认 5,建议 1–10)' },
|
|
11
|
+
allowed_domains: {
|
|
12
|
+
type: 'array',
|
|
13
|
+
description: '仅保留这些域名的结果(可选,如 ["github.com", "stackoverflow.com"]);含子域',
|
|
14
|
+
items: { type: 'string' },
|
|
15
|
+
},
|
|
16
|
+
blocked_domains: {
|
|
17
|
+
type: 'array',
|
|
18
|
+
description: '排除这些域名的结果(可选);含子域',
|
|
19
|
+
items: { type: 'string' },
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
required: ['query'],
|
|
23
|
+
};
|
|
24
|
+
function filterByDomains(rows, allowedDomains, blockedDomains) {
|
|
25
|
+
let filtered = rows;
|
|
26
|
+
if (Array.isArray(allowedDomains) && allowedDomains.length) {
|
|
27
|
+
const allowed = allowedDomains.filter((d) => typeof d === 'string' && d.trim().length > 0);
|
|
28
|
+
filtered = filtered.filter(r => {
|
|
29
|
+
try {
|
|
30
|
+
const hostname = new URL(r.url).hostname;
|
|
31
|
+
return allowed.some(d => hostnameMatchesList(hostname, d));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
if (Array.isArray(blockedDomains) && blockedDomains.length) {
|
|
39
|
+
const blocked = blockedDomains.filter((d) => typeof d === 'string' && d.trim().length > 0);
|
|
40
|
+
filtered = filtered.filter(r => {
|
|
41
|
+
try {
|
|
42
|
+
const hostname = new URL(r.url).hostname;
|
|
43
|
+
return !blocked.some(d => hostnameMatchesList(hostname, d));
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return filtered;
|
|
51
|
+
}
|
|
52
|
+
export class WebSearchBuiltinTool extends BuiltinBaseTool {
|
|
53
|
+
name = 'web_search';
|
|
54
|
+
description = '在互联网上搜索(Bing),返回匹配的标题、URL 和摘要片段。用于查资料、找网页。支持域名过滤。默认中文结果;用户可在 user_profile 中设置 language 或 preferred_language 覆盖;也可由集成方设置 ToolContext.extra.web_search_locale。';
|
|
55
|
+
parameters = WEB_SEARCH_PARAMETERS;
|
|
56
|
+
kind = 'web';
|
|
57
|
+
searchCount = 0;
|
|
58
|
+
constructor() {
|
|
59
|
+
super();
|
|
60
|
+
this.tags.push('web', 'search');
|
|
61
|
+
this.keywords.push('搜索', '网上搜', '网页搜索', '搜索引擎', 'search', 'google', '百度', 'bing', '查询', '搜一下');
|
|
62
|
+
}
|
|
63
|
+
async run(args, _context) {
|
|
64
|
+
try {
|
|
65
|
+
this.searchCount++;
|
|
66
|
+
if (this.searchCount > MAX_WEB_SEARCH_COUNT) {
|
|
67
|
+
return `Error: 搜索次数已达上限 (${MAX_WEB_SEARCH_COUNT})。请使用已获取的信息回答。`;
|
|
68
|
+
}
|
|
69
|
+
const limitRaw = typeof args.limit === 'number' && Number.isFinite(args.limit) ? args.limit : 5;
|
|
70
|
+
const limit = Math.max(1, Math.min(20, limitRaw));
|
|
71
|
+
const query = String(args.query ?? '').trim();
|
|
72
|
+
if (!query)
|
|
73
|
+
return 'Error: query is required';
|
|
74
|
+
const market = resolveWebSearchMarketFromContext(_context);
|
|
75
|
+
const url = buildBingSearchUrl(query, market);
|
|
76
|
+
const res = await fetch(url, {
|
|
77
|
+
headers: bingSearchFetchHeaders(market),
|
|
78
|
+
redirect: 'follow',
|
|
79
|
+
signal: AbortSignal.timeout(BING_SEARCH_FETCH_TIMEOUT_MS),
|
|
80
|
+
});
|
|
81
|
+
if (!res.ok)
|
|
82
|
+
return `HTTP ${res.status}: ${res.statusText}`;
|
|
83
|
+
const html = await res.text();
|
|
84
|
+
const rawRows = extractBingResults(html);
|
|
85
|
+
const filtered = filterByDomains(rawRows, args.allowed_domains, args.blocked_domains).slice(0, limit);
|
|
86
|
+
if (filtered.length === 0) {
|
|
87
|
+
if (rawRows.length === 0) {
|
|
88
|
+
return 'No results found.(若页面为人机验证或结构变化,可稍后重试或改用 web_fetch 打开已知 URL)';
|
|
89
|
+
}
|
|
90
|
+
return 'No results found.';
|
|
91
|
+
}
|
|
92
|
+
return (`(${this.searchCount}/${MAX_WEB_SEARCH_COUNT} searches)\n` +
|
|
93
|
+
filtered
|
|
94
|
+
.map((r, i) => `${i + 1}. ${r.title}\n URL: ${r.url}\n ${r.snippet ?? ''}`.trimEnd())
|
|
95
|
+
.join('\n\n'));
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
return `Error: ${errMsg(e)}`;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export function createWebSearchTool() {
|
|
103
|
+
return new WebSearchBuiltinTool().toTool();
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=web-search-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-search-tool.js","sourceRoot":"","sources":["../../src/builtin/web-search-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-tool-utils.d.ts","sourceRoot":"","sources":["../../src/builtin/web-tool-utils.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,0CAA0C,CAAC;AAC3E,eAAO,MAAM,yBAAyB,QAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-tool-utils.js","sourceRoot":"","sources":["../../src/builtin/web-tool-utils.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,MAAM,CAAC,MAAM,mBAAmB,GAAG,uCAAuC,CAAC;AAC3E,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Tool, ToolContext, ToolParametersSchema, ToolResult } from '@zhin.js/core';
|
|
2
|
+
import { BuiltinBaseTool } from './builtin-base-tool.js';
|
|
3
|
+
export declare const WRITE_FILE_PARAMETERS: ToolParametersSchema;
|
|
4
|
+
export declare class WriteFileBuiltinTool extends BuiltinBaseTool {
|
|
5
|
+
readonly name = "write_file";
|
|
6
|
+
readonly description = "\u5411\u6307\u5B9A\u8DEF\u5F84\u5199\u5165\u5185\u5BB9\uFF0C\u521B\u5EFA\u6216\u8986\u76D6\u6587\u4EF6\uFF1B\u82E5\u76EE\u5F55\u4E0D\u5B58\u5728\u4F1A\u81EA\u52A8\u521B\u5EFA\u3002";
|
|
7
|
+
readonly parameters: ToolParametersSchema<Record<string, any>>;
|
|
8
|
+
readonly kind = "file";
|
|
9
|
+
constructor();
|
|
10
|
+
run(args: Record<string, unknown>, _context?: ToolContext): Promise<ToolResult>;
|
|
11
|
+
}
|
|
12
|
+
export declare function createWriteFileTool(): Tool;
|
|
13
|
+
//# sourceMappingURL=write-file-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-file-tool.d.ts","sourceRoot":"","sources":["../../src/builtin/write-file-tool.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGzF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,eAAO,MAAM,qBAAqB,EAAE,oBAOnC,CAAC;AAEF,qBAAa,oBAAqB,SAAQ,eAAe;IACvD,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,WAAW,0LACe;IACnC,QAAQ,CAAC,UAAU,4CAAyB;IAC5C,QAAQ,CAAC,IAAI,UAAU;;IAiBjB,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAmBtF;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* write_file — 内置文件写入
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'node:fs/promises';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
import { assertFileAccess } from '../security/file-policy.js';
|
|
7
|
+
import { expandHome, nodeErrToFileMessage } from '../discovery/utils.js';
|
|
8
|
+
import { BuiltinBaseTool } from './builtin-base-tool.js';
|
|
9
|
+
export const WRITE_FILE_PARAMETERS = {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
file_path: { type: 'string', description: '要写入的文件路径' },
|
|
13
|
+
content: { type: 'string', description: '要写入的完整内容' },
|
|
14
|
+
},
|
|
15
|
+
required: ['file_path', 'content'],
|
|
16
|
+
};
|
|
17
|
+
export class WriteFileBuiltinTool extends BuiltinBaseTool {
|
|
18
|
+
name = 'write_file';
|
|
19
|
+
description = '向指定路径写入内容,创建或覆盖文件;若目录不存在会自动创建。';
|
|
20
|
+
parameters = WRITE_FILE_PARAMETERS;
|
|
21
|
+
kind = 'file';
|
|
22
|
+
constructor() {
|
|
23
|
+
super();
|
|
24
|
+
this.tags.push('file', 'write');
|
|
25
|
+
this.keywords.push('写文件', '写入文件', '创建文件', '保存文件', 'write file', 'write', '保存', '创建');
|
|
26
|
+
}
|
|
27
|
+
async run(args, _context) {
|
|
28
|
+
const filePathArg = args.file_path;
|
|
29
|
+
const contentArg = args.content;
|
|
30
|
+
if (typeof filePathArg !== 'string' || !filePathArg.trim()) {
|
|
31
|
+
return 'Error: file_path is required';
|
|
32
|
+
}
|
|
33
|
+
if (typeof contentArg !== 'string') {
|
|
34
|
+
return 'Error: content is required';
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const fp = expandHome(filePathArg);
|
|
38
|
+
assertFileAccess(fp);
|
|
39
|
+
await fs.mkdir(path.dirname(fp), { recursive: true });
|
|
40
|
+
await fs.writeFile(fp, contentArg, 'utf-8');
|
|
41
|
+
return `✅ Wrote ${Buffer.byteLength(contentArg)} bytes to ${fp}`;
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
return nodeErrToFileMessage(e, String(filePathArg), 'write');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function createWriteFileTool() {
|
|
49
|
+
return new WriteFileBuiltinTool().toTool();
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=write-file-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-file-tool.js","sourceRoot":"","sources":["../../src/builtin/write-file-tool.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,CAAC,MAAM,qBAAqB,GAAyB;IACzD,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE;QACtD,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE;KACrD;IACD,QAAQ,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC;CACnC,CAAC;AAEF,MAAM,OAAO,oBAAqB,SAAQ,eAAe;IAC9C,IAAI,GAAG,YAAY,CAAC;IACpB,WAAW,GAClB,gCAAgC,CAAC;IAC1B,UAAU,GAAG,qBAAqB,CAAC;IACnC,IAAI,GAAG,MAAM,CAAC;IAEvB;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,KAAK,EACL,MAAM,EACN,MAAM,EACN,MAAM,EACN,YAAY,EACZ,OAAO,EACP,IAAI,EACJ,IAAI,CACL,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAA6B,EAAE,QAAsB;QAC7D,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;QACnC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC;QAChC,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3D,OAAO,8BAA8B,CAAC;QACxC,CAAC;QACD,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;YACnC,OAAO,4BAA4B,CAAC;QACtC,CAAC;QACD,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;YACnC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YACrB,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACtD,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;YAC5C,OAAO,WAAW,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,aAAa,EAAE,EAAE,CAAC;QACnE,CAAC;QAAC,OAAO,CAAU,EAAE,CAAC;YACpB,OAAO,oBAAoB,CAAC,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;CACF;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,oBAAoB,EAAE,CAAC,MAAM,EAAE,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Tool, ToolContext, ToolParametersSchema, ToolResult } from '@zhin.js/core';
|
|
2
|
+
import { BuiltinBaseTool } from './builtin-base-tool.js';
|
|
3
|
+
export declare const WRITE_MEMORY_PARAMETERS: ToolParametersSchema;
|
|
4
|
+
export declare class WriteMemoryBuiltinTool extends BuiltinBaseTool {
|
|
5
|
+
private readonly dataDir;
|
|
6
|
+
readonly name = "write_memory";
|
|
7
|
+
readonly description = "\u5199\u5165\u6301\u4E45\u5316\u8BB0\u5FC6\u3002\u5F53\u7528\u6237\u8BF4\"\u8BB0\u4F4F\u2026\"\u3001\"\u8BB0\u5F55\u2026\"\u65F6\u4F7F\u7528\u6B64\u5DE5\u5177";
|
|
8
|
+
readonly parameters: ToolParametersSchema<Record<string, any>>;
|
|
9
|
+
readonly kind = "memory";
|
|
10
|
+
constructor(dataDir: string);
|
|
11
|
+
run(args: Record<string, unknown>, _context?: ToolContext): Promise<ToolResult>;
|
|
12
|
+
}
|
|
13
|
+
export declare function createWriteMemoryTool(dataDir: string): Tool;
|
|
14
|
+
//# sourceMappingURL=write-memory-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-memory-tool.d.ts","sourceRoot":"","sources":["../../src/builtin/write-memory-tool.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEzF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,eAAO,MAAM,uBAAuB,EAAE,oBAYrC,CAAC;AAEF,qBAAa,sBAAuB,SAAQ,eAAe;IAM7C,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC,QAAQ,CAAC,IAAI,kBAAkB;IAC/B,QAAQ,CAAC,WAAW,oKAAmC;IACvD,QAAQ,CAAC,UAAU,4CAA2B;IAC9C,QAAQ,CAAC,IAAI,YAAY;gBAEI,OAAO,EAAE,MAAM;IAMtC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAYtF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3D"}
|