修 arcrun-rag#10(Arcrun@0d49989):cypher 補 /portal/admin/ai+UI 已輸入態
- tier2/cypher:新增 GET|POST /portal/admin/ai(grep 0→2)——這是「key 從來沒存進去」的真因 - tier2/ui:拔掉寫死 cypher.arcrun.dev fallback(portal+console 兩處,grep 歸 0); 金鑰欄改 leo 規格「已輸入+修改」唯讀態(不顯示 key) - manifest 24 顆 sha256 全數重新核對相符(含我手動重建的 ui) - daemon 仍 v0.15.0,tier1 未變
This commit is contained in:
+3
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"schema": "arcrun-rag-bundles/v1",
|
||||
"built": "2026-07-31",
|
||||
"source": "Arcrun@c735b91",
|
||||
"source": "Arcrun@0d49989",
|
||||
"core": [
|
||||
{
|
||||
"name": "arcrun-array-ops",
|
||||
@@ -503,7 +503,7 @@
|
||||
"tier": 2,
|
||||
"main_file": "tier2/cypher/index.js",
|
||||
"main_module": "index.js",
|
||||
"sha256": "0e03e7f1093e115865a7c8f38335f5e30747c53113fd96df2bc73d0135823a6d",
|
||||
"sha256": "6e330271867978f85557bcb3863fb92e6719babe4a6c4c59bb6245dab6020efb",
|
||||
"compat_date": "2025-02-19",
|
||||
"compat_flags": [
|
||||
"nodejs_compat",
|
||||
@@ -634,7 +634,7 @@
|
||||
"tier": 2,
|
||||
"main_file": "tier2/ui/index.js",
|
||||
"main_module": "index.js",
|
||||
"sha256": "30ea47698513e66df985cd54a0d3235ca226a8300326c70b2b358f31bc81e44d",
|
||||
"sha256": "1a295abca7f1a499a593863d171c20aafb8825734fc09f6a34948cb0b6f21130",
|
||||
"compat_date": "2026-07-01",
|
||||
"compat_flags": [],
|
||||
"modules": [],
|
||||
|
||||
@@ -14573,6 +14573,78 @@ portalRouter.patch(
|
||||
return c.json({ success: true, library: toPublicLibrary(updated) });
|
||||
})
|
||||
);
|
||||
var AI_PREF_KEY = /* @__PURE__ */ __name((tenantSlug) => `portal_ai_pref:${tenantSlug}`, "AI_PREF_KEY");
|
||||
async function readAiPref(env2, tenantSlug) {
|
||||
try {
|
||||
const raw2 = await env2.WEBHOOKS.get(AI_PREF_KEY(tenantSlug));
|
||||
if (!raw2) return { use_claude_for_extract: false };
|
||||
const p = JSON.parse(raw2);
|
||||
return { use_claude_for_extract: !!p.use_claude_for_extract };
|
||||
} catch {
|
||||
return { use_claude_for_extract: false };
|
||||
}
|
||||
}
|
||||
__name(readAiPref, "readAiPref");
|
||||
portalRouter.get(
|
||||
"/portal/admin/ai",
|
||||
(c) => run(c, async () => {
|
||||
const auth = await requirePortalAdmin(c);
|
||||
if (!auth.ok) return auth.res;
|
||||
const tenantSlug = portalTenant(c.env);
|
||||
let hasKey = false;
|
||||
try {
|
||||
const row = await c.env.CREDENTIALS_DB.prepare("SELECT 1 FROM credentials WHERE api_key = ? AND name = ? LIMIT 1").bind(tenantSlug, "gemini_api_key").first();
|
||||
hasKey = !!row;
|
||||
} catch {
|
||||
hasKey = false;
|
||||
}
|
||||
const pref = await readAiPref(c.env, tenantSlug);
|
||||
return c.json({
|
||||
success: true,
|
||||
has_key: hasKey,
|
||||
// 目前後端沒有「這台電腦有沒有 Claude Code」的訊號來源(該由小幫手回報)
|
||||
// ⇒ 誠實回 false,前端會顯示「連上小幫手後才知道…」,不假綠。
|
||||
claude_available: false,
|
||||
use_claude_for_extract: pref.use_claude_for_extract
|
||||
});
|
||||
})
|
||||
);
|
||||
portalRouter.post(
|
||||
"/portal/admin/ai",
|
||||
(c) => run(c, async () => {
|
||||
const auth = await requirePortalAdmin(c);
|
||||
if (!auth.ok) return auth.res;
|
||||
const body = await c.req.json().catch(() => null);
|
||||
const rawKey = typeof body?.gemini_api_key === "string" ? body.gemini_api_key.trim() : "";
|
||||
const hasPref = typeof body?.use_claude_for_extract === "boolean";
|
||||
if (!rawKey && !hasPref) {
|
||||
return c.json({ error: "\u6C92\u6709\u8981\u8B8A\u66F4\u7684\u9805\u76EE\uFF08\u91D1\u9470\u7559\u7A7A\u4E14\u672A\u6539\u8A2D\u5B9A\uFF09" }, 400);
|
||||
}
|
||||
const tenantSlug = portalTenant(c.env);
|
||||
if (rawKey) {
|
||||
try {
|
||||
await storeCredential(c.env, tenantSlug, "gemini_api_key", rawKey, "gemini");
|
||||
} catch (e) {
|
||||
return c.json(
|
||||
{ error: `\u91D1\u9470\u5132\u5B58\u5931\u6557\uFF1A${e instanceof Error ? e.message : String(e)}` },
|
||||
502
|
||||
);
|
||||
}
|
||||
}
|
||||
if (hasPref) {
|
||||
await c.env.WEBHOOKS.put(
|
||||
AI_PREF_KEY(tenantSlug),
|
||||
JSON.stringify({ use_claude_for_extract: !!body.use_claude_for_extract })
|
||||
);
|
||||
}
|
||||
const pref = await readAiPref(c.env, tenantSlug);
|
||||
return c.json({
|
||||
success: true,
|
||||
has_key: rawKey ? true : void 0,
|
||||
use_claude_for_extract: pref.use_claude_for_extract
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
// src/routes/init-seed.ts
|
||||
var initSeedRouter = new Hono2();
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user