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.
- package/LICENSE +22 -0
- package/README.md +82 -0
- package/dist/cli/commands.d.ts +18 -0
- package/dist/cli/commands.js +474 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +205 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/agent.d.ts +27 -0
- package/dist/core/agent.js +108 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/permissions.d.ts +9 -0
- package/dist/core/permissions.js +45 -0
- package/dist/core/permissions.js.map +1 -0
- package/dist/core/session.d.ts +7 -0
- package/dist/core/session.js +42 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/tools.d.ts +7 -0
- package/dist/core/tools.js +216 -0
- package/dist/core/tools.js.map +1 -0
- package/dist/hackathon/workflows.d.ts +13 -0
- package/dist/hackathon/workflows.js +132 -0
- package/dist/hackathon/workflows.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/models/provider.d.ts +26 -0
- package/dist/models/provider.js +347 -0
- package/dist/models/provider.js.map +1 -0
- package/dist/types.d.ts +131 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/config.d.ts +15 -0
- package/dist/utils/config.js +93 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/cost.d.ts +16 -0
- package/dist/utils/cost.js +48 -0
- package/dist/utils/cost.js.map +1 -0
- package/dist/utils/input.d.ts +4 -0
- package/dist/utils/input.js +37 -0
- package/dist/utils/input.js.map +1 -0
- package/dist/utils/logger.d.ts +6 -0
- package/dist/utils/logger.js +33 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/pet.d.ts +9 -0
- package/dist/utils/pet.js +74 -0
- package/dist/utils/pet.js.map +1 -0
- package/package.json +53 -0
- package/src/templates/pitch.md +30 -0
- package/src/templates/readme.md +36 -0
- package/src/templates/submission.md +40 -0
- package/src/templates/timeline.md +28 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
// 模型 Provider 抽象与实现:OpenAI / Anthropic / Gemini / Ollama / 自定义兼容接口
|
|
2
|
+
// M2:统一 chat(messages, options) 协议,把各家 function calling 转换为内部 ToolCallRequest。
|
|
3
|
+
import { estimateCostUsd } from "../utils/cost.js";
|
|
4
|
+
import { toJsonSchema } from "../core/tools.js";
|
|
5
|
+
export class CloverError extends Error {
|
|
6
|
+
}
|
|
7
|
+
function requireKey(config) {
|
|
8
|
+
if (!config.apiKey) {
|
|
9
|
+
throw new CloverError(config.id + " 未配置 API Key:请运行 clover config 配置,或设置 CLOVER_" + config.id.toUpperCase() + "_KEY 环境变量");
|
|
10
|
+
}
|
|
11
|
+
return config.apiKey;
|
|
12
|
+
}
|
|
13
|
+
function toUsage(inputTokens, outputTokens) {
|
|
14
|
+
return { inputTokens, outputTokens };
|
|
15
|
+
}
|
|
16
|
+
function finish(model, content, usage, toolCalls) {
|
|
17
|
+
const result = {
|
|
18
|
+
content,
|
|
19
|
+
usage,
|
|
20
|
+
estimatedCostUsd: estimateCostUsd(usage, model),
|
|
21
|
+
model,
|
|
22
|
+
};
|
|
23
|
+
if (toolCalls && toolCalls.length > 0)
|
|
24
|
+
result.toolCalls = toolCalls;
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
function stripSystem(messages) {
|
|
28
|
+
const system = messages.find((m) => m.role === "system")?.content;
|
|
29
|
+
return { system, rest: messages.filter((m) => m.role !== "system") };
|
|
30
|
+
}
|
|
31
|
+
/** 解析 OpenAI 风格 tool_calls(arguments 可能是 JSON 字符串或对象) */
|
|
32
|
+
function parseOpenAIToolCalls(raw) {
|
|
33
|
+
return (raw ?? []).map((tc, index) => {
|
|
34
|
+
let args = {};
|
|
35
|
+
const rawArgs = tc.function?.arguments;
|
|
36
|
+
if (typeof rawArgs === "string") {
|
|
37
|
+
try {
|
|
38
|
+
const parsed = JSON.parse(rawArgs);
|
|
39
|
+
if (parsed && typeof parsed === "object")
|
|
40
|
+
args = parsed;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
args = {};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else if (rawArgs && typeof rawArgs === "object") {
|
|
47
|
+
args = rawArgs;
|
|
48
|
+
}
|
|
49
|
+
return { id: tc.id ?? "call_" + index, name: tc.function?.name ?? "", args };
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/** OpenAI 风格消息转换(OpenAI / custom / Ollama 共用;arguments 按各家要求决定字符串化与否) */
|
|
53
|
+
export function toOpenAIMessages(messages, argsAsString) {
|
|
54
|
+
return messages.map((m) => {
|
|
55
|
+
if (m.role === "assistant") {
|
|
56
|
+
const msg = { role: "assistant", content: m.content };
|
|
57
|
+
if (m.toolCalls && m.toolCalls.length > 0) {
|
|
58
|
+
msg.tool_calls = m.toolCalls.map((tc) => ({
|
|
59
|
+
id: tc.id,
|
|
60
|
+
type: "function",
|
|
61
|
+
function: { name: tc.name, arguments: argsAsString ? JSON.stringify(tc.args) : tc.args },
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
return msg;
|
|
65
|
+
}
|
|
66
|
+
if (m.role === "tool") {
|
|
67
|
+
return { role: "tool", tool_call_id: m.toolCallId, content: m.content };
|
|
68
|
+
}
|
|
69
|
+
if (m.role === "user" && m.images && m.images.length > 0) {
|
|
70
|
+
const parts = [];
|
|
71
|
+
if (m.content)
|
|
72
|
+
parts.push({ type: "text", text: m.content });
|
|
73
|
+
for (const img of m.images) {
|
|
74
|
+
parts.push({ type: "image_url", image_url: { url: "data:" + img.mediaType + ";base64," + img.dataBase64 } });
|
|
75
|
+
}
|
|
76
|
+
return { role: "user", content: parts };
|
|
77
|
+
}
|
|
78
|
+
return { role: m.role, content: m.content };
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/** Anthropic 消息转换:tool_use/tool_result 与图片块,合并相邻 user 消息 */
|
|
82
|
+
export function toAnthropicMessages(messages) {
|
|
83
|
+
const mapped = [];
|
|
84
|
+
for (const m of messages) {
|
|
85
|
+
if (m.role === "assistant") {
|
|
86
|
+
const content = [];
|
|
87
|
+
if (m.content)
|
|
88
|
+
content.push({ type: "text", text: m.content });
|
|
89
|
+
for (const tc of m.toolCalls ?? []) {
|
|
90
|
+
content.push({ type: "tool_use", id: tc.id, name: tc.name, input: tc.args });
|
|
91
|
+
}
|
|
92
|
+
mapped.push({ role: "assistant", content });
|
|
93
|
+
}
|
|
94
|
+
else if (m.role === "tool") {
|
|
95
|
+
mapped.push({
|
|
96
|
+
role: "user",
|
|
97
|
+
content: [{ type: "tool_result", tool_use_id: m.toolCallId ?? "", content: m.content }],
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
const content = [];
|
|
102
|
+
if (m.content)
|
|
103
|
+
content.push({ type: "text", text: m.content });
|
|
104
|
+
for (const img of m.images ?? []) {
|
|
105
|
+
content.push({ type: "image", source: { type: "base64", media_type: img.mediaType, data: img.dataBase64 } });
|
|
106
|
+
}
|
|
107
|
+
mapped.push({ role: "user", content });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const merged = [];
|
|
111
|
+
for (const m of mapped) {
|
|
112
|
+
const prev = merged[merged.length - 1];
|
|
113
|
+
if (prev && prev.role === m.role)
|
|
114
|
+
prev.content.push(...m.content);
|
|
115
|
+
else
|
|
116
|
+
merged.push({ role: m.role, content: [...m.content] });
|
|
117
|
+
}
|
|
118
|
+
return merged;
|
|
119
|
+
}
|
|
120
|
+
function openAITools(tools) {
|
|
121
|
+
return tools.map((t) => ({
|
|
122
|
+
type: "function",
|
|
123
|
+
function: { name: t.name, description: t.description, parameters: toJsonSchema(t) },
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
// ---------- OpenAI 与自定义兼容接口 ----------
|
|
127
|
+
class OpenAICompatibleProvider {
|
|
128
|
+
config;
|
|
129
|
+
constructor(config) {
|
|
130
|
+
this.config = config;
|
|
131
|
+
}
|
|
132
|
+
async chat(messages, options) {
|
|
133
|
+
const apiKey = requireKey(this.config);
|
|
134
|
+
const baseUrl = (this.config.baseUrl ?? "https://api.openai.com/v1").replace(/\/$/, "");
|
|
135
|
+
const body = {
|
|
136
|
+
model: this.config.model,
|
|
137
|
+
messages: toOpenAIMessages(messages, true),
|
|
138
|
+
};
|
|
139
|
+
if (options?.tools && options.tools.length > 0) {
|
|
140
|
+
body.tools = openAITools(options.tools);
|
|
141
|
+
body.tool_choice = "auto";
|
|
142
|
+
}
|
|
143
|
+
const res = await fetch(baseUrl + "/chat/completions", {
|
|
144
|
+
method: "POST",
|
|
145
|
+
headers: { "Content-Type": "application/json", Authorization: "Bearer " + apiKey },
|
|
146
|
+
body: JSON.stringify(body),
|
|
147
|
+
});
|
|
148
|
+
if (!res.ok)
|
|
149
|
+
throw new CloverError(this.config.id + " 请求失败:" + res.status + " " + (await res.text()));
|
|
150
|
+
const data = (await res.json());
|
|
151
|
+
const message = data.choices[0]?.message;
|
|
152
|
+
return finish(this.config.model, message?.content ?? "", toUsage(data.usage.prompt_tokens, data.usage.completion_tokens), parseOpenAIToolCalls(message?.tool_calls ?? []));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/** Gemini 消息转换:functionCall/functionResponse 与内联图片,合并相邻同角色消息 */
|
|
156
|
+
export function toGeminiContents(messages) {
|
|
157
|
+
const mapped = [];
|
|
158
|
+
for (const m of messages) {
|
|
159
|
+
if (m.role === "assistant") {
|
|
160
|
+
const parts = [];
|
|
161
|
+
if (m.content)
|
|
162
|
+
parts.push({ text: m.content });
|
|
163
|
+
for (const tc of m.toolCalls ?? []) {
|
|
164
|
+
parts.push({ functionCall: { name: tc.name, args: tc.args } });
|
|
165
|
+
}
|
|
166
|
+
mapped.push({ role: "model", parts });
|
|
167
|
+
}
|
|
168
|
+
else if (m.role === "tool") {
|
|
169
|
+
mapped.push({
|
|
170
|
+
role: "user",
|
|
171
|
+
parts: [{ functionResponse: { name: m.name, response: { result: m.content } } }],
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
const parts = [];
|
|
176
|
+
if (m.content)
|
|
177
|
+
parts.push({ text: m.content });
|
|
178
|
+
for (const img of m.images ?? []) {
|
|
179
|
+
parts.push({ inline_data: { mime_type: img.mediaType, data: img.dataBase64 } });
|
|
180
|
+
}
|
|
181
|
+
mapped.push({ role: "user", parts });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const merged = [];
|
|
185
|
+
for (const m of mapped) {
|
|
186
|
+
const prev = merged[merged.length - 1];
|
|
187
|
+
if (prev && prev.role === m.role)
|
|
188
|
+
prev.parts.push(...m.parts);
|
|
189
|
+
else
|
|
190
|
+
merged.push({ role: m.role, parts: [...m.parts] });
|
|
191
|
+
}
|
|
192
|
+
return merged;
|
|
193
|
+
}
|
|
194
|
+
// ---------- Anthropic ----------
|
|
195
|
+
class AnthropicProvider {
|
|
196
|
+
config;
|
|
197
|
+
constructor(config) {
|
|
198
|
+
this.config = config;
|
|
199
|
+
}
|
|
200
|
+
async chat(messages, options) {
|
|
201
|
+
const apiKey = requireKey(this.config);
|
|
202
|
+
const { system, rest } = stripSystem(messages);
|
|
203
|
+
const merged = toAnthropicMessages(rest);
|
|
204
|
+
const body = {
|
|
205
|
+
model: this.config.model,
|
|
206
|
+
max_tokens: 4096,
|
|
207
|
+
system: system ?? undefined,
|
|
208
|
+
messages: merged,
|
|
209
|
+
};
|
|
210
|
+
if (options?.tools && options.tools.length > 0) {
|
|
211
|
+
body.tools = options.tools.map((t) => ({
|
|
212
|
+
name: t.name,
|
|
213
|
+
description: t.description,
|
|
214
|
+
input_schema: toJsonSchema(t),
|
|
215
|
+
}));
|
|
216
|
+
body.tool_choice = { type: "auto" };
|
|
217
|
+
}
|
|
218
|
+
const res = await fetch("https://api.anthropic.com/v1/messages", {
|
|
219
|
+
method: "POST",
|
|
220
|
+
headers: {
|
|
221
|
+
"Content-Type": "application/json",
|
|
222
|
+
"x-api-key": apiKey,
|
|
223
|
+
"anthropic-version": "2023-06-01",
|
|
224
|
+
},
|
|
225
|
+
body: JSON.stringify(body),
|
|
226
|
+
});
|
|
227
|
+
if (!res.ok)
|
|
228
|
+
throw new CloverError("anthropic 请求失败:" + res.status + " " + (await res.text()));
|
|
229
|
+
const data = (await res.json());
|
|
230
|
+
const text = data.content.filter((c) => c.type === "text").map((c) => c.text ?? "").join("");
|
|
231
|
+
const toolCalls = data.content
|
|
232
|
+
.filter((c) => c.type === "tool_use")
|
|
233
|
+
.map((c) => ({ id: c.id ?? "", name: c.name ?? "", args: c.input ?? {} }));
|
|
234
|
+
return finish(this.config.model, text, toUsage(data.usage.input_tokens, data.usage.output_tokens), toolCalls);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// ---------- Gemini ----------
|
|
238
|
+
class GeminiProvider {
|
|
239
|
+
config;
|
|
240
|
+
constructor(config) {
|
|
241
|
+
this.config = config;
|
|
242
|
+
}
|
|
243
|
+
async chat(messages, options) {
|
|
244
|
+
const apiKey = requireKey(this.config);
|
|
245
|
+
const url = "https://generativelanguage.googleapis.com/v1beta/models/" +
|
|
246
|
+
this.config.model +
|
|
247
|
+
":generateContent?key=" +
|
|
248
|
+
encodeURIComponent(apiKey);
|
|
249
|
+
const { system, rest } = stripSystem(messages);
|
|
250
|
+
const merged = toGeminiContents(rest);
|
|
251
|
+
const body = {
|
|
252
|
+
systemInstruction: system ? { parts: [{ text: system }] } : undefined,
|
|
253
|
+
contents: merged,
|
|
254
|
+
};
|
|
255
|
+
if (options?.tools && options.tools.length > 0) {
|
|
256
|
+
body.tools = [
|
|
257
|
+
{
|
|
258
|
+
functionDeclarations: options.tools.map((t) => ({
|
|
259
|
+
name: t.name,
|
|
260
|
+
description: t.description,
|
|
261
|
+
parameters: toJsonSchema(t),
|
|
262
|
+
})),
|
|
263
|
+
},
|
|
264
|
+
];
|
|
265
|
+
}
|
|
266
|
+
const res = await fetch(url, {
|
|
267
|
+
method: "POST",
|
|
268
|
+
headers: { "Content-Type": "application/json" },
|
|
269
|
+
body: JSON.stringify(body),
|
|
270
|
+
});
|
|
271
|
+
if (!res.ok)
|
|
272
|
+
throw new CloverError("gemini 请求失败:" + res.status + " " + (await res.text()));
|
|
273
|
+
const data = (await res.json());
|
|
274
|
+
const parts = data.candidates?.[0]?.content?.parts ?? [];
|
|
275
|
+
const text = parts.map((p) => p.text ?? "").join("");
|
|
276
|
+
const toolCalls = parts
|
|
277
|
+
.filter((p) => p.functionCall)
|
|
278
|
+
.map((p, index) => ({
|
|
279
|
+
id: "fc_" + index,
|
|
280
|
+
name: p.functionCall?.name ?? "",
|
|
281
|
+
args: p.functionCall?.args ?? {},
|
|
282
|
+
}));
|
|
283
|
+
return finish(this.config.model, text, toUsage(data.usageMetadata?.promptTokenCount ?? 0, data.usageMetadata?.candidatesTokenCount ?? 0), toolCalls);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/** Ollama 消息转换:OpenAI 形态,图片走 images 字段 */
|
|
287
|
+
export function toOllamaMessages(messages) {
|
|
288
|
+
return toOpenAIMessages(messages, false).map((m) => {
|
|
289
|
+
if (m.role === "user" && Array.isArray(m.content)) {
|
|
290
|
+
const parts = m.content;
|
|
291
|
+
const images = parts
|
|
292
|
+
.filter((p) => p.type === "image_url")
|
|
293
|
+
.map((p) => String(p.image_url?.url ?? "").split(",").pop() ?? "");
|
|
294
|
+
const text = parts
|
|
295
|
+
.filter((p) => p.type === "text")
|
|
296
|
+
.map((p) => String(p.text ?? ""))
|
|
297
|
+
.join("\n");
|
|
298
|
+
const msg = { role: "user", content: text };
|
|
299
|
+
if (images.length > 0)
|
|
300
|
+
msg.images = images;
|
|
301
|
+
return msg;
|
|
302
|
+
}
|
|
303
|
+
return m;
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
// ---------- Ollama ----------
|
|
307
|
+
class OllamaProvider {
|
|
308
|
+
config;
|
|
309
|
+
constructor(config) {
|
|
310
|
+
this.config = config;
|
|
311
|
+
}
|
|
312
|
+
async chat(messages, options) {
|
|
313
|
+
const baseUrl = (this.config.baseUrl ?? "http://localhost:11434").replace(/\/$/, "");
|
|
314
|
+
const body = {
|
|
315
|
+
model: this.config.model,
|
|
316
|
+
stream: false,
|
|
317
|
+
messages: toOllamaMessages(messages),
|
|
318
|
+
};
|
|
319
|
+
if (options?.tools && options.tools.length > 0) {
|
|
320
|
+
body.tools = openAITools(options.tools);
|
|
321
|
+
}
|
|
322
|
+
const res = await fetch(baseUrl + "/api/chat", {
|
|
323
|
+
method: "POST",
|
|
324
|
+
headers: { "Content-Type": "application/json" },
|
|
325
|
+
body: JSON.stringify(body),
|
|
326
|
+
});
|
|
327
|
+
if (!res.ok)
|
|
328
|
+
throw new CloverError("ollama 请求失败:" + res.status + " " + (await res.text()));
|
|
329
|
+
const data = (await res.json());
|
|
330
|
+
return finish(this.config.model, data.message?.content ?? "", toUsage(data.prompt_eval_count ?? 0, data.eval_count ?? 0), parseOpenAIToolCalls(data.message?.tool_calls ?? []));
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
export function createProvider(config) {
|
|
334
|
+
switch (config.id) {
|
|
335
|
+
case "openai":
|
|
336
|
+
return new OpenAICompatibleProvider(config);
|
|
337
|
+
case "custom":
|
|
338
|
+
return new OpenAICompatibleProvider(config);
|
|
339
|
+
case "anthropic":
|
|
340
|
+
return new AnthropicProvider(config);
|
|
341
|
+
case "gemini":
|
|
342
|
+
return new GeminiProvider(config);
|
|
343
|
+
case "ollama":
|
|
344
|
+
return new OllamaProvider(config);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/models/provider.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
export type ProviderId = "openai" | "anthropic" | "gemini" | "ollama" | "custom";
|
|
2
|
+
export type ChatRole = "system" | "user" | "assistant" | "tool";
|
|
3
|
+
export interface ImageBlock {
|
|
4
|
+
mediaType: string;
|
|
5
|
+
dataBase64: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ChatMessage {
|
|
8
|
+
role: ChatRole;
|
|
9
|
+
content: string;
|
|
10
|
+
/** 附件图片(多模态) */
|
|
11
|
+
images?: ImageBlock[];
|
|
12
|
+
/** 工具结果消息:对应的工具调用 ID */
|
|
13
|
+
toolCallId?: string;
|
|
14
|
+
/** 工具结果消息:工具名 */
|
|
15
|
+
name?: string;
|
|
16
|
+
/** assistant 消息:本轮请求的工具调用列表 */
|
|
17
|
+
toolCalls?: ToolCallRequest[];
|
|
18
|
+
}
|
|
19
|
+
export interface ChatUsage {
|
|
20
|
+
inputTokens: number;
|
|
21
|
+
outputTokens: number;
|
|
22
|
+
}
|
|
23
|
+
export interface ToolCallRequest {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
args: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
export interface ChatOptions {
|
|
29
|
+
/** 本轮可用的工具定义(各家会转换为自己的 function calling 协议) */
|
|
30
|
+
tools?: ToolDefinition[];
|
|
31
|
+
}
|
|
32
|
+
export interface ChatResult {
|
|
33
|
+
content: string;
|
|
34
|
+
usage: ChatUsage;
|
|
35
|
+
/** 估算费用(美元) */
|
|
36
|
+
estimatedCostUsd: number;
|
|
37
|
+
model: string;
|
|
38
|
+
/** 模型请求的工具调用(没有则为空) */
|
|
39
|
+
toolCalls?: ToolCallRequest[];
|
|
40
|
+
}
|
|
41
|
+
export interface ToolParameter {
|
|
42
|
+
name: string;
|
|
43
|
+
/** JSON Schema 类型 */
|
|
44
|
+
type: "string" | "number" | "boolean" | "array" | "object";
|
|
45
|
+
description: string;
|
|
46
|
+
required?: boolean;
|
|
47
|
+
}
|
|
48
|
+
export interface ToolResult {
|
|
49
|
+
ok: boolean;
|
|
50
|
+
output: string;
|
|
51
|
+
}
|
|
52
|
+
export interface ToolDefinition {
|
|
53
|
+
name: string;
|
|
54
|
+
description: string;
|
|
55
|
+
parameters: ToolParameter[];
|
|
56
|
+
run(args: Record<string, string | undefined>): Promise<ToolResult>;
|
|
57
|
+
}
|
|
58
|
+
export interface ProviderConfig {
|
|
59
|
+
id: ProviderId;
|
|
60
|
+
/** 默认模型名 */
|
|
61
|
+
model: string;
|
|
62
|
+
apiKey?: string;
|
|
63
|
+
baseUrl?: string;
|
|
64
|
+
enabled: boolean;
|
|
65
|
+
}
|
|
66
|
+
export interface CloverConfig {
|
|
67
|
+
/** 界面与生成文档的语言:zh | en */
|
|
68
|
+
language: "zh" | "en";
|
|
69
|
+
/** 默认模型 Provider */
|
|
70
|
+
defaultProvider: ProviderId;
|
|
71
|
+
providers: Partial<Record<ProviderId, ProviderConfig>>;
|
|
72
|
+
/** 预算上限(美元),0 表示不限制 */
|
|
73
|
+
budgetUsd: number;
|
|
74
|
+
/** 竞速模式:自动执行已批准类型命令 */
|
|
75
|
+
speedMode: boolean;
|
|
76
|
+
/** 自动 git 备份间隔(分钟) */
|
|
77
|
+
backupIntervalMinutes: number;
|
|
78
|
+
/** 定时备份开关 */
|
|
79
|
+
autoBackup: boolean;
|
|
80
|
+
}
|
|
81
|
+
export interface HackathonMeta {
|
|
82
|
+
name: string;
|
|
83
|
+
theme?: string;
|
|
84
|
+
url?: string;
|
|
85
|
+
startAt?: string;
|
|
86
|
+
endAt?: string;
|
|
87
|
+
durationHours: number;
|
|
88
|
+
createdAt: string;
|
|
89
|
+
}
|
|
90
|
+
export interface SessionRecord {
|
|
91
|
+
id: string;
|
|
92
|
+
startedAt: string;
|
|
93
|
+
updatedAt: string;
|
|
94
|
+
messages: ChatMessage[];
|
|
95
|
+
totalInputTokens: number;
|
|
96
|
+
totalOutputTokens: number;
|
|
97
|
+
totalCostUsd: number;
|
|
98
|
+
}
|
|
99
|
+
export interface ProjectState {
|
|
100
|
+
meta: HackathonMeta | null;
|
|
101
|
+
challengeSummary?: string;
|
|
102
|
+
ideas?: IdeaRecord[];
|
|
103
|
+
mvpPlan?: MvpRecord;
|
|
104
|
+
checklist?: Record<string, boolean>;
|
|
105
|
+
}
|
|
106
|
+
export interface IdeaRecord {
|
|
107
|
+
id: string;
|
|
108
|
+
title: string;
|
|
109
|
+
summary: string;
|
|
110
|
+
score: number;
|
|
111
|
+
marketNote?: string;
|
|
112
|
+
createdAt: string;
|
|
113
|
+
}
|
|
114
|
+
export interface MvpRecord {
|
|
115
|
+
goal: string;
|
|
116
|
+
features: string[];
|
|
117
|
+
milestones: Array<{
|
|
118
|
+
title: string;
|
|
119
|
+
hours: number;
|
|
120
|
+
tasks: string[];
|
|
121
|
+
}>;
|
|
122
|
+
createdAt: string;
|
|
123
|
+
}
|
|
124
|
+
export interface ArchiveEntry {
|
|
125
|
+
id: string;
|
|
126
|
+
name: string;
|
|
127
|
+
path: string;
|
|
128
|
+
createdAt: string;
|
|
129
|
+
endedAt?: string;
|
|
130
|
+
retrospective?: string;
|
|
131
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,gBAAgB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CloverConfig } from "../types.js";
|
|
2
|
+
export declare const GLOBAL_DIR: string;
|
|
3
|
+
export declare const GLOBAL_CONFIG_PATH: string;
|
|
4
|
+
export declare const PROJECT_DIR_NAME = ".clover";
|
|
5
|
+
export declare const PROJECT_CONFIG_PATH: string;
|
|
6
|
+
export declare const ARCHIVE_PATH: string;
|
|
7
|
+
export declare const DEFAULT_CONFIG: CloverConfig;
|
|
8
|
+
/** 读取 JSON,兼容 UTF-8 BOM;文件不存在返回 null */
|
|
9
|
+
export declare function readJsonFile<T>(filePath: string): T | null;
|
|
10
|
+
export declare function writeJsonFile(filePath: string, data: unknown): void;
|
|
11
|
+
export declare function loadGlobalConfig(): CloverConfig;
|
|
12
|
+
export declare function saveGlobalConfig(config: CloverConfig): void;
|
|
13
|
+
/** 判断当前目录是否已初始化比赛项目 */
|
|
14
|
+
export declare function isProject(): boolean;
|
|
15
|
+
export declare function requireProject(): CloverConfig;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// 配置系统:全局配置(~/.clover/config.json)+ 项目状态(.clover/)
|
|
2
|
+
// 支持 .env 注入 API Key(CLOVER_OPENAI_KEY 等),向导生成 + 手动编辑双通道。
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import dotenv from "dotenv";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
dotenv.config();
|
|
9
|
+
export const GLOBAL_DIR = path.join(os.homedir(), ".clover");
|
|
10
|
+
export const GLOBAL_CONFIG_PATH = path.join(GLOBAL_DIR, "config.json");
|
|
11
|
+
export const PROJECT_DIR_NAME = ".clover";
|
|
12
|
+
export const PROJECT_CONFIG_PATH = path.join(PROJECT_DIR_NAME, "clover.json");
|
|
13
|
+
export const ARCHIVE_PATH = path.join(GLOBAL_DIR, "archive.json");
|
|
14
|
+
const providerSchema = z.object({
|
|
15
|
+
id: z.enum(["openai", "anthropic", "gemini", "ollama", "custom"]),
|
|
16
|
+
model: z.string(),
|
|
17
|
+
apiKey: z.string().optional(),
|
|
18
|
+
baseUrl: z.string().optional(),
|
|
19
|
+
enabled: z.boolean(),
|
|
20
|
+
});
|
|
21
|
+
const configSchema = z.object({
|
|
22
|
+
language: z.enum(["zh", "en"]),
|
|
23
|
+
defaultProvider: z.enum(["openai", "anthropic", "gemini", "ollama", "custom"]),
|
|
24
|
+
providers: z.record(z.string(), providerSchema).optional(),
|
|
25
|
+
budgetUsd: z.number().min(0),
|
|
26
|
+
speedMode: z.boolean(),
|
|
27
|
+
backupIntervalMinutes: z.number().min(1),
|
|
28
|
+
autoBackup: z.boolean(),
|
|
29
|
+
});
|
|
30
|
+
export const DEFAULT_CONFIG = {
|
|
31
|
+
language: "zh",
|
|
32
|
+
defaultProvider: "openai",
|
|
33
|
+
providers: {
|
|
34
|
+
openai: { id: "openai", model: "gpt-4o-mini", apiKey: undefined, enabled: false },
|
|
35
|
+
anthropic: { id: "anthropic", model: "claude-sonnet-4-5", apiKey: undefined, enabled: false },
|
|
36
|
+
gemini: { id: "gemini", model: "gemini-2.5-flash", apiKey: undefined, enabled: false },
|
|
37
|
+
ollama: { id: "ollama", model: "qwen2.5:7b", baseUrl: "http://localhost:11434", enabled: false },
|
|
38
|
+
custom: { id: "custom", model: "gpt-4o-mini", apiKey: undefined, baseUrl: undefined, enabled: false },
|
|
39
|
+
},
|
|
40
|
+
budgetUsd: 10,
|
|
41
|
+
speedMode: false,
|
|
42
|
+
backupIntervalMinutes: 30,
|
|
43
|
+
autoBackup: true,
|
|
44
|
+
};
|
|
45
|
+
/** 读取 JSON,兼容 UTF-8 BOM;文件不存在返回 null */
|
|
46
|
+
export function readJsonFile(filePath) {
|
|
47
|
+
if (!fs.existsSync(filePath))
|
|
48
|
+
return null;
|
|
49
|
+
const raw = fs.readFileSync(filePath, "utf8").replace(/^\uFEFF/, "");
|
|
50
|
+
try {
|
|
51
|
+
return JSON.parse(raw);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export function writeJsonFile(filePath, data) {
|
|
58
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
59
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
60
|
+
}
|
|
61
|
+
/** 从环境变量补全 API Key:CLOVER_<PROVIDER>_KEY */
|
|
62
|
+
function applyEnvKeys(config) {
|
|
63
|
+
for (const id of Object.keys(config.providers)) {
|
|
64
|
+
const envKey = "CLOVER_" + id.toUpperCase() + "_KEY";
|
|
65
|
+
const value = process.env[envKey];
|
|
66
|
+
const provider = config.providers[id];
|
|
67
|
+
if (provider && value && !provider.apiKey) {
|
|
68
|
+
provider.apiKey = value;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return config;
|
|
72
|
+
}
|
|
73
|
+
export function loadGlobalConfig() {
|
|
74
|
+
const raw = readJsonFile(GLOBAL_CONFIG_PATH);
|
|
75
|
+
if (!raw)
|
|
76
|
+
return DEFAULT_CONFIG;
|
|
77
|
+
const parsed = configSchema.safeParse(raw);
|
|
78
|
+
return applyEnvKeys(parsed.success ? parsed.data : DEFAULT_CONFIG);
|
|
79
|
+
}
|
|
80
|
+
export function saveGlobalConfig(config) {
|
|
81
|
+
writeJsonFile(GLOBAL_CONFIG_PATH, config);
|
|
82
|
+
}
|
|
83
|
+
/** 判断当前目录是否已初始化比赛项目 */
|
|
84
|
+
export function isProject() {
|
|
85
|
+
return fs.existsSync(PROJECT_CONFIG_PATH);
|
|
86
|
+
}
|
|
87
|
+
export function requireProject() {
|
|
88
|
+
if (!isProject()) {
|
|
89
|
+
throw new Error("当前目录不是 Clover 比赛项目,请先运行 clover init");
|
|
90
|
+
}
|
|
91
|
+
return loadGlobalConfig();
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ChatUsage } from "../types.js";
|
|
2
|
+
export interface ModelPrice {
|
|
3
|
+
inputPerM: number;
|
|
4
|
+
outputPerM: number;
|
|
5
|
+
}
|
|
6
|
+
export declare const PRICING: Record<string, ModelPrice>;
|
|
7
|
+
export declare function estimateCostUsd(usage: ChatUsage, model: string): number;
|
|
8
|
+
export declare function formatUsd(value: number): string;
|
|
9
|
+
export interface BudgetStatus {
|
|
10
|
+
totalUsd: number;
|
|
11
|
+
limitUsd: number;
|
|
12
|
+
ratio: number;
|
|
13
|
+
nearLimit: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function checkBudget(totalUsd: number, limitUsd: number): BudgetStatus;
|
|
16
|
+
export declare function addUsage(a: ChatUsage, b: ChatUsage): ChatUsage;
|