@hirohsu/user-web-feedback 2.8.17 → 2.8.18
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 +25 -25
- package/dist/index.cjs +25 -25
- package/dist/static/modules/timer-controller.js +6 -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);
|
|
@@ -92921,8 +92921,6 @@ init_mcp_client_manager();
|
|
|
92921
92921
|
init_prompt_aggregator2();
|
|
92922
92922
|
var MAX_RETRIES2 = 3;
|
|
92923
92923
|
var RETRY_DELAYS2 = [1e3, 2e3, 4e3];
|
|
92924
|
-
var cache2 = /* @__PURE__ */ new Map();
|
|
92925
|
-
var CACHE_TTL3 = 5 * 60 * 1e3;
|
|
92926
92924
|
function getProviderFromUrl2(apiUrl) {
|
|
92927
92925
|
if (!apiUrl) return "google";
|
|
92928
92926
|
const normalizedUrl = apiUrl.toLowerCase();
|
|
@@ -92946,15 +92944,17 @@ var APIProvider = class {
|
|
|
92946
92944
|
}
|
|
92947
92945
|
async generateReply(request) {
|
|
92948
92946
|
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
92947
|
const settings = getAISettings();
|
|
92948
|
+
logger.info("[APIProvider] AI \u8A2D\u5B9A\u72C0\u614B", {
|
|
92949
|
+
hasSettings: !!settings,
|
|
92950
|
+
hasApiKey: !!settings?.apiKey,
|
|
92951
|
+
apiKeyLength: settings?.apiKey?.length,
|
|
92952
|
+
apiKeyPrefix: settings?.apiKey?.substring(0, 6),
|
|
92953
|
+
model: settings?.model,
|
|
92954
|
+
apiUrl: settings?.apiUrl || "(\u672A\u8A2D\u5B9A)",
|
|
92955
|
+
temperature: settings?.temperature,
|
|
92956
|
+
maxTokens: settings?.maxTokens
|
|
92957
|
+
});
|
|
92958
92958
|
if (!settings || !settings.apiKey || settings.apiKey === "YOUR_API_KEY_HERE") {
|
|
92959
92959
|
logger.warn("[APIProvider] API Key \u672A\u8A2D\u5B9A\u6216\u7121\u6548");
|
|
92960
92960
|
return { success: false, error: "\u8ACB\u5148\u5728\u8A2D\u5B9A\u4E2D\u914D\u7F6E AI API Key", mode: "api" };
|
|
@@ -92978,10 +92978,13 @@ var APIProvider = class {
|
|
|
92978
92978
|
context.mode = "api";
|
|
92979
92979
|
const aggregated = aggregator.aggregate(context);
|
|
92980
92980
|
const promptSent = aggregated.fullPrompt;
|
|
92981
|
+
logger.info(`[APIProvider] Prompt \u5DF2\u5EFA\u69CB, \u9577\u5EA6: ${promptSent.length}`);
|
|
92981
92982
|
const provider = getProviderFromUrl2(settings.apiUrl);
|
|
92982
|
-
logger.info(`[APIProvider] \u4F7F\u7528 ${provider} \u63D0\u4F9B\u5546, apiUrl: ${settings.apiUrl || "(\u9810\u8A2D)"}`);
|
|
92983
|
+
logger.info(`[APIProvider] \u4F7F\u7528 ${provider} \u63D0\u4F9B\u5546, apiUrl: ${settings.apiUrl || "(\u9810\u8A2D)"}, model: ${settings.model}`);
|
|
92984
|
+
const startTime = Date.now();
|
|
92983
92985
|
let reply;
|
|
92984
92986
|
if (provider !== "google") {
|
|
92987
|
+
logger.info(`[APIProvider] \u958B\u59CB\u547C\u53EB OpenAI \u76F8\u5BB9 API...`);
|
|
92985
92988
|
reply = await this.generateWithOpenAI(
|
|
92986
92989
|
settings.apiKey,
|
|
92987
92990
|
settings.model,
|
|
@@ -92991,6 +92994,7 @@ var APIProvider = class {
|
|
|
92991
92994
|
settings.maxTokens
|
|
92992
92995
|
);
|
|
92993
92996
|
} else {
|
|
92997
|
+
logger.info(`[APIProvider] \u958B\u59CB\u547C\u53EB Google Gemini API...`);
|
|
92994
92998
|
reply = await this.generateWithGoogle(
|
|
92995
92999
|
settings.apiKey,
|
|
92996
93000
|
settings.model,
|
|
@@ -92999,10 +93003,7 @@ var APIProvider = class {
|
|
|
92999
93003
|
settings.maxTokens
|
|
93000
93004
|
);
|
|
93001
93005
|
}
|
|
93002
|
-
|
|
93003
|
-
cache2.set(cacheKey, { reply, timestamp: Date.now() });
|
|
93004
|
-
this.cleanExpiredCache();
|
|
93005
|
-
}
|
|
93006
|
+
logger.info(`[APIProvider] API \u547C\u53EB\u5B8C\u6210, \u8017\u6642: ${Date.now() - startTime}ms, \u56DE\u8986\u9577\u5EA6: ${reply.length}`);
|
|
93006
93007
|
return { success: true, reply, promptSent, mode: "api" };
|
|
93007
93008
|
} catch (error2) {
|
|
93008
93009
|
logger.error("[APIProvider] \u751F\u6210\u56DE\u8986\u5931\u6557", error2);
|
|
@@ -93015,6 +93016,7 @@ var APIProvider = class {
|
|
|
93015
93016
|
}
|
|
93016
93017
|
async generateWithGoogle(apiKey, model, prompt, temperature, maxTokens, retryCount = 0) {
|
|
93017
93018
|
try {
|
|
93019
|
+
logger.info(`[APIProvider/Google] \u547C\u53EB API: model=${model}, promptLength=${prompt.length}, retry=${retryCount}`);
|
|
93018
93020
|
const genAI = new GoogleGenerativeAI(apiKey);
|
|
93019
93021
|
const generativeModel = genAI.getGenerativeModel({
|
|
93020
93022
|
model,
|
|
@@ -93050,10 +93052,13 @@ var APIProvider = class {
|
|
|
93050
93052
|
}
|
|
93051
93053
|
async generateWithOpenAI(apiKey, model, apiUrl, prompt, temperature, maxTokens, retryCount = 0) {
|
|
93052
93054
|
try {
|
|
93055
|
+
const baseURL = apiUrl || "https://api.openai.com/v1";
|
|
93056
|
+
logger.info(`[APIProvider/OpenAI] \u547C\u53EB API: baseURL=${baseURL}, model=${model}, promptLength=${prompt.length}, retry=${retryCount}`);
|
|
93053
93057
|
const OpenAI = (await import("openai")).default;
|
|
93054
93058
|
const client = new OpenAI({
|
|
93055
93059
|
apiKey,
|
|
93056
|
-
baseURL
|
|
93060
|
+
baseURL,
|
|
93061
|
+
timeout: 12e4
|
|
93057
93062
|
});
|
|
93058
93063
|
const response = await client.chat.completions.create({
|
|
93059
93064
|
model,
|
|
@@ -93061,6 +93066,7 @@ var APIProvider = class {
|
|
|
93061
93066
|
temperature: temperature ?? 0.7,
|
|
93062
93067
|
max_tokens: maxTokens ?? 1e3
|
|
93063
93068
|
});
|
|
93069
|
+
logger.info(`[APIProvider/OpenAI] API \u56DE\u61C9: choices=${response.choices?.length}, usage=${JSON.stringify(response.usage)}`);
|
|
93064
93070
|
const text = response.choices?.[0]?.message?.content;
|
|
93065
93071
|
if (!text) throw new Error("AI \u56DE\u8986\u70BA\u7A7A");
|
|
93066
93072
|
return text;
|
|
@@ -93087,12 +93093,6 @@ var APIProvider = class {
|
|
|
93087
93093
|
sleep(ms) {
|
|
93088
93094
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
93089
93095
|
}
|
|
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
93096
|
};
|
|
93097
93097
|
|
|
93098
93098
|
// src/utils/cli-provider.ts
|
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);
|
|
@@ -89933,8 +89933,6 @@ init_mcp_client_manager();
|
|
|
89933
89933
|
init_prompt_aggregator2();
|
|
89934
89934
|
var MAX_RETRIES2 = 3;
|
|
89935
89935
|
var RETRY_DELAYS2 = [1e3, 2e3, 4e3];
|
|
89936
|
-
var cache2 = /* @__PURE__ */ new Map();
|
|
89937
|
-
var CACHE_TTL3 = 5 * 60 * 1e3;
|
|
89938
89936
|
function getProviderFromUrl2(apiUrl) {
|
|
89939
89937
|
if (!apiUrl) return "google";
|
|
89940
89938
|
const normalizedUrl = apiUrl.toLowerCase();
|
|
@@ -89958,15 +89956,17 @@ var APIProvider = class {
|
|
|
89958
89956
|
}
|
|
89959
89957
|
async generateReply(request) {
|
|
89960
89958
|
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
89959
|
const settings = getAISettings();
|
|
89960
|
+
logger.info("[APIProvider] AI \u8A2D\u5B9A\u72C0\u614B", {
|
|
89961
|
+
hasSettings: !!settings,
|
|
89962
|
+
hasApiKey: !!settings?.apiKey,
|
|
89963
|
+
apiKeyLength: settings?.apiKey?.length,
|
|
89964
|
+
apiKeyPrefix: settings?.apiKey?.substring(0, 6),
|
|
89965
|
+
model: settings?.model,
|
|
89966
|
+
apiUrl: settings?.apiUrl || "(\u672A\u8A2D\u5B9A)",
|
|
89967
|
+
temperature: settings?.temperature,
|
|
89968
|
+
maxTokens: settings?.maxTokens
|
|
89969
|
+
});
|
|
89970
89970
|
if (!settings || !settings.apiKey || settings.apiKey === "YOUR_API_KEY_HERE") {
|
|
89971
89971
|
logger.warn("[APIProvider] API Key \u672A\u8A2D\u5B9A\u6216\u7121\u6548");
|
|
89972
89972
|
return { success: false, error: "\u8ACB\u5148\u5728\u8A2D\u5B9A\u4E2D\u914D\u7F6E AI API Key", mode: "api" };
|
|
@@ -89990,10 +89990,13 @@ var APIProvider = class {
|
|
|
89990
89990
|
context.mode = "api";
|
|
89991
89991
|
const aggregated = aggregator.aggregate(context);
|
|
89992
89992
|
const promptSent = aggregated.fullPrompt;
|
|
89993
|
+
logger.info(`[APIProvider] Prompt \u5DF2\u5EFA\u69CB, \u9577\u5EA6: ${promptSent.length}`);
|
|
89993
89994
|
const provider = getProviderFromUrl2(settings.apiUrl);
|
|
89994
|
-
logger.info(`[APIProvider] \u4F7F\u7528 ${provider} \u63D0\u4F9B\u5546, apiUrl: ${settings.apiUrl || "(\u9810\u8A2D)"}`);
|
|
89995
|
+
logger.info(`[APIProvider] \u4F7F\u7528 ${provider} \u63D0\u4F9B\u5546, apiUrl: ${settings.apiUrl || "(\u9810\u8A2D)"}, model: ${settings.model}`);
|
|
89996
|
+
const startTime = Date.now();
|
|
89995
89997
|
let reply;
|
|
89996
89998
|
if (provider !== "google") {
|
|
89999
|
+
logger.info(`[APIProvider] \u958B\u59CB\u547C\u53EB OpenAI \u76F8\u5BB9 API...`);
|
|
89997
90000
|
reply = await this.generateWithOpenAI(
|
|
89998
90001
|
settings.apiKey,
|
|
89999
90002
|
settings.model,
|
|
@@ -90003,6 +90006,7 @@ var APIProvider = class {
|
|
|
90003
90006
|
settings.maxTokens
|
|
90004
90007
|
);
|
|
90005
90008
|
} else {
|
|
90009
|
+
logger.info(`[APIProvider] \u958B\u59CB\u547C\u53EB Google Gemini API...`);
|
|
90006
90010
|
reply = await this.generateWithGoogle(
|
|
90007
90011
|
settings.apiKey,
|
|
90008
90012
|
settings.model,
|
|
@@ -90011,10 +90015,7 @@ var APIProvider = class {
|
|
|
90011
90015
|
settings.maxTokens
|
|
90012
90016
|
);
|
|
90013
90017
|
}
|
|
90014
|
-
|
|
90015
|
-
cache2.set(cacheKey, { reply, timestamp: Date.now() });
|
|
90016
|
-
this.cleanExpiredCache();
|
|
90017
|
-
}
|
|
90018
|
+
logger.info(`[APIProvider] API \u547C\u53EB\u5B8C\u6210, \u8017\u6642: ${Date.now() - startTime}ms, \u56DE\u8986\u9577\u5EA6: ${reply.length}`);
|
|
90018
90019
|
return { success: true, reply, promptSent, mode: "api" };
|
|
90019
90020
|
} catch (error2) {
|
|
90020
90021
|
logger.error("[APIProvider] \u751F\u6210\u56DE\u8986\u5931\u6557", error2);
|
|
@@ -90027,6 +90028,7 @@ var APIProvider = class {
|
|
|
90027
90028
|
}
|
|
90028
90029
|
async generateWithGoogle(apiKey, model, prompt, temperature, maxTokens, retryCount = 0) {
|
|
90029
90030
|
try {
|
|
90031
|
+
logger.info(`[APIProvider/Google] \u547C\u53EB API: model=${model}, promptLength=${prompt.length}, retry=${retryCount}`);
|
|
90030
90032
|
const genAI = new GoogleGenerativeAI(apiKey);
|
|
90031
90033
|
const generativeModel = genAI.getGenerativeModel({
|
|
90032
90034
|
model,
|
|
@@ -90062,10 +90064,13 @@ var APIProvider = class {
|
|
|
90062
90064
|
}
|
|
90063
90065
|
async generateWithOpenAI(apiKey, model, apiUrl, prompt, temperature, maxTokens, retryCount = 0) {
|
|
90064
90066
|
try {
|
|
90067
|
+
const baseURL = apiUrl || "https://api.openai.com/v1";
|
|
90068
|
+
logger.info(`[APIProvider/OpenAI] \u547C\u53EB API: baseURL=${baseURL}, model=${model}, promptLength=${prompt.length}, retry=${retryCount}`);
|
|
90065
90069
|
const OpenAI = (await import("openai")).default;
|
|
90066
90070
|
const client = new OpenAI({
|
|
90067
90071
|
apiKey,
|
|
90068
|
-
baseURL
|
|
90072
|
+
baseURL,
|
|
90073
|
+
timeout: 12e4
|
|
90069
90074
|
});
|
|
90070
90075
|
const response = await client.chat.completions.create({
|
|
90071
90076
|
model,
|
|
@@ -90073,6 +90078,7 @@ var APIProvider = class {
|
|
|
90073
90078
|
temperature: temperature ?? 0.7,
|
|
90074
90079
|
max_tokens: maxTokens ?? 1e3
|
|
90075
90080
|
});
|
|
90081
|
+
logger.info(`[APIProvider/OpenAI] API \u56DE\u61C9: choices=${response.choices?.length}, usage=${JSON.stringify(response.usage)}`);
|
|
90076
90082
|
const text = response.choices?.[0]?.message?.content;
|
|
90077
90083
|
if (!text) throw new Error("AI \u56DE\u8986\u70BA\u7A7A");
|
|
90078
90084
|
return text;
|
|
@@ -90099,12 +90105,6 @@ var APIProvider = class {
|
|
|
90099
90105
|
sleep(ms) {
|
|
90100
90106
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
90101
90107
|
}
|
|
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
90108
|
};
|
|
90109
90109
|
|
|
90110
90110
|
// src/utils/cli-provider.ts
|
|
@@ -108,6 +108,12 @@ export function startCloseCountdown() {
|
|
|
108
108
|
setCloseCountdownInterval(null);
|
|
109
109
|
console.log("倒數結束,關閉頁面");
|
|
110
110
|
window.close();
|
|
111
|
+
setTimeout(() => {
|
|
112
|
+
document.body.innerHTML = `
|
|
113
|
+
<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;font-family:system-ui;color:#888;">
|
|
114
|
+
<p style="font-size:1.2rem;">✅ 回應已送出,您可以關閉此分頁。</p>
|
|
115
|
+
</div>`;
|
|
116
|
+
}, 300);
|
|
111
117
|
}
|
|
112
118
|
}, 1000);
|
|
113
119
|
|