@hirohsu/user-web-feedback 2.8.17 → 2.8.19
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/dist/cli.cjs +84 -234
- package/dist/index.cjs +84 -234
- package/dist/static/modules/conversation-panel.js +132 -47
- package/dist/static/modules/feedback-handler.js +37 -8
- package/dist/static/modules/timer-controller.js +6 -0
- package/dist/static/style.css +106 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -44214,7 +44214,7 @@ var require_application = __commonJS({
|
|
|
44214
44214
|
};
|
|
44215
44215
|
app.del = deprecate.function(app.delete, "app.del: Use app.delete instead");
|
|
44216
44216
|
app.render = function render(name, options, callback) {
|
|
44217
|
-
var
|
|
44217
|
+
var cache2 = this.cache;
|
|
44218
44218
|
var done = callback;
|
|
44219
44219
|
var engines = this.engines;
|
|
44220
44220
|
var opts = options;
|
|
@@ -44233,7 +44233,7 @@ var require_application = __commonJS({
|
|
|
44233
44233
|
renderOptions.cache = this.enabled("view cache");
|
|
44234
44234
|
}
|
|
44235
44235
|
if (renderOptions.cache) {
|
|
44236
|
-
view =
|
|
44236
|
+
view = cache2[name];
|
|
44237
44237
|
}
|
|
44238
44238
|
if (!view) {
|
|
44239
44239
|
var View2 = this.get("view");
|
|
@@ -44249,7 +44249,7 @@ var require_application = __commonJS({
|
|
|
44249
44249
|
return done(err);
|
|
44250
44250
|
}
|
|
44251
44251
|
if (renderOptions.cache) {
|
|
44252
|
-
|
|
44252
|
+
cache2[name] = view;
|
|
44253
44253
|
}
|
|
44254
44254
|
}
|
|
44255
44255
|
tryRender(view, renderOptions, done);
|
|
@@ -75263,6 +75263,15 @@ var init_prompt_aggregator = __esm({
|
|
|
75263
75263
|
getComponentNames() {
|
|
75264
75264
|
return this.components.map((c) => c.getName());
|
|
75265
75265
|
}
|
|
75266
|
+
getPromptConfigsForDebug() {
|
|
75267
|
+
const configs = this.getPromptConfigsWithDefaults();
|
|
75268
|
+
return configs.map((c) => ({
|
|
75269
|
+
id: c.id,
|
|
75270
|
+
enabled: c.enabled,
|
|
75271
|
+
firstOrder: c.firstOrder,
|
|
75272
|
+
secondOrder: c.secondOrder
|
|
75273
|
+
}));
|
|
75274
|
+
}
|
|
75266
75275
|
getPromptConfigsWithDefaults() {
|
|
75267
75276
|
try {
|
|
75268
75277
|
const configs = getPromptConfigs();
|
|
@@ -75365,61 +75374,6 @@ function formatToolResults(results) {
|
|
|
75365
75374
|
}
|
|
75366
75375
|
return lines.join("\n");
|
|
75367
75376
|
}
|
|
75368
|
-
function buildToolsPrompt(tools, projectName, projectPath) {
|
|
75369
|
-
if (tools.length === 0) {
|
|
75370
|
-
return "";
|
|
75371
|
-
}
|
|
75372
|
-
const lines = [];
|
|
75373
|
-
if (projectName || projectPath) {
|
|
75374
|
-
lines.push("");
|
|
75375
|
-
lines.push("## \u5C08\u6848\u80CC\u666F\u8CC7\u8A0A");
|
|
75376
|
-
lines.push(`\u7576\u524D\u5C08\u6848: ${projectName || "\u672A\u547D\u540D\u5C08\u6848"}`);
|
|
75377
|
-
if (projectPath) {
|
|
75378
|
-
lines.push(`\u5C08\u6848\u8DEF\u5F91: ${projectPath}`);
|
|
75379
|
-
}
|
|
75380
|
-
lines.push("");
|
|
75381
|
-
lines.push("**\u91CD\u8981\u6307\u793A**: \u5728\u56DE\u8986\u4E4B\u524D\uFF0C\u4F60\u61C9\u8A72\u5148\u4F7F\u7528 MCP \u5DE5\u5177\u4F86\u67E5\u8A62\u5C08\u6848\u7684\u80CC\u666F\u8CC7\u8A0A\uFF1A");
|
|
75382
|
-
lines.push("1. \u5C08\u6848\u7684\u67B6\u69CB\u548C\u7D50\u69CB\uFF08\u5982\u4F7F\u7528 get_symbols_overview, list_dir \u7B49\uFF09");
|
|
75383
|
-
lines.push("2. \u5C08\u6848\u7684\u958B\u767C\u8A08\u5283\u548C\u898F\u7BC4\uFF08\u5982\u8B80\u53D6 openspec \u76EE\u9304\u4E2D\u7684\u6587\u4EF6\uFF09");
|
|
75384
|
-
lines.push("3. \u7576\u524D\u7684\u4EFB\u52D9\u548C\u9032\u5EA6");
|
|
75385
|
-
lines.push("");
|
|
75386
|
-
lines.push("**\u8ACB\u52D9\u5FC5\u5148\u8ABF\u7528\u5DE5\u5177\u67E5\u8A62\u5C08\u6848\u8CC7\u8A0A**\uFF0C\u7136\u5F8C\u6839\u64DA\u67E5\u8A62\u7D50\u679C\u63D0\u4F9B\u7CBE\u78BA\u7684\u56DE\u8986\u3002");
|
|
75387
|
-
}
|
|
75388
|
-
lines.push("");
|
|
75389
|
-
lines.push("## MCP \u5DE5\u5177\u4F7F\u7528\u8AAA\u660E");
|
|
75390
|
-
lines.push("");
|
|
75391
|
-
lines.push("\u7576\u4F60\u9700\u8981\u4F7F\u7528\u5DE5\u5177\u6642\uFF0C\u8ACB\u56DE\u8986\u4E00\u500B JSON \u683C\u5F0F\u7684\u5DE5\u5177\u8ABF\u7528\u8ACB\u6C42\uFF08\u4E0D\u8981\u6709\u5176\u4ED6\u6587\u5B57\uFF09\uFF1A");
|
|
75392
|
-
lines.push("");
|
|
75393
|
-
lines.push("```json");
|
|
75394
|
-
lines.push("{");
|
|
75395
|
-
lines.push(' "tool_calls": [');
|
|
75396
|
-
lines.push(' { "name": "\u5DE5\u5177\u540D\u7A31", "arguments": { "\u53C3\u6578\u540D": "\u53C3\u6578\u503C" } }');
|
|
75397
|
-
lines.push(" ],");
|
|
75398
|
-
lines.push(' "message": "\u8AAA\u660E\u4F60\u6B63\u5728\u505A\u4EC0\u9EBC\uFF08\u53EF\u9078\uFF09"');
|
|
75399
|
-
lines.push("}");
|
|
75400
|
-
lines.push("```");
|
|
75401
|
-
lines.push("");
|
|
75402
|
-
lines.push("\u5DE5\u5177\u57F7\u884C\u5F8C\uFF0C\u7D50\u679C\u6703\u56DE\u50B3\u7D66\u4F60\u3002\u4F60\u53EF\u4EE5\u7E7C\u7E8C\u8ABF\u7528\u66F4\u591A\u5DE5\u5177\uFF0C\u6216\u6839\u64DA\u7D50\u679C\u63D0\u4F9B\u6700\u7D42\u56DE\u8986\u3002");
|
|
75403
|
-
lines.push("\u7576\u4F60\u4E0D\u9700\u8981\u8ABF\u7528\u5DE5\u5177\u6642\uFF0C\u76F4\u63A5\u4EE5\u7D14\u6587\u5B57\u56DE\u8986\u5373\u53EF\u3002");
|
|
75404
|
-
lines.push("");
|
|
75405
|
-
lines.push("## \u53EF\u7528\u5DE5\u5177\u5217\u8868");
|
|
75406
|
-
lines.push("");
|
|
75407
|
-
for (const tool of tools) {
|
|
75408
|
-
lines.push(`### ${tool.name}`);
|
|
75409
|
-
if (tool.description) {
|
|
75410
|
-
lines.push(tool.description);
|
|
75411
|
-
}
|
|
75412
|
-
if (tool.inputSchema) {
|
|
75413
|
-
lines.push("");
|
|
75414
|
-
lines.push("\u53C3\u6578\u683C\u5F0F:");
|
|
75415
|
-
lines.push("```json");
|
|
75416
|
-
lines.push(JSON.stringify(tool.inputSchema, null, 2));
|
|
75417
|
-
lines.push("```");
|
|
75418
|
-
}
|
|
75419
|
-
lines.push("");
|
|
75420
|
-
}
|
|
75421
|
-
return lines.join("\n");
|
|
75422
|
-
}
|
|
75423
75377
|
var init_mcp_tool_parser = __esm({
|
|
75424
75378
|
"src/utils/mcp-tool-parser.ts"() {
|
|
75425
75379
|
"use strict";
|
|
@@ -75772,131 +75726,91 @@ async function generateCLIReply(request, cliSettings) {
|
|
|
75772
75726
|
}
|
|
75773
75727
|
}
|
|
75774
75728
|
async function generateAPIReply(request) {
|
|
75729
|
+
const startTime = Date.now();
|
|
75775
75730
|
try {
|
|
75776
75731
|
const cacheKey = `${request.aiMessage}:${request.userContext || ""}`;
|
|
75777
75732
|
if (!request.toolResults) {
|
|
75778
75733
|
const cached2 = cache.get(cacheKey);
|
|
75779
75734
|
if (cached2 && Date.now() - cached2.timestamp < CACHE_TTL2) {
|
|
75780
75735
|
logger.debug("[AI Service] \u4F7F\u7528\u5FEB\u53D6\u56DE\u8986");
|
|
75781
|
-
return {
|
|
75782
|
-
success: true,
|
|
75783
|
-
reply: cached2.reply
|
|
75784
|
-
};
|
|
75736
|
+
return { success: true, reply: cached2.reply };
|
|
75785
75737
|
}
|
|
75786
75738
|
}
|
|
75787
75739
|
logger.debug("[AI Service] \u7372\u53D6 AI \u8A2D\u5B9A");
|
|
75788
75740
|
const settings = getAISettings();
|
|
75789
|
-
logger.debug("[AI Service] AI \u8A2D\u5B9A\u7372\u53D6\u5B8C\u6210", {
|
|
75790
|
-
hasApiKey: !!settings?.apiKey,
|
|
75791
|
-
model: settings?.model,
|
|
75792
|
-
hasMcpToolsPrompt: !!settings?.mcpToolsPrompt
|
|
75793
|
-
});
|
|
75794
75741
|
if (!settings || !settings.apiKey || settings.apiKey === "YOUR_API_KEY_HERE") {
|
|
75795
75742
|
logger.warn("[AI Service] API Key \u672A\u8A2D\u5B9A\u6216\u7121\u6548");
|
|
75796
|
-
return {
|
|
75797
|
-
success: false,
|
|
75798
|
-
error: "\u8ACB\u5148\u5728\u8A2D\u5B9A\u4E2D\u914D\u7F6E AI API Key"
|
|
75799
|
-
};
|
|
75743
|
+
return { success: false, error: "\u8ACB\u5148\u5728\u8A2D\u5B9A\u4E2D\u914D\u7F6E AI API Key" };
|
|
75800
75744
|
}
|
|
75801
|
-
|
|
75745
|
+
const aggregator = getPromptAggregator();
|
|
75746
|
+
const cliSettings = getCLISettings();
|
|
75747
|
+
let mcpTools = [];
|
|
75802
75748
|
if (request.includeMCPTools) {
|
|
75803
|
-
logger.debug("[AI Service] \u958B\u59CB\u7372\u53D6 MCP \u5DE5\u5177");
|
|
75804
75749
|
try {
|
|
75805
75750
|
const allTools = mcpClientManager.getAllTools();
|
|
75806
|
-
|
|
75807
|
-
|
|
75808
|
-
|
|
75809
|
-
|
|
75810
|
-
|
|
75811
|
-
|
|
75812
|
-
|
|
75813
|
-
logger.debug("[AI Service] \u9644\u52A0\u5DE5\u5177\u5217\u8868\u5230\u63D0\u793A\u8A5E");
|
|
75814
|
-
mcpToolsPrompt += "\n\n## \u53EF\u7528\u5DE5\u5177\u5217\u8868\n\n";
|
|
75815
|
-
for (const tool of allTools) {
|
|
75816
|
-
mcpToolsPrompt += `### ${tool.name}
|
|
75817
|
-
`;
|
|
75818
|
-
if (tool.description) {
|
|
75819
|
-
mcpToolsPrompt += `${tool.description}
|
|
75820
|
-
`;
|
|
75821
|
-
}
|
|
75822
|
-
if (tool.inputSchema) {
|
|
75823
|
-
mcpToolsPrompt += "\n\u53C3\u6578\u683C\u5F0F:\n```json\n";
|
|
75824
|
-
mcpToolsPrompt += JSON.stringify(tool.inputSchema, null, 2);
|
|
75825
|
-
mcpToolsPrompt += "\n```\n";
|
|
75826
|
-
}
|
|
75827
|
-
mcpToolsPrompt += "\n";
|
|
75828
|
-
}
|
|
75829
|
-
}
|
|
75830
|
-
} else {
|
|
75831
|
-
logger.debug("[AI Service] \u4F7F\u7528\u9810\u8A2D\u7684 buildToolsPrompt");
|
|
75832
|
-
mcpToolsPrompt = buildToolsPrompt(allTools, request.projectName, request.projectPath);
|
|
75833
|
-
}
|
|
75834
|
-
} catch (error2) {
|
|
75835
|
-
logger.warn("[AI Service] Failed to get MCP tools for AI prompt", error2);
|
|
75751
|
+
mcpTools = allTools.map((t) => ({
|
|
75752
|
+
name: t.name,
|
|
75753
|
+
description: t.description,
|
|
75754
|
+
inputSchema: t.inputSchema
|
|
75755
|
+
}));
|
|
75756
|
+
} catch {
|
|
75757
|
+
logger.warn("[AI Service] \u7121\u6CD5\u7372\u53D6 MCP \u5DE5\u5177");
|
|
75836
75758
|
}
|
|
75837
75759
|
}
|
|
75838
|
-
|
|
75839
|
-
|
|
75840
|
-
|
|
75841
|
-
|
|
75842
|
-
|
|
75760
|
+
const context = aggregator.buildContextSync(request, settings, cliSettings, mcpTools);
|
|
75761
|
+
context.mode = "api";
|
|
75762
|
+
const aggregated = aggregator.aggregate(context);
|
|
75763
|
+
const promptSent = aggregated.fullPrompt;
|
|
75764
|
+
logger.debug("[AI Service] PromptAggregator \u69CB\u5EFA\u5B8C\u6210", {
|
|
75765
|
+
componentCount: aggregated.sections.length,
|
|
75766
|
+
sections: aggregated.sections.map((s) => `${s.name}(order:${s.order})`),
|
|
75767
|
+
totalLength: promptSent.length,
|
|
75768
|
+
tokenEstimate: aggregated.metadata.tokenEstimate
|
|
75843
75769
|
});
|
|
75844
|
-
const
|
|
75845
|
-
settings.systemPrompt,
|
|
75846
|
-
request.aiMessage,
|
|
75847
|
-
request.userContext,
|
|
75848
|
-
mcpToolsPrompt,
|
|
75849
|
-
request.toolResults
|
|
75850
|
-
);
|
|
75851
|
-
const reply = await generateWithRetry(
|
|
75770
|
+
const reply = await generateWithRetryFromPrompt(
|
|
75852
75771
|
settings.apiKey,
|
|
75853
75772
|
settings.model,
|
|
75854
|
-
|
|
75855
|
-
request.aiMessage,
|
|
75856
|
-
request.userContext,
|
|
75773
|
+
promptSent,
|
|
75857
75774
|
settings.temperature,
|
|
75858
|
-
settings.maxTokens
|
|
75859
|
-
0,
|
|
75860
|
-
mcpToolsPrompt,
|
|
75861
|
-
request.toolResults
|
|
75775
|
+
settings.maxTokens
|
|
75862
75776
|
);
|
|
75863
|
-
|
|
75864
|
-
replyLength: reply.length
|
|
75865
|
-
});
|
|
75777
|
+
const elapsedMs = Date.now() - startTime;
|
|
75866
75778
|
if (!request.toolResults) {
|
|
75867
|
-
cache.set(cacheKey, {
|
|
75868
|
-
reply,
|
|
75869
|
-
timestamp: Date.now()
|
|
75870
|
-
});
|
|
75779
|
+
cache.set(cacheKey, { reply, timestamp: Date.now() });
|
|
75871
75780
|
cleanExpiredCache();
|
|
75872
75781
|
}
|
|
75873
|
-
|
|
75782
|
+
const promptConfigs = aggregator.getPromptConfigsForDebug();
|
|
75874
75783
|
return {
|
|
75875
75784
|
success: true,
|
|
75876
75785
|
reply,
|
|
75877
75786
|
promptSent,
|
|
75878
|
-
mode: "api"
|
|
75787
|
+
mode: "api",
|
|
75788
|
+
debug: {
|
|
75789
|
+
sections: aggregated.sections.map((s) => ({ name: s.name, order: s.order, length: s.content.length })),
|
|
75790
|
+
tokenEstimate: aggregated.metadata.tokenEstimate,
|
|
75791
|
+
totalPromptLength: promptSent.length,
|
|
75792
|
+
elapsedMs,
|
|
75793
|
+
model: settings.model,
|
|
75794
|
+
temperature: settings.temperature,
|
|
75795
|
+
maxTokens: settings.maxTokens,
|
|
75796
|
+
mcpToolsCount: mcpTools.length,
|
|
75797
|
+
componentCount: aggregated.sections.length,
|
|
75798
|
+
promptConfigs
|
|
75799
|
+
}
|
|
75879
75800
|
};
|
|
75880
75801
|
} catch (error2) {
|
|
75802
|
+
const elapsedMs = Date.now() - startTime;
|
|
75881
75803
|
logger.error("[AI Service] AI service error:", error2);
|
|
75882
75804
|
return {
|
|
75883
75805
|
success: false,
|
|
75884
75806
|
error: error2 instanceof Error ? error2.message : "\u672A\u77E5\u932F\u8AA4",
|
|
75885
|
-
mode: "api"
|
|
75807
|
+
mode: "api",
|
|
75808
|
+
debug: { elapsedMs }
|
|
75886
75809
|
};
|
|
75887
75810
|
}
|
|
75888
75811
|
}
|
|
75889
|
-
async function
|
|
75812
|
+
async function generateWithRetryFromPrompt(apiKey, model, prompt, temperature, maxTokens, retryCount = 0) {
|
|
75890
75813
|
try {
|
|
75891
|
-
logger.debug("[AI Service] generateWithRetry \u958B\u59CB", {
|
|
75892
|
-
model,
|
|
75893
|
-
retryCount,
|
|
75894
|
-
hasSystemPrompt: !!systemPrompt,
|
|
75895
|
-
hasMcpToolsPrompt: !!mcpToolsPrompt,
|
|
75896
|
-
hasToolResults: !!toolResults,
|
|
75897
|
-
temperature,
|
|
75898
|
-
maxTokens
|
|
75899
|
-
});
|
|
75900
75814
|
const genAI = new GoogleGenerativeAI(apiKey);
|
|
75901
75815
|
const generativeModel = genAI.getGenerativeModel({
|
|
75902
75816
|
model,
|
|
@@ -75905,45 +75819,20 @@ async function generateWithRetry(apiKey, model, systemPrompt, aiMessage, userCon
|
|
|
75905
75819
|
maxOutputTokens: maxTokens ?? 1e3
|
|
75906
75820
|
}
|
|
75907
75821
|
});
|
|
75908
|
-
logger.debug("[AI Service] \
|
|
75909
|
-
const prompt = buildPrompt(systemPrompt, aiMessage, userContext, mcpToolsPrompt, toolResults);
|
|
75910
|
-
logger.debug("[AI Service] \u63D0\u793A\u8A5E\u69CB\u5EFA\u5B8C\u6210", {
|
|
75911
|
-
promptLength: prompt.length
|
|
75912
|
-
});
|
|
75913
|
-
logger.debug("[AI Service] \u958B\u59CB\u8ABF\u7528 Google Gemini API");
|
|
75822
|
+
logger.debug("[AI Service] \u958B\u59CB\u8ABF\u7528 API (PromptAggregator prompt)", { promptLength: prompt.length });
|
|
75914
75823
|
const result = await generativeModel.generateContent(prompt);
|
|
75915
|
-
logger.debug("[AI Service] API \u8ABF\u7528\u5B8C\u6210");
|
|
75916
75824
|
const response = await result.response;
|
|
75917
75825
|
const text = response.text();
|
|
75918
75826
|
if (!text) {
|
|
75919
75827
|
throw new Error("AI \u56DE\u8986\u70BA\u7A7A");
|
|
75920
75828
|
}
|
|
75921
|
-
logger.debug("[AI Service] \u56DE\u8986\u6587\u5B57\u7372\u53D6\u6210\u529F", {
|
|
75922
|
-
textLength: text.length
|
|
75923
|
-
});
|
|
75924
75829
|
return text;
|
|
75925
75830
|
} catch (error2) {
|
|
75926
|
-
logger.debug("[AI Service] generateWithRetry \u767C\u751F\u932F\u8AA4", {
|
|
75927
|
-
error: error2 instanceof Error ? error2.message : String(error2),
|
|
75928
|
-
retryCount
|
|
75929
|
-
});
|
|
75930
75831
|
if (error2 instanceof Error) {
|
|
75931
75832
|
if (error2.message.includes("429") || error2.message.includes("quota")) {
|
|
75932
75833
|
if (retryCount < MAX_RETRIES) {
|
|
75933
|
-
|
|
75934
|
-
|
|
75935
|
-
return generateWithRetry(
|
|
75936
|
-
apiKey,
|
|
75937
|
-
model,
|
|
75938
|
-
systemPrompt,
|
|
75939
|
-
aiMessage,
|
|
75940
|
-
userContext,
|
|
75941
|
-
temperature,
|
|
75942
|
-
maxTokens,
|
|
75943
|
-
retryCount + 1,
|
|
75944
|
-
mcpToolsPrompt,
|
|
75945
|
-
toolResults
|
|
75946
|
-
);
|
|
75834
|
+
await sleep(RETRY_DELAYS[retryCount] || 4e3);
|
|
75835
|
+
return generateWithRetryFromPrompt(apiKey, model, prompt, temperature, maxTokens, retryCount + 1);
|
|
75947
75836
|
}
|
|
75948
75837
|
throw new Error("API \u914D\u984D\u5DF2\u7528\u76E1\u6216\u901F\u7387\u9650\u5236\uFF0C\u8ACB\u7A0D\u5F8C\u518D\u8A66");
|
|
75949
75838
|
}
|
|
@@ -75951,51 +75840,13 @@ async function generateWithRetry(apiKey, model, systemPrompt, aiMessage, userCon
|
|
|
75951
75840
|
throw new Error("API Key \u7121\u6548\uFF0C\u8ACB\u6AA2\u67E5\u8A2D\u5B9A");
|
|
75952
75841
|
}
|
|
75953
75842
|
if (retryCount < MAX_RETRIES) {
|
|
75954
|
-
|
|
75955
|
-
|
|
75956
|
-
return generateWithRetry(
|
|
75957
|
-
apiKey,
|
|
75958
|
-
model,
|
|
75959
|
-
systemPrompt,
|
|
75960
|
-
aiMessage,
|
|
75961
|
-
userContext,
|
|
75962
|
-
temperature,
|
|
75963
|
-
maxTokens,
|
|
75964
|
-
retryCount + 1,
|
|
75965
|
-
mcpToolsPrompt,
|
|
75966
|
-
toolResults
|
|
75967
|
-
);
|
|
75843
|
+
await sleep(RETRY_DELAYS[retryCount] || 4e3);
|
|
75844
|
+
return generateWithRetryFromPrompt(apiKey, model, prompt, temperature, maxTokens, retryCount + 1);
|
|
75968
75845
|
}
|
|
75969
75846
|
}
|
|
75970
75847
|
throw error2;
|
|
75971
75848
|
}
|
|
75972
75849
|
}
|
|
75973
|
-
function buildPrompt(systemPrompt, aiMessage, userContext, mcpToolsPrompt = "", toolResults) {
|
|
75974
|
-
let prompt = `${systemPrompt}
|
|
75975
|
-
|
|
75976
|
-
`;
|
|
75977
|
-
if (mcpToolsPrompt) {
|
|
75978
|
-
prompt += mcpToolsPrompt + "\n\n";
|
|
75979
|
-
}
|
|
75980
|
-
prompt += `AI \u5DE5\u4F5C\u532F\u5831\uFF1A
|
|
75981
|
-
${aiMessage}
|
|
75982
|
-
|
|
75983
|
-
`;
|
|
75984
|
-
if (userContext) {
|
|
75985
|
-
prompt += `\u4F7F\u7528\u8005\u4E0A\u4E0B\u6587\uFF1A
|
|
75986
|
-
${userContext}
|
|
75987
|
-
|
|
75988
|
-
`;
|
|
75989
|
-
}
|
|
75990
|
-
if (toolResults) {
|
|
75991
|
-
prompt += `\u5148\u524D\u5DE5\u5177\u57F7\u884C\u7D50\u679C\uFF1A
|
|
75992
|
-
${toolResults}
|
|
75993
|
-
|
|
75994
|
-
`;
|
|
75995
|
-
}
|
|
75996
|
-
prompt += "\u8ACB\u751F\u6210\u4E00\u500B\u7C21\u6F54\u3001\u5C08\u696D\u7684\u56DE\u61C9\uFF1A";
|
|
75997
|
-
return prompt;
|
|
75998
|
-
}
|
|
75999
75850
|
function sleep(ms) {
|
|
76000
75851
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
76001
75852
|
}
|
|
@@ -76095,7 +75946,6 @@ var init_ai_service = __esm({
|
|
|
76095
75946
|
init_cli_executor();
|
|
76096
75947
|
init_cli_detector();
|
|
76097
75948
|
init_prompt_aggregator2();
|
|
76098
|
-
init_mcp_tool_parser();
|
|
76099
75949
|
MAX_RETRIES = 3;
|
|
76100
75950
|
RETRY_DELAYS = [1e3, 2e3, 4e3];
|
|
76101
75951
|
cache = /* @__PURE__ */ new Map();
|
|
@@ -89933,8 +89783,6 @@ init_mcp_client_manager();
|
|
|
89933
89783
|
init_prompt_aggregator2();
|
|
89934
89784
|
var MAX_RETRIES2 = 3;
|
|
89935
89785
|
var RETRY_DELAYS2 = [1e3, 2e3, 4e3];
|
|
89936
|
-
var cache2 = /* @__PURE__ */ new Map();
|
|
89937
|
-
var CACHE_TTL3 = 5 * 60 * 1e3;
|
|
89938
89786
|
function getProviderFromUrl2(apiUrl) {
|
|
89939
89787
|
if (!apiUrl) return "google";
|
|
89940
89788
|
const normalizedUrl = apiUrl.toLowerCase();
|
|
@@ -89958,15 +89806,17 @@ var APIProvider = class {
|
|
|
89958
89806
|
}
|
|
89959
89807
|
async generateReply(request) {
|
|
89960
89808
|
try {
|
|
89961
|
-
const cacheKey = `${request.aiMessage}:${request.userContext || ""}`;
|
|
89962
|
-
if (!request.toolResults) {
|
|
89963
|
-
const cached2 = cache2.get(cacheKey);
|
|
89964
|
-
if (cached2 && Date.now() - cached2.timestamp < CACHE_TTL3) {
|
|
89965
|
-
logger.debug("[APIProvider] \u4F7F\u7528\u5FEB\u53D6\u56DE\u8986");
|
|
89966
|
-
return { success: true, reply: cached2.reply, mode: "api" };
|
|
89967
|
-
}
|
|
89968
|
-
}
|
|
89969
89809
|
const settings = getAISettings();
|
|
89810
|
+
logger.info("[APIProvider] AI \u8A2D\u5B9A\u72C0\u614B", {
|
|
89811
|
+
hasSettings: !!settings,
|
|
89812
|
+
hasApiKey: !!settings?.apiKey,
|
|
89813
|
+
apiKeyLength: settings?.apiKey?.length,
|
|
89814
|
+
apiKeyPrefix: settings?.apiKey?.substring(0, 6),
|
|
89815
|
+
model: settings?.model,
|
|
89816
|
+
apiUrl: settings?.apiUrl || "(\u672A\u8A2D\u5B9A)",
|
|
89817
|
+
temperature: settings?.temperature,
|
|
89818
|
+
maxTokens: settings?.maxTokens
|
|
89819
|
+
});
|
|
89970
89820
|
if (!settings || !settings.apiKey || settings.apiKey === "YOUR_API_KEY_HERE") {
|
|
89971
89821
|
logger.warn("[APIProvider] API Key \u672A\u8A2D\u5B9A\u6216\u7121\u6548");
|
|
89972
89822
|
return { success: false, error: "\u8ACB\u5148\u5728\u8A2D\u5B9A\u4E2D\u914D\u7F6E AI API Key", mode: "api" };
|
|
@@ -89990,10 +89840,13 @@ var APIProvider = class {
|
|
|
89990
89840
|
context.mode = "api";
|
|
89991
89841
|
const aggregated = aggregator.aggregate(context);
|
|
89992
89842
|
const promptSent = aggregated.fullPrompt;
|
|
89843
|
+
logger.info(`[APIProvider] Prompt \u5DF2\u5EFA\u69CB, \u9577\u5EA6: ${promptSent.length}`);
|
|
89993
89844
|
const provider = getProviderFromUrl2(settings.apiUrl);
|
|
89994
|
-
logger.info(`[APIProvider] \u4F7F\u7528 ${provider} \u63D0\u4F9B\u5546, apiUrl: ${settings.apiUrl || "(\u9810\u8A2D)"}`);
|
|
89845
|
+
logger.info(`[APIProvider] \u4F7F\u7528 ${provider} \u63D0\u4F9B\u5546, apiUrl: ${settings.apiUrl || "(\u9810\u8A2D)"}, model: ${settings.model}`);
|
|
89846
|
+
const startTime = Date.now();
|
|
89995
89847
|
let reply;
|
|
89996
89848
|
if (provider !== "google") {
|
|
89849
|
+
logger.info(`[APIProvider] \u958B\u59CB\u547C\u53EB OpenAI \u76F8\u5BB9 API...`);
|
|
89997
89850
|
reply = await this.generateWithOpenAI(
|
|
89998
89851
|
settings.apiKey,
|
|
89999
89852
|
settings.model,
|
|
@@ -90003,6 +89856,7 @@ var APIProvider = class {
|
|
|
90003
89856
|
settings.maxTokens
|
|
90004
89857
|
);
|
|
90005
89858
|
} else {
|
|
89859
|
+
logger.info(`[APIProvider] \u958B\u59CB\u547C\u53EB Google Gemini API...`);
|
|
90006
89860
|
reply = await this.generateWithGoogle(
|
|
90007
89861
|
settings.apiKey,
|
|
90008
89862
|
settings.model,
|
|
@@ -90011,10 +89865,7 @@ var APIProvider = class {
|
|
|
90011
89865
|
settings.maxTokens
|
|
90012
89866
|
);
|
|
90013
89867
|
}
|
|
90014
|
-
|
|
90015
|
-
cache2.set(cacheKey, { reply, timestamp: Date.now() });
|
|
90016
|
-
this.cleanExpiredCache();
|
|
90017
|
-
}
|
|
89868
|
+
logger.info(`[APIProvider] API \u547C\u53EB\u5B8C\u6210, \u8017\u6642: ${Date.now() - startTime}ms, \u56DE\u8986\u9577\u5EA6: ${reply.length}`);
|
|
90018
89869
|
return { success: true, reply, promptSent, mode: "api" };
|
|
90019
89870
|
} catch (error2) {
|
|
90020
89871
|
logger.error("[APIProvider] \u751F\u6210\u56DE\u8986\u5931\u6557", error2);
|
|
@@ -90027,6 +89878,7 @@ var APIProvider = class {
|
|
|
90027
89878
|
}
|
|
90028
89879
|
async generateWithGoogle(apiKey, model, prompt, temperature, maxTokens, retryCount = 0) {
|
|
90029
89880
|
try {
|
|
89881
|
+
logger.info(`[APIProvider/Google] \u547C\u53EB API: model=${model}, promptLength=${prompt.length}, retry=${retryCount}`);
|
|
90030
89882
|
const genAI = new GoogleGenerativeAI(apiKey);
|
|
90031
89883
|
const generativeModel = genAI.getGenerativeModel({
|
|
90032
89884
|
model,
|
|
@@ -90062,10 +89914,13 @@ var APIProvider = class {
|
|
|
90062
89914
|
}
|
|
90063
89915
|
async generateWithOpenAI(apiKey, model, apiUrl, prompt, temperature, maxTokens, retryCount = 0) {
|
|
90064
89916
|
try {
|
|
89917
|
+
const baseURL = apiUrl || "https://api.openai.com/v1";
|
|
89918
|
+
logger.info(`[APIProvider/OpenAI] \u547C\u53EB API: baseURL=${baseURL}, model=${model}, promptLength=${prompt.length}, retry=${retryCount}`);
|
|
90065
89919
|
const OpenAI = (await import("openai")).default;
|
|
90066
89920
|
const client = new OpenAI({
|
|
90067
89921
|
apiKey,
|
|
90068
|
-
baseURL
|
|
89922
|
+
baseURL,
|
|
89923
|
+
timeout: 12e4
|
|
90069
89924
|
});
|
|
90070
89925
|
const response = await client.chat.completions.create({
|
|
90071
89926
|
model,
|
|
@@ -90073,6 +89928,7 @@ var APIProvider = class {
|
|
|
90073
89928
|
temperature: temperature ?? 0.7,
|
|
90074
89929
|
max_tokens: maxTokens ?? 1e3
|
|
90075
89930
|
});
|
|
89931
|
+
logger.info(`[APIProvider/OpenAI] API \u56DE\u61C9: choices=${response.choices?.length}, usage=${JSON.stringify(response.usage)}`);
|
|
90076
89932
|
const text = response.choices?.[0]?.message?.content;
|
|
90077
89933
|
if (!text) throw new Error("AI \u56DE\u8986\u70BA\u7A7A");
|
|
90078
89934
|
return text;
|
|
@@ -90099,12 +89955,6 @@ var APIProvider = class {
|
|
|
90099
89955
|
sleep(ms) {
|
|
90100
89956
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
90101
89957
|
}
|
|
90102
|
-
cleanExpiredCache() {
|
|
90103
|
-
const now = Date.now();
|
|
90104
|
-
for (const [key, entry] of cache2.entries()) {
|
|
90105
|
-
if (now - entry.timestamp > CACHE_TTL3) cache2.delete(key);
|
|
90106
|
-
}
|
|
90107
|
-
}
|
|
90108
89958
|
};
|
|
90109
89959
|
|
|
90110
89960
|
// src/utils/cli-provider.ts
|