clover-hackathon 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.
Files changed (52) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +82 -0
  3. package/dist/cli/commands.d.ts +18 -0
  4. package/dist/cli/commands.js +474 -0
  5. package/dist/cli/commands.js.map +1 -0
  6. package/dist/cli/index.d.ts +1 -0
  7. package/dist/cli/index.js +205 -0
  8. package/dist/cli/index.js.map +1 -0
  9. package/dist/core/agent.d.ts +27 -0
  10. package/dist/core/agent.js +108 -0
  11. package/dist/core/agent.js.map +1 -0
  12. package/dist/core/permissions.d.ts +9 -0
  13. package/dist/core/permissions.js +45 -0
  14. package/dist/core/permissions.js.map +1 -0
  15. package/dist/core/session.d.ts +7 -0
  16. package/dist/core/session.js +42 -0
  17. package/dist/core/session.js.map +1 -0
  18. package/dist/core/tools.d.ts +7 -0
  19. package/dist/core/tools.js +216 -0
  20. package/dist/core/tools.js.map +1 -0
  21. package/dist/hackathon/workflows.d.ts +13 -0
  22. package/dist/hackathon/workflows.js +132 -0
  23. package/dist/hackathon/workflows.js.map +1 -0
  24. package/dist/index.d.ts +2 -0
  25. package/dist/index.js +8 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/models/provider.d.ts +26 -0
  28. package/dist/models/provider.js +347 -0
  29. package/dist/models/provider.js.map +1 -0
  30. package/dist/types.d.ts +131 -0
  31. package/dist/types.js +3 -0
  32. package/dist/types.js.map +1 -0
  33. package/dist/utils/config.d.ts +15 -0
  34. package/dist/utils/config.js +93 -0
  35. package/dist/utils/config.js.map +1 -0
  36. package/dist/utils/cost.d.ts +16 -0
  37. package/dist/utils/cost.js +48 -0
  38. package/dist/utils/cost.js.map +1 -0
  39. package/dist/utils/input.d.ts +4 -0
  40. package/dist/utils/input.js +37 -0
  41. package/dist/utils/input.js.map +1 -0
  42. package/dist/utils/logger.d.ts +6 -0
  43. package/dist/utils/logger.js +33 -0
  44. package/dist/utils/logger.js.map +1 -0
  45. package/dist/utils/pet.d.ts +9 -0
  46. package/dist/utils/pet.js +74 -0
  47. package/dist/utils/pet.js.map +1 -0
  48. package/package.json +53 -0
  49. package/src/templates/pitch.md +30 -0
  50. package/src/templates/readme.md +36 -0
  51. package/src/templates/submission.md +40 -0
  52. package/src/templates/timeline.md +28 -0
@@ -0,0 +1,205 @@
1
+ // CLI 入口:注册所有 clover 子命令
2
+ import { Command } from "commander";
3
+ import { cmdInit, cmdNew, cmdArchiveList, cmdConfig, cmdModels, cmdSessions, cmdStatus, cmdCheck, cmdTemplate, cmdAnalyze, cmdIdeate, cmdEvaluate, cmdPlan, cmdPitch, cmdReview, cmdStart } from "./commands.js";
4
+ export async function runCli() {
5
+ const program = new Command();
6
+ program
7
+ .name("clover")
8
+ .description("🍀 Clover — 专为黑客松比赛设计的命令行 AI Agent")
9
+ .version("0.1.0");
10
+ program
11
+ .command("init")
12
+ .description("在当前目录初始化比赛项目")
13
+ .action(async () => {
14
+ try {
15
+ await cmdInit();
16
+ }
17
+ catch (err) {
18
+ console.error("✖ " + (err instanceof Error ? err.message : err));
19
+ process.exitCode = 1;
20
+ }
21
+ });
22
+ program
23
+ .command("new <name>")
24
+ .description("创建新比赛档案目录")
25
+ .action(async (name) => {
26
+ try {
27
+ await cmdNew(name);
28
+ }
29
+ catch (err) {
30
+ console.error("✖ " + (err instanceof Error ? err.message : err));
31
+ process.exitCode = 1;
32
+ }
33
+ });
34
+ program
35
+ .command("archive")
36
+ .description("历史比赛档案")
37
+ .argument("[list]", "子命令,目前仅支持 list")
38
+ .action(async () => {
39
+ try {
40
+ await cmdArchiveList();
41
+ }
42
+ catch (err) {
43
+ console.error("✖ " + (err instanceof Error ? err.message : err));
44
+ process.exitCode = 1;
45
+ }
46
+ });
47
+ program
48
+ .command("config")
49
+ .description("配置向导:模型、API Key、语言、预算、竞速模式")
50
+ .action(async () => {
51
+ try {
52
+ await cmdConfig();
53
+ }
54
+ catch (err) {
55
+ console.error("✖ " + (err instanceof Error ? err.message : err));
56
+ process.exitCode = 1;
57
+ }
58
+ });
59
+ program
60
+ .command("models")
61
+ .description("查看模型配置")
62
+ .action(() => {
63
+ try {
64
+ cmdModels();
65
+ }
66
+ catch (err) {
67
+ console.error("✖ " + (err instanceof Error ? err.message : err));
68
+ process.exitCode = 1;
69
+ }
70
+ });
71
+ program
72
+ .command("status")
73
+ .description("比赛状态:倒计时/预算/模式")
74
+ .action(() => {
75
+ try {
76
+ cmdStatus();
77
+ }
78
+ catch (err) {
79
+ console.error("✖ " + (err instanceof Error ? err.message : err));
80
+ process.exitCode = 1;
81
+ }
82
+ });
83
+ program
84
+ .command("analyze [source]")
85
+ .description("解析赛题(文件路径 / URL / 直接粘贴文本)")
86
+ .action(async (source) => {
87
+ try {
88
+ await cmdAnalyze(source);
89
+ }
90
+ catch (err) {
91
+ console.error("✖ " + (err instanceof Error ? err.message : err));
92
+ process.exitCode = 1;
93
+ }
94
+ });
95
+ program
96
+ .command("ideate")
97
+ .description("基于赛题生成项目点子")
98
+ .action(async () => {
99
+ try {
100
+ await cmdIdeate();
101
+ }
102
+ catch (err) {
103
+ console.error("✖ " + (err instanceof Error ? err.message : err));
104
+ process.exitCode = 1;
105
+ }
106
+ });
107
+ program
108
+ .command("evaluate [idea]")
109
+ .description("点子评估:合理性 + 市场分析(蓝海/红海)")
110
+ .action(async (idea) => {
111
+ try {
112
+ await cmdEvaluate(idea);
113
+ }
114
+ catch (err) {
115
+ console.error("✖ " + (err instanceof Error ? err.message : err));
116
+ process.exitCode = 1;
117
+ }
118
+ });
119
+ program
120
+ .command("plan")
121
+ .description("MVP 规划")
122
+ .action(async () => {
123
+ try {
124
+ await cmdPlan();
125
+ }
126
+ catch (err) {
127
+ console.error("✖ " + (err instanceof Error ? err.message : err));
128
+ process.exitCode = 1;
129
+ }
130
+ });
131
+ program
132
+ .command("pitch")
133
+ .description("生成 Pitch 演讲稿")
134
+ .action(async () => {
135
+ try {
136
+ await cmdPitch();
137
+ }
138
+ catch (err) {
139
+ console.error("✖ " + (err instanceof Error ? err.message : err));
140
+ process.exitCode = 1;
141
+ }
142
+ });
143
+ program
144
+ .command("template <type>")
145
+ .description("生成模板文档:readme / pitch / submission / timeline")
146
+ .action((type) => {
147
+ try {
148
+ cmdTemplate(type);
149
+ }
150
+ catch (err) {
151
+ console.error("✖ " + (err instanceof Error ? err.message : err));
152
+ process.exitCode = 1;
153
+ }
154
+ });
155
+ program
156
+ .command("check")
157
+ .description("提交前检查清单")
158
+ .action(async () => {
159
+ try {
160
+ await cmdCheck();
161
+ }
162
+ catch (err) {
163
+ console.error("✖ " + (err instanceof Error ? err.message : err));
164
+ process.exitCode = 1;
165
+ }
166
+ });
167
+ program
168
+ .command("review")
169
+ .description("赛后复盘报告")
170
+ .action(async () => {
171
+ try {
172
+ await cmdReview();
173
+ }
174
+ catch (err) {
175
+ console.error("✖ " + (err instanceof Error ? err.message : err));
176
+ process.exitCode = 1;
177
+ }
178
+ });
179
+ program
180
+ .command("sessions [id]")
181
+ .description("查看历史会话(无参=列表,带ID=详情)")
182
+ .action((id) => {
183
+ try {
184
+ cmdSessions(id);
185
+ }
186
+ catch (err) {
187
+ console.error("✖ " + (err instanceof Error ? err.message : err));
188
+ process.exitCode = 1;
189
+ }
190
+ });
191
+ program
192
+ .command("start")
193
+ .description("进入 Clover 对话模式")
194
+ .action(async () => {
195
+ try {
196
+ await cmdStart();
197
+ }
198
+ catch (err) {
199
+ console.error("✖ " + (err instanceof Error ? err.message : err));
200
+ process.exitCode = 1;
201
+ }
202
+ });
203
+ program.parseAsync(process.argv);
204
+ }
205
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { ModelProvider } from "../models/provider.js";
2
+ import type { ImageBlock, SessionRecord } from "../types.js";
3
+ /** 命令审批器:执行 run_command 前需要用户确认 */
4
+ export interface CommandApprover {
5
+ approve(command: string): Promise<boolean>;
6
+ }
7
+ export interface AgentOptions {
8
+ provider: ModelProvider;
9
+ session: SessionRecord;
10
+ budgetUsd: number;
11
+ permissions?: CommandApprover;
12
+ }
13
+ export declare class Agent {
14
+ private readonly options;
15
+ private readonly messages;
16
+ constructor(options: AgentOptions);
17
+ /** 发送一轮对话:模型可多次调用工具,直至给出最终回答 */
18
+ turn(userInput: string, images?: ImageBlock[]): Promise<string>;
19
+ private account;
20
+ private executeTool;
21
+ /** 总用量统计 */
22
+ usage(): {
23
+ costUsd: number;
24
+ inputTokens: number;
25
+ outputTokens: number;
26
+ };
27
+ }
@@ -0,0 +1,108 @@
1
+ // Agent 主循环:M2 已接入工具调用(读写文件、执行命令)与权限确认
2
+ import { appendMessage, saveSession } from "./session.js";
3
+ import { checkBudget, formatUsd } from "../utils/cost.js";
4
+ import { note, warn } from "../utils/logger.js";
5
+ import { findTool, TOOLS } from "./tools.js";
6
+ const SYSTEM_PROMPT = [
7
+ "你是 Clover,一个专为黑客松比赛设计的 AI 搭档。",
8
+ "你会帮助用户:解析赛题、生成与评估点子、规划 MVP、管理时间、检查提交材料、准备 Pitch。",
9
+ "你可以在项目目录里读写文件、执行终端命令,真正动手完成开发任务。",
10
+ "默认使用中文交流(除非用户要求其他语言)。回答要简洁、可执行、紧扣黑客松时间有限的特点。",
11
+ ].join("\n");
12
+ const MAX_TOOL_ROUNDS = 10;
13
+ export class Agent {
14
+ options;
15
+ messages;
16
+ constructor(options) {
17
+ this.options = options;
18
+ this.messages = [
19
+ { role: "system", content: SYSTEM_PROMPT },
20
+ ...options.session.messages,
21
+ ];
22
+ }
23
+ /** 发送一轮对话:模型可多次调用工具,直至给出最终回答 */
24
+ async turn(userInput, images) {
25
+ const { provider, session, budgetUsd, permissions } = this.options;
26
+ const userMessage = { role: "user", content: userInput };
27
+ if (images && images.length > 0)
28
+ userMessage.images = images;
29
+ appendMessage(session, userMessage);
30
+ this.messages.push(userMessage);
31
+ let finalText = "";
32
+ let turnCost = 0;
33
+ for (let round = 0; round < MAX_TOOL_ROUNDS; round++) {
34
+ const result = await provider.chat(this.messages, { tools: TOOLS });
35
+ turnCost += result.estimatedCostUsd;
36
+ this.account(session, result);
37
+ const assistantMessage = { role: "assistant", content: result.content };
38
+ if (result.toolCalls && result.toolCalls.length > 0) {
39
+ assistantMessage.toolCalls = result.toolCalls;
40
+ }
41
+ appendMessage(session, assistantMessage);
42
+ this.messages.push(assistantMessage);
43
+ if (!assistantMessage.toolCalls || assistantMessage.toolCalls.length === 0) {
44
+ finalText = result.content;
45
+ break;
46
+ }
47
+ for (const call of assistantMessage.toolCalls) {
48
+ const toolResult = await this.executeTool(call, permissions);
49
+ note("🔧 " + call.name + " → " + summarize(toolResult));
50
+ const toolMessage = {
51
+ role: "tool",
52
+ toolCallId: call.id,
53
+ name: call.name,
54
+ content: toolResult.ok ? toolResult.output : "ERROR: " + toolResult.output,
55
+ };
56
+ appendMessage(session, toolMessage);
57
+ this.messages.push(toolMessage);
58
+ }
59
+ }
60
+ if (!finalText) {
61
+ warn("工具调用超过 " + MAX_TOOL_ROUNDS + " 轮,已停止");
62
+ finalText = "(工具调用过多已停止,请重新描述你的目标)";
63
+ }
64
+ saveSession(session);
65
+ const status = checkBudget(session.totalCostUsd, budgetUsd);
66
+ note("本次: " + formatUsd(turnCost) + " · 累计: " + formatUsd(session.totalCostUsd));
67
+ if (status.nearLimit) {
68
+ warn("已接近预算上限(" + formatUsd(budgetUsd) + "),请留意成本");
69
+ }
70
+ return finalText;
71
+ }
72
+ account(session, result) {
73
+ session.totalInputTokens += result.usage.inputTokens;
74
+ session.totalOutputTokens += result.usage.outputTokens;
75
+ session.totalCostUsd += result.estimatedCostUsd;
76
+ }
77
+ async executeTool(call, permissions) {
78
+ const tool = findTool(call.name);
79
+ if (!tool)
80
+ return { ok: false, output: "未知工具: " + call.name };
81
+ // 各家参数可能是对象/数字等,统一字符串化后传给工具
82
+ const args = {};
83
+ for (const [key, value] of Object.entries(call.args ?? {})) {
84
+ args[key] = value == null ? undefined : typeof value === "string" ? value : JSON.stringify(value);
85
+ }
86
+ if (tool.name === "run_command" && permissions) {
87
+ const approved = await permissions.approve(args.command ?? "");
88
+ if (!approved) {
89
+ return { ok: false, output: "用户拒绝了命令执行" };
90
+ }
91
+ }
92
+ return tool.run(args);
93
+ }
94
+ /** 总用量统计 */
95
+ usage() {
96
+ const u = {
97
+ inputTokens: this.options.session.totalInputTokens,
98
+ outputTokens: this.options.session.totalOutputTokens,
99
+ };
100
+ return { ...u, costUsd: this.options.session.totalCostUsd };
101
+ }
102
+ }
103
+ function summarize(toolResult) {
104
+ const first = toolResult.output.split("\n")[0]?.trim() || (toolResult.ok ? "完成" : "失败");
105
+ const short = first.length > 60 ? first.slice(0, 60) + "…" : first;
106
+ return toolResult.ok ? short : "失败: " + short;
107
+ }
108
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/core/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { CloverConfig } from "../types.js";
2
+ export declare class PermissionManager {
3
+ private readonly config;
4
+ private allowed;
5
+ constructor(config: CloverConfig);
6
+ /** 检查命令是否可执行:竞速模式 + 已批准前缀 → 自动放行;否则询问用户 */
7
+ approve(command: string): Promise<boolean>;
8
+ listAllowed(): string[];
9
+ }
@@ -0,0 +1,45 @@
1
+ // 命令权限:默认需确认;竞速模式自动放行;已批准前缀不再询问
2
+ // 批准规则持久化在项目 .clover/allowed-commands.json
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import { askYesNo } from "../utils/input.js";
6
+ const ALLOWED_FILE = path.join(".clover", "allowed-commands.json");
7
+ function loadAllowed() {
8
+ if (!fs.existsSync(ALLOWED_FILE))
9
+ return [];
10
+ try {
11
+ return JSON.parse(fs.readFileSync(ALLOWED_FILE, "utf8"));
12
+ }
13
+ catch {
14
+ return [];
15
+ }
16
+ }
17
+ function saveAllowed(prefixes) {
18
+ fs.mkdirSync(path.dirname(ALLOWED_FILE), { recursive: true });
19
+ fs.writeFileSync(ALLOWED_FILE, JSON.stringify(prefixes, null, 2), "utf8");
20
+ }
21
+ export class PermissionManager {
22
+ config;
23
+ allowed = loadAllowed();
24
+ constructor(config) {
25
+ this.config = config;
26
+ }
27
+ /** 检查命令是否可执行:竞速模式 + 已批准前缀 → 自动放行;否则询问用户 */
28
+ async approve(command) {
29
+ if (this.config.speedMode)
30
+ return true;
31
+ const head = command.trim().split(/\s+/)[0] ?? "";
32
+ if (this.allowed.includes(head))
33
+ return true;
34
+ const ok = await askYesNo("允许执行命令? " + command.slice(0, 120));
35
+ if (ok && head) {
36
+ this.allowed.push(head);
37
+ saveAllowed(this.allowed);
38
+ }
39
+ return ok;
40
+ }
41
+ listAllowed() {
42
+ return [...this.allowed];
43
+ }
44
+ }
45
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/core/permissions.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,2CAA2C;AAE3C,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC;AAEnE,SAAS,WAAW;IAClB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,EAAE,CAAC;IAC5C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAa,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,QAAkB;IACrC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,OAAO,iBAAiB;IAGC;IAFrB,OAAO,GAAG,WAAW,EAAE,CAAC;IAEhC,YAA6B,MAAoB;QAApB,WAAM,GAAN,MAAM,CAAc;IAAG,CAAC;IAErD,2CAA2C;IAC3C,KAAK,CAAC,OAAO,CAAC,OAAe;QAC3B,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QACvC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC7C,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC9D,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxB,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,WAAW;QACT,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import type { ChatMessage, SessionRecord } from "../types.js";
2
+ export declare function createSession(): SessionRecord;
3
+ export declare function saveSession(session: SessionRecord): void;
4
+ export declare function loadSession(id: string): SessionRecord | null;
5
+ export declare function listSessions(): SessionRecord[];
6
+ export declare function latestSession(): SessionRecord | null;
7
+ export declare function appendMessage(session: SessionRecord, message: ChatMessage): void;
@@ -0,0 +1,42 @@
1
+ // 会话持久化:.clover/sessions/<id>.json,支持恢复
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import crypto from "node:crypto";
5
+ import { readJsonFile, writeJsonFile } from "../utils/config.js";
6
+ const SESSIONS_DIR = path.join(".clover", "sessions");
7
+ export function createSession() {
8
+ const now = new Date().toISOString();
9
+ return {
10
+ id: crypto.randomUUID(),
11
+ startedAt: now,
12
+ updatedAt: now,
13
+ messages: [],
14
+ totalInputTokens: 0,
15
+ totalOutputTokens: 0,
16
+ totalCostUsd: 0,
17
+ };
18
+ }
19
+ export function saveSession(session) {
20
+ writeJsonFile(path.join(SESSIONS_DIR, session.id + ".json"), session);
21
+ }
22
+ export function loadSession(id) {
23
+ return readJsonFile(path.join(SESSIONS_DIR, id + ".json"));
24
+ }
25
+ export function listSessions() {
26
+ if (!fs.existsSync(SESSIONS_DIR))
27
+ return [];
28
+ return fs
29
+ .readdirSync(SESSIONS_DIR)
30
+ .filter((f) => f.endsWith(".json"))
31
+ .map((f) => readJsonFile(path.join(SESSIONS_DIR, f)))
32
+ .filter((s) => s !== null)
33
+ .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
34
+ }
35
+ export function latestSession() {
36
+ return listSessions()[0] ?? null;
37
+ }
38
+ export function appendMessage(session, message) {
39
+ session.messages.push(message);
40
+ session.updatedAt = new Date().toISOString();
41
+ }
42
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAExC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEjE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AAEtD,MAAM,UAAU,aAAa;IAC3B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,GAAG;QACd,QAAQ,EAAE,EAAE;QACZ,gBAAgB,EAAE,CAAC;QACnB,iBAAiB,EAAE,CAAC;QACpB,YAAY,EAAE,CAAC;KAChB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAsB;IAChD,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAAU;IACpC,OAAO,YAAY,CAAgB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,EAAE,CAAC;IAC5C,OAAO,EAAE;SACN,WAAW,CAAC,YAAY,CAAC;SACzB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAgB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;SACnE,MAAM,CAAC,CAAC,CAAC,EAAsB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;SAC7C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAsB,EAAE,OAAoB;IACxE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,OAAO,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ToolDefinition } from "../types.js";
2
+ export declare const TOOLS: ToolDefinition[];
3
+ export declare function findTool(name: string): ToolDefinition | undefined;
4
+ /** 把工具的 parameters 转成 JSON Schema,供各家 API 使用 */
5
+ export declare function toJsonSchema(tool: ToolDefinition): Record<string, unknown>;
6
+ /** 联网搜索,返回最多 maxResults 条:标题 / 链接 / 摘要 */
7
+ export declare function searchWeb(query: string, maxResults?: number): Promise<string>;