@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/cli.cjs
CHANGED
|
@@ -47327,7 +47327,7 @@ var require_application = __commonJS({
|
|
|
47327
47327
|
};
|
|
47328
47328
|
app.del = deprecate.function(app.delete, "app.del: Use app.delete instead");
|
|
47329
47329
|
app.render = function render(name, options, callback) {
|
|
47330
|
-
var
|
|
47330
|
+
var cache2 = this.cache;
|
|
47331
47331
|
var done = callback;
|
|
47332
47332
|
var engines = this.engines;
|
|
47333
47333
|
var opts = options;
|
|
@@ -47346,7 +47346,7 @@ var require_application = __commonJS({
|
|
|
47346
47346
|
renderOptions.cache = this.enabled("view cache");
|
|
47347
47347
|
}
|
|
47348
47348
|
if (renderOptions.cache) {
|
|
47349
|
-
view =
|
|
47349
|
+
view = cache2[name];
|
|
47350
47350
|
}
|
|
47351
47351
|
if (!view) {
|
|
47352
47352
|
var View2 = this.get("view");
|
|
@@ -47362,7 +47362,7 @@ var require_application = __commonJS({
|
|
|
47362
47362
|
return done(err);
|
|
47363
47363
|
}
|
|
47364
47364
|
if (renderOptions.cache) {
|
|
47365
|
-
|
|
47365
|
+
cache2[name] = view;
|
|
47366
47366
|
}
|
|
47367
47367
|
}
|
|
47368
47368
|
tryRender(view, renderOptions, done);
|
|
@@ -78376,6 +78376,15 @@ var init_prompt_aggregator = __esm({
|
|
|
78376
78376
|
getComponentNames() {
|
|
78377
78377
|
return this.components.map((c) => c.getName());
|
|
78378
78378
|
}
|
|
78379
|
+
getPromptConfigsForDebug() {
|
|
78380
|
+
const configs = this.getPromptConfigsWithDefaults();
|
|
78381
|
+
return configs.map((c) => ({
|
|
78382
|
+
id: c.id,
|
|
78383
|
+
enabled: c.enabled,
|
|
78384
|
+
firstOrder: c.firstOrder,
|
|
78385
|
+
secondOrder: c.secondOrder
|
|
78386
|
+
}));
|
|
78387
|
+
}
|
|
78379
78388
|
getPromptConfigsWithDefaults() {
|
|
78380
78389
|
try {
|
|
78381
78390
|
const configs = getPromptConfigs();
|
|
@@ -78478,61 +78487,6 @@ function formatToolResults(results) {
|
|
|
78478
78487
|
}
|
|
78479
78488
|
return lines.join("\n");
|
|
78480
78489
|
}
|
|
78481
|
-
function buildToolsPrompt(tools, projectName, projectPath) {
|
|
78482
|
-
if (tools.length === 0) {
|
|
78483
|
-
return "";
|
|
78484
|
-
}
|
|
78485
|
-
const lines = [];
|
|
78486
|
-
if (projectName || projectPath) {
|
|
78487
|
-
lines.push("");
|
|
78488
|
-
lines.push("## \u5C08\u6848\u80CC\u666F\u8CC7\u8A0A");
|
|
78489
|
-
lines.push(`\u7576\u524D\u5C08\u6848: ${projectName || "\u672A\u547D\u540D\u5C08\u6848"}`);
|
|
78490
|
-
if (projectPath) {
|
|
78491
|
-
lines.push(`\u5C08\u6848\u8DEF\u5F91: ${projectPath}`);
|
|
78492
|
-
}
|
|
78493
|
-
lines.push("");
|
|
78494
|
-
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");
|
|
78495
|
-
lines.push("1. \u5C08\u6848\u7684\u67B6\u69CB\u548C\u7D50\u69CB\uFF08\u5982\u4F7F\u7528 get_symbols_overview, list_dir \u7B49\uFF09");
|
|
78496
|
-
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");
|
|
78497
|
-
lines.push("3. \u7576\u524D\u7684\u4EFB\u52D9\u548C\u9032\u5EA6");
|
|
78498
|
-
lines.push("");
|
|
78499
|
-
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");
|
|
78500
|
-
}
|
|
78501
|
-
lines.push("");
|
|
78502
|
-
lines.push("## MCP \u5DE5\u5177\u4F7F\u7528\u8AAA\u660E");
|
|
78503
|
-
lines.push("");
|
|
78504
|
-
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");
|
|
78505
|
-
lines.push("");
|
|
78506
|
-
lines.push("```json");
|
|
78507
|
-
lines.push("{");
|
|
78508
|
-
lines.push(' "tool_calls": [');
|
|
78509
|
-
lines.push(' { "name": "\u5DE5\u5177\u540D\u7A31", "arguments": { "\u53C3\u6578\u540D": "\u53C3\u6578\u503C" } }');
|
|
78510
|
-
lines.push(" ],");
|
|
78511
|
-
lines.push(' "message": "\u8AAA\u660E\u4F60\u6B63\u5728\u505A\u4EC0\u9EBC\uFF08\u53EF\u9078\uFF09"');
|
|
78512
|
-
lines.push("}");
|
|
78513
|
-
lines.push("```");
|
|
78514
|
-
lines.push("");
|
|
78515
|
-
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");
|
|
78516
|
-
lines.push("\u7576\u4F60\u4E0D\u9700\u8981\u8ABF\u7528\u5DE5\u5177\u6642\uFF0C\u76F4\u63A5\u4EE5\u7D14\u6587\u5B57\u56DE\u8986\u5373\u53EF\u3002");
|
|
78517
|
-
lines.push("");
|
|
78518
|
-
lines.push("## \u53EF\u7528\u5DE5\u5177\u5217\u8868");
|
|
78519
|
-
lines.push("");
|
|
78520
|
-
for (const tool of tools) {
|
|
78521
|
-
lines.push(`### ${tool.name}`);
|
|
78522
|
-
if (tool.description) {
|
|
78523
|
-
lines.push(tool.description);
|
|
78524
|
-
}
|
|
78525
|
-
if (tool.inputSchema) {
|
|
78526
|
-
lines.push("");
|
|
78527
|
-
lines.push("\u53C3\u6578\u683C\u5F0F:");
|
|
78528
|
-
lines.push("```json");
|
|
78529
|
-
lines.push(JSON.stringify(tool.inputSchema, null, 2));
|
|
78530
|
-
lines.push("```");
|
|
78531
|
-
}
|
|
78532
|
-
lines.push("");
|
|
78533
|
-
}
|
|
78534
|
-
return lines.join("\n");
|
|
78535
|
-
}
|
|
78536
78490
|
var init_mcp_tool_parser = __esm({
|
|
78537
78491
|
"src/utils/mcp-tool-parser.ts"() {
|
|
78538
78492
|
"use strict";
|
|
@@ -78885,131 +78839,91 @@ async function generateCLIReply(request, cliSettings) {
|
|
|
78885
78839
|
}
|
|
78886
78840
|
}
|
|
78887
78841
|
async function generateAPIReply(request) {
|
|
78842
|
+
const startTime = Date.now();
|
|
78888
78843
|
try {
|
|
78889
78844
|
const cacheKey = `${request.aiMessage}:${request.userContext || ""}`;
|
|
78890
78845
|
if (!request.toolResults) {
|
|
78891
78846
|
const cached2 = cache.get(cacheKey);
|
|
78892
78847
|
if (cached2 && Date.now() - cached2.timestamp < CACHE_TTL2) {
|
|
78893
78848
|
logger.debug("[AI Service] \u4F7F\u7528\u5FEB\u53D6\u56DE\u8986");
|
|
78894
|
-
return {
|
|
78895
|
-
success: true,
|
|
78896
|
-
reply: cached2.reply
|
|
78897
|
-
};
|
|
78849
|
+
return { success: true, reply: cached2.reply };
|
|
78898
78850
|
}
|
|
78899
78851
|
}
|
|
78900
78852
|
logger.debug("[AI Service] \u7372\u53D6 AI \u8A2D\u5B9A");
|
|
78901
78853
|
const settings = getAISettings();
|
|
78902
|
-
logger.debug("[AI Service] AI \u8A2D\u5B9A\u7372\u53D6\u5B8C\u6210", {
|
|
78903
|
-
hasApiKey: !!settings?.apiKey,
|
|
78904
|
-
model: settings?.model,
|
|
78905
|
-
hasMcpToolsPrompt: !!settings?.mcpToolsPrompt
|
|
78906
|
-
});
|
|
78907
78854
|
if (!settings || !settings.apiKey || settings.apiKey === "YOUR_API_KEY_HERE") {
|
|
78908
78855
|
logger.warn("[AI Service] API Key \u672A\u8A2D\u5B9A\u6216\u7121\u6548");
|
|
78909
|
-
return {
|
|
78910
|
-
success: false,
|
|
78911
|
-
error: "\u8ACB\u5148\u5728\u8A2D\u5B9A\u4E2D\u914D\u7F6E AI API Key"
|
|
78912
|
-
};
|
|
78856
|
+
return { success: false, error: "\u8ACB\u5148\u5728\u8A2D\u5B9A\u4E2D\u914D\u7F6E AI API Key" };
|
|
78913
78857
|
}
|
|
78914
|
-
|
|
78858
|
+
const aggregator = getPromptAggregator();
|
|
78859
|
+
const cliSettings = getCLISettings();
|
|
78860
|
+
let mcpTools = [];
|
|
78915
78861
|
if (request.includeMCPTools) {
|
|
78916
|
-
logger.debug("[AI Service] \u958B\u59CB\u7372\u53D6 MCP \u5DE5\u5177");
|
|
78917
78862
|
try {
|
|
78918
78863
|
const allTools = mcpClientManager.getAllTools();
|
|
78919
|
-
|
|
78920
|
-
|
|
78921
|
-
|
|
78922
|
-
|
|
78923
|
-
|
|
78924
|
-
|
|
78925
|
-
|
|
78926
|
-
logger.debug("[AI Service] \u9644\u52A0\u5DE5\u5177\u5217\u8868\u5230\u63D0\u793A\u8A5E");
|
|
78927
|
-
mcpToolsPrompt += "\n\n## \u53EF\u7528\u5DE5\u5177\u5217\u8868\n\n";
|
|
78928
|
-
for (const tool of allTools) {
|
|
78929
|
-
mcpToolsPrompt += `### ${tool.name}
|
|
78930
|
-
`;
|
|
78931
|
-
if (tool.description) {
|
|
78932
|
-
mcpToolsPrompt += `${tool.description}
|
|
78933
|
-
`;
|
|
78934
|
-
}
|
|
78935
|
-
if (tool.inputSchema) {
|
|
78936
|
-
mcpToolsPrompt += "\n\u53C3\u6578\u683C\u5F0F:\n```json\n";
|
|
78937
|
-
mcpToolsPrompt += JSON.stringify(tool.inputSchema, null, 2);
|
|
78938
|
-
mcpToolsPrompt += "\n```\n";
|
|
78939
|
-
}
|
|
78940
|
-
mcpToolsPrompt += "\n";
|
|
78941
|
-
}
|
|
78942
|
-
}
|
|
78943
|
-
} else {
|
|
78944
|
-
logger.debug("[AI Service] \u4F7F\u7528\u9810\u8A2D\u7684 buildToolsPrompt");
|
|
78945
|
-
mcpToolsPrompt = buildToolsPrompt(allTools, request.projectName, request.projectPath);
|
|
78946
|
-
}
|
|
78947
|
-
} catch (error2) {
|
|
78948
|
-
logger.warn("[AI Service] Failed to get MCP tools for AI prompt", error2);
|
|
78864
|
+
mcpTools = allTools.map((t) => ({
|
|
78865
|
+
name: t.name,
|
|
78866
|
+
description: t.description,
|
|
78867
|
+
inputSchema: t.inputSchema
|
|
78868
|
+
}));
|
|
78869
|
+
} catch {
|
|
78870
|
+
logger.warn("[AI Service] \u7121\u6CD5\u7372\u53D6 MCP \u5DE5\u5177");
|
|
78949
78871
|
}
|
|
78950
78872
|
}
|
|
78951
|
-
|
|
78952
|
-
|
|
78953
|
-
|
|
78954
|
-
|
|
78955
|
-
|
|
78873
|
+
const context = aggregator.buildContextSync(request, settings, cliSettings, mcpTools);
|
|
78874
|
+
context.mode = "api";
|
|
78875
|
+
const aggregated = aggregator.aggregate(context);
|
|
78876
|
+
const promptSent = aggregated.fullPrompt;
|
|
78877
|
+
logger.debug("[AI Service] PromptAggregator \u69CB\u5EFA\u5B8C\u6210", {
|
|
78878
|
+
componentCount: aggregated.sections.length,
|
|
78879
|
+
sections: aggregated.sections.map((s) => `${s.name}(order:${s.order})`),
|
|
78880
|
+
totalLength: promptSent.length,
|
|
78881
|
+
tokenEstimate: aggregated.metadata.tokenEstimate
|
|
78956
78882
|
});
|
|
78957
|
-
const
|
|
78958
|
-
settings.systemPrompt,
|
|
78959
|
-
request.aiMessage,
|
|
78960
|
-
request.userContext,
|
|
78961
|
-
mcpToolsPrompt,
|
|
78962
|
-
request.toolResults
|
|
78963
|
-
);
|
|
78964
|
-
const reply = await generateWithRetry(
|
|
78883
|
+
const reply = await generateWithRetryFromPrompt(
|
|
78965
78884
|
settings.apiKey,
|
|
78966
78885
|
settings.model,
|
|
78967
|
-
|
|
78968
|
-
request.aiMessage,
|
|
78969
|
-
request.userContext,
|
|
78886
|
+
promptSent,
|
|
78970
78887
|
settings.temperature,
|
|
78971
|
-
settings.maxTokens
|
|
78972
|
-
0,
|
|
78973
|
-
mcpToolsPrompt,
|
|
78974
|
-
request.toolResults
|
|
78888
|
+
settings.maxTokens
|
|
78975
78889
|
);
|
|
78976
|
-
|
|
78977
|
-
replyLength: reply.length
|
|
78978
|
-
});
|
|
78890
|
+
const elapsedMs = Date.now() - startTime;
|
|
78979
78891
|
if (!request.toolResults) {
|
|
78980
|
-
cache.set(cacheKey, {
|
|
78981
|
-
reply,
|
|
78982
|
-
timestamp: Date.now()
|
|
78983
|
-
});
|
|
78892
|
+
cache.set(cacheKey, { reply, timestamp: Date.now() });
|
|
78984
78893
|
cleanExpiredCache();
|
|
78985
78894
|
}
|
|
78986
|
-
|
|
78895
|
+
const promptConfigs = aggregator.getPromptConfigsForDebug();
|
|
78987
78896
|
return {
|
|
78988
78897
|
success: true,
|
|
78989
78898
|
reply,
|
|
78990
78899
|
promptSent,
|
|
78991
|
-
mode: "api"
|
|
78900
|
+
mode: "api",
|
|
78901
|
+
debug: {
|
|
78902
|
+
sections: aggregated.sections.map((s) => ({ name: s.name, order: s.order, length: s.content.length })),
|
|
78903
|
+
tokenEstimate: aggregated.metadata.tokenEstimate,
|
|
78904
|
+
totalPromptLength: promptSent.length,
|
|
78905
|
+
elapsedMs,
|
|
78906
|
+
model: settings.model,
|
|
78907
|
+
temperature: settings.temperature,
|
|
78908
|
+
maxTokens: settings.maxTokens,
|
|
78909
|
+
mcpToolsCount: mcpTools.length,
|
|
78910
|
+
componentCount: aggregated.sections.length,
|
|
78911
|
+
promptConfigs
|
|
78912
|
+
}
|
|
78992
78913
|
};
|
|
78993
78914
|
} catch (error2) {
|
|
78915
|
+
const elapsedMs = Date.now() - startTime;
|
|
78994
78916
|
logger.error("[AI Service] AI service error:", error2);
|
|
78995
78917
|
return {
|
|
78996
78918
|
success: false,
|
|
78997
78919
|
error: error2 instanceof Error ? error2.message : "\u672A\u77E5\u932F\u8AA4",
|
|
78998
|
-
mode: "api"
|
|
78920
|
+
mode: "api",
|
|
78921
|
+
debug: { elapsedMs }
|
|
78999
78922
|
};
|
|
79000
78923
|
}
|
|
79001
78924
|
}
|
|
79002
|
-
async function
|
|
78925
|
+
async function generateWithRetryFromPrompt(apiKey, model, prompt, temperature, maxTokens, retryCount = 0) {
|
|
79003
78926
|
try {
|
|
79004
|
-
logger.debug("[AI Service] generateWithRetry \u958B\u59CB", {
|
|
79005
|
-
model,
|
|
79006
|
-
retryCount,
|
|
79007
|
-
hasSystemPrompt: !!systemPrompt,
|
|
79008
|
-
hasMcpToolsPrompt: !!mcpToolsPrompt,
|
|
79009
|
-
hasToolResults: !!toolResults,
|
|
79010
|
-
temperature,
|
|
79011
|
-
maxTokens
|
|
79012
|
-
});
|
|
79013
78927
|
const genAI = new GoogleGenerativeAI(apiKey);
|
|
79014
78928
|
const generativeModel = genAI.getGenerativeModel({
|
|
79015
78929
|
model,
|
|
@@ -79018,45 +78932,20 @@ async function generateWithRetry(apiKey, model, systemPrompt, aiMessage, userCon
|
|
|
79018
78932
|
maxOutputTokens: maxTokens ?? 1e3
|
|
79019
78933
|
}
|
|
79020
78934
|
});
|
|
79021
|
-
logger.debug("[AI Service] \
|
|
79022
|
-
const prompt = buildPrompt(systemPrompt, aiMessage, userContext, mcpToolsPrompt, toolResults);
|
|
79023
|
-
logger.debug("[AI Service] \u63D0\u793A\u8A5E\u69CB\u5EFA\u5B8C\u6210", {
|
|
79024
|
-
promptLength: prompt.length
|
|
79025
|
-
});
|
|
79026
|
-
logger.debug("[AI Service] \u958B\u59CB\u8ABF\u7528 Google Gemini API");
|
|
78935
|
+
logger.debug("[AI Service] \u958B\u59CB\u8ABF\u7528 API (PromptAggregator prompt)", { promptLength: prompt.length });
|
|
79027
78936
|
const result = await generativeModel.generateContent(prompt);
|
|
79028
|
-
logger.debug("[AI Service] API \u8ABF\u7528\u5B8C\u6210");
|
|
79029
78937
|
const response = await result.response;
|
|
79030
78938
|
const text = response.text();
|
|
79031
78939
|
if (!text) {
|
|
79032
78940
|
throw new Error("AI \u56DE\u8986\u70BA\u7A7A");
|
|
79033
78941
|
}
|
|
79034
|
-
logger.debug("[AI Service] \u56DE\u8986\u6587\u5B57\u7372\u53D6\u6210\u529F", {
|
|
79035
|
-
textLength: text.length
|
|
79036
|
-
});
|
|
79037
78942
|
return text;
|
|
79038
78943
|
} catch (error2) {
|
|
79039
|
-
logger.debug("[AI Service] generateWithRetry \u767C\u751F\u932F\u8AA4", {
|
|
79040
|
-
error: error2 instanceof Error ? error2.message : String(error2),
|
|
79041
|
-
retryCount
|
|
79042
|
-
});
|
|
79043
78944
|
if (error2 instanceof Error) {
|
|
79044
78945
|
if (error2.message.includes("429") || error2.message.includes("quota")) {
|
|
79045
78946
|
if (retryCount < MAX_RETRIES) {
|
|
79046
|
-
|
|
79047
|
-
|
|
79048
|
-
return generateWithRetry(
|
|
79049
|
-
apiKey,
|
|
79050
|
-
model,
|
|
79051
|
-
systemPrompt,
|
|
79052
|
-
aiMessage,
|
|
79053
|
-
userContext,
|
|
79054
|
-
temperature,
|
|
79055
|
-
maxTokens,
|
|
79056
|
-
retryCount + 1,
|
|
79057
|
-
mcpToolsPrompt,
|
|
79058
|
-
toolResults
|
|
79059
|
-
);
|
|
78947
|
+
await sleep(RETRY_DELAYS[retryCount] || 4e3);
|
|
78948
|
+
return generateWithRetryFromPrompt(apiKey, model, prompt, temperature, maxTokens, retryCount + 1);
|
|
79060
78949
|
}
|
|
79061
78950
|
throw new Error("API \u914D\u984D\u5DF2\u7528\u76E1\u6216\u901F\u7387\u9650\u5236\uFF0C\u8ACB\u7A0D\u5F8C\u518D\u8A66");
|
|
79062
78951
|
}
|
|
@@ -79064,51 +78953,13 @@ async function generateWithRetry(apiKey, model, systemPrompt, aiMessage, userCon
|
|
|
79064
78953
|
throw new Error("API Key \u7121\u6548\uFF0C\u8ACB\u6AA2\u67E5\u8A2D\u5B9A");
|
|
79065
78954
|
}
|
|
79066
78955
|
if (retryCount < MAX_RETRIES) {
|
|
79067
|
-
|
|
79068
|
-
|
|
79069
|
-
return generateWithRetry(
|
|
79070
|
-
apiKey,
|
|
79071
|
-
model,
|
|
79072
|
-
systemPrompt,
|
|
79073
|
-
aiMessage,
|
|
79074
|
-
userContext,
|
|
79075
|
-
temperature,
|
|
79076
|
-
maxTokens,
|
|
79077
|
-
retryCount + 1,
|
|
79078
|
-
mcpToolsPrompt,
|
|
79079
|
-
toolResults
|
|
79080
|
-
);
|
|
78956
|
+
await sleep(RETRY_DELAYS[retryCount] || 4e3);
|
|
78957
|
+
return generateWithRetryFromPrompt(apiKey, model, prompt, temperature, maxTokens, retryCount + 1);
|
|
79081
78958
|
}
|
|
79082
78959
|
}
|
|
79083
78960
|
throw error2;
|
|
79084
78961
|
}
|
|
79085
78962
|
}
|
|
79086
|
-
function buildPrompt(systemPrompt, aiMessage, userContext, mcpToolsPrompt = "", toolResults) {
|
|
79087
|
-
let prompt = `${systemPrompt}
|
|
79088
|
-
|
|
79089
|
-
`;
|
|
79090
|
-
if (mcpToolsPrompt) {
|
|
79091
|
-
prompt += mcpToolsPrompt + "\n\n";
|
|
79092
|
-
}
|
|
79093
|
-
prompt += `AI \u5DE5\u4F5C\u532F\u5831\uFF1A
|
|
79094
|
-
${aiMessage}
|
|
79095
|
-
|
|
79096
|
-
`;
|
|
79097
|
-
if (userContext) {
|
|
79098
|
-
prompt += `\u4F7F\u7528\u8005\u4E0A\u4E0B\u6587\uFF1A
|
|
79099
|
-
${userContext}
|
|
79100
|
-
|
|
79101
|
-
`;
|
|
79102
|
-
}
|
|
79103
|
-
if (toolResults) {
|
|
79104
|
-
prompt += `\u5148\u524D\u5DE5\u5177\u57F7\u884C\u7D50\u679C\uFF1A
|
|
79105
|
-
${toolResults}
|
|
79106
|
-
|
|
79107
|
-
`;
|
|
79108
|
-
}
|
|
79109
|
-
prompt += "\u8ACB\u751F\u6210\u4E00\u500B\u7C21\u6F54\u3001\u5C08\u696D\u7684\u56DE\u61C9\uFF1A";
|
|
79110
|
-
return prompt;
|
|
79111
|
-
}
|
|
79112
78963
|
function sleep(ms) {
|
|
79113
78964
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
79114
78965
|
}
|
|
@@ -79208,7 +79059,6 @@ var init_ai_service = __esm({
|
|
|
79208
79059
|
init_cli_executor();
|
|
79209
79060
|
init_cli_detector();
|
|
79210
79061
|
init_prompt_aggregator2();
|
|
79211
|
-
init_mcp_tool_parser();
|
|
79212
79062
|
MAX_RETRIES = 3;
|
|
79213
79063
|
RETRY_DELAYS = [1e3, 2e3, 4e3];
|
|
79214
79064
|
cache = /* @__PURE__ */ new Map();
|
|
@@ -92921,8 +92771,6 @@ init_mcp_client_manager();
|
|
|
92921
92771
|
init_prompt_aggregator2();
|
|
92922
92772
|
var MAX_RETRIES2 = 3;
|
|
92923
92773
|
var RETRY_DELAYS2 = [1e3, 2e3, 4e3];
|
|
92924
|
-
var cache2 = /* @__PURE__ */ new Map();
|
|
92925
|
-
var CACHE_TTL3 = 5 * 60 * 1e3;
|
|
92926
92774
|
function getProviderFromUrl2(apiUrl) {
|
|
92927
92775
|
if (!apiUrl) return "google";
|
|
92928
92776
|
const normalizedUrl = apiUrl.toLowerCase();
|
|
@@ -92946,15 +92794,17 @@ var APIProvider = class {
|
|
|
92946
92794
|
}
|
|
92947
92795
|
async generateReply(request) {
|
|
92948
92796
|
try {
|
|
92949
|
-
const cacheKey = `${request.aiMessage}:${request.userContext || ""}`;
|
|
92950
|
-
if (!request.toolResults) {
|
|
92951
|
-
const cached2 = cache2.get(cacheKey);
|
|
92952
|
-
if (cached2 && Date.now() - cached2.timestamp < CACHE_TTL3) {
|
|
92953
|
-
logger.debug("[APIProvider] \u4F7F\u7528\u5FEB\u53D6\u56DE\u8986");
|
|
92954
|
-
return { success: true, reply: cached2.reply, mode: "api" };
|
|
92955
|
-
}
|
|
92956
|
-
}
|
|
92957
92797
|
const settings = getAISettings();
|
|
92798
|
+
logger.info("[APIProvider] AI \u8A2D\u5B9A\u72C0\u614B", {
|
|
92799
|
+
hasSettings: !!settings,
|
|
92800
|
+
hasApiKey: !!settings?.apiKey,
|
|
92801
|
+
apiKeyLength: settings?.apiKey?.length,
|
|
92802
|
+
apiKeyPrefix: settings?.apiKey?.substring(0, 6),
|
|
92803
|
+
model: settings?.model,
|
|
92804
|
+
apiUrl: settings?.apiUrl || "(\u672A\u8A2D\u5B9A)",
|
|
92805
|
+
temperature: settings?.temperature,
|
|
92806
|
+
maxTokens: settings?.maxTokens
|
|
92807
|
+
});
|
|
92958
92808
|
if (!settings || !settings.apiKey || settings.apiKey === "YOUR_API_KEY_HERE") {
|
|
92959
92809
|
logger.warn("[APIProvider] API Key \u672A\u8A2D\u5B9A\u6216\u7121\u6548");
|
|
92960
92810
|
return { success: false, error: "\u8ACB\u5148\u5728\u8A2D\u5B9A\u4E2D\u914D\u7F6E AI API Key", mode: "api" };
|
|
@@ -92978,10 +92828,13 @@ var APIProvider = class {
|
|
|
92978
92828
|
context.mode = "api";
|
|
92979
92829
|
const aggregated = aggregator.aggregate(context);
|
|
92980
92830
|
const promptSent = aggregated.fullPrompt;
|
|
92831
|
+
logger.info(`[APIProvider] Prompt \u5DF2\u5EFA\u69CB, \u9577\u5EA6: ${promptSent.length}`);
|
|
92981
92832
|
const provider = getProviderFromUrl2(settings.apiUrl);
|
|
92982
|
-
logger.info(`[APIProvider] \u4F7F\u7528 ${provider} \u63D0\u4F9B\u5546, apiUrl: ${settings.apiUrl || "(\u9810\u8A2D)"}`);
|
|
92833
|
+
logger.info(`[APIProvider] \u4F7F\u7528 ${provider} \u63D0\u4F9B\u5546, apiUrl: ${settings.apiUrl || "(\u9810\u8A2D)"}, model: ${settings.model}`);
|
|
92834
|
+
const startTime = Date.now();
|
|
92983
92835
|
let reply;
|
|
92984
92836
|
if (provider !== "google") {
|
|
92837
|
+
logger.info(`[APIProvider] \u958B\u59CB\u547C\u53EB OpenAI \u76F8\u5BB9 API...`);
|
|
92985
92838
|
reply = await this.generateWithOpenAI(
|
|
92986
92839
|
settings.apiKey,
|
|
92987
92840
|
settings.model,
|
|
@@ -92991,6 +92844,7 @@ var APIProvider = class {
|
|
|
92991
92844
|
settings.maxTokens
|
|
92992
92845
|
);
|
|
92993
92846
|
} else {
|
|
92847
|
+
logger.info(`[APIProvider] \u958B\u59CB\u547C\u53EB Google Gemini API...`);
|
|
92994
92848
|
reply = await this.generateWithGoogle(
|
|
92995
92849
|
settings.apiKey,
|
|
92996
92850
|
settings.model,
|
|
@@ -92999,10 +92853,7 @@ var APIProvider = class {
|
|
|
92999
92853
|
settings.maxTokens
|
|
93000
92854
|
);
|
|
93001
92855
|
}
|
|
93002
|
-
|
|
93003
|
-
cache2.set(cacheKey, { reply, timestamp: Date.now() });
|
|
93004
|
-
this.cleanExpiredCache();
|
|
93005
|
-
}
|
|
92856
|
+
logger.info(`[APIProvider] API \u547C\u53EB\u5B8C\u6210, \u8017\u6642: ${Date.now() - startTime}ms, \u56DE\u8986\u9577\u5EA6: ${reply.length}`);
|
|
93006
92857
|
return { success: true, reply, promptSent, mode: "api" };
|
|
93007
92858
|
} catch (error2) {
|
|
93008
92859
|
logger.error("[APIProvider] \u751F\u6210\u56DE\u8986\u5931\u6557", error2);
|
|
@@ -93015,6 +92866,7 @@ var APIProvider = class {
|
|
|
93015
92866
|
}
|
|
93016
92867
|
async generateWithGoogle(apiKey, model, prompt, temperature, maxTokens, retryCount = 0) {
|
|
93017
92868
|
try {
|
|
92869
|
+
logger.info(`[APIProvider/Google] \u547C\u53EB API: model=${model}, promptLength=${prompt.length}, retry=${retryCount}`);
|
|
93018
92870
|
const genAI = new GoogleGenerativeAI(apiKey);
|
|
93019
92871
|
const generativeModel = genAI.getGenerativeModel({
|
|
93020
92872
|
model,
|
|
@@ -93050,10 +92902,13 @@ var APIProvider = class {
|
|
|
93050
92902
|
}
|
|
93051
92903
|
async generateWithOpenAI(apiKey, model, apiUrl, prompt, temperature, maxTokens, retryCount = 0) {
|
|
93052
92904
|
try {
|
|
92905
|
+
const baseURL = apiUrl || "https://api.openai.com/v1";
|
|
92906
|
+
logger.info(`[APIProvider/OpenAI] \u547C\u53EB API: baseURL=${baseURL}, model=${model}, promptLength=${prompt.length}, retry=${retryCount}`);
|
|
93053
92907
|
const OpenAI = (await import("openai")).default;
|
|
93054
92908
|
const client = new OpenAI({
|
|
93055
92909
|
apiKey,
|
|
93056
|
-
baseURL
|
|
92910
|
+
baseURL,
|
|
92911
|
+
timeout: 12e4
|
|
93057
92912
|
});
|
|
93058
92913
|
const response = await client.chat.completions.create({
|
|
93059
92914
|
model,
|
|
@@ -93061,6 +92916,7 @@ var APIProvider = class {
|
|
|
93061
92916
|
temperature: temperature ?? 0.7,
|
|
93062
92917
|
max_tokens: maxTokens ?? 1e3
|
|
93063
92918
|
});
|
|
92919
|
+
logger.info(`[APIProvider/OpenAI] API \u56DE\u61C9: choices=${response.choices?.length}, usage=${JSON.stringify(response.usage)}`);
|
|
93064
92920
|
const text = response.choices?.[0]?.message?.content;
|
|
93065
92921
|
if (!text) throw new Error("AI \u56DE\u8986\u70BA\u7A7A");
|
|
93066
92922
|
return text;
|
|
@@ -93087,12 +92943,6 @@ var APIProvider = class {
|
|
|
93087
92943
|
sleep(ms) {
|
|
93088
92944
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
93089
92945
|
}
|
|
93090
|
-
cleanExpiredCache() {
|
|
93091
|
-
const now = Date.now();
|
|
93092
|
-
for (const [key, entry] of cache2.entries()) {
|
|
93093
|
-
if (now - entry.timestamp > CACHE_TTL3) cache2.delete(key);
|
|
93094
|
-
}
|
|
93095
|
-
}
|
|
93096
92946
|
};
|
|
93097
92947
|
|
|
93098
92948
|
// src/utils/cli-provider.ts
|