diff --git a/.env.example b/.env.example index 2f30fdd..5f3fd85 100644 --- a/.env.example +++ b/.env.example @@ -63,3 +63,5 @@ EMB_DIM= EMB_TRANSLATE_MODEL= TRACE_ENABLED=false + +PRODUCT_TIMEOUT_MS=30000 diff --git a/bridge/src/server.js b/bridge/src/server.js index f667235..992f5fd 100644 --- a/bridge/src/server.js +++ b/bridge/src/server.js @@ -7,11 +7,11 @@ const { createTools, resolveSiteProfile } = require('./tools'); const { createIdentity } = require('./identity'); const { createLibreDeskWebhook } = require('./libredesk-webhook'); const { createAgent } = require('./agent'); +const { createLLM } = require('./llm'); +const { createReranker } = require('./reranker'); const { createVerification } = require('./verification'); const { createLibreDeskClient } = require('./libredesk'); const { createRetriever } = require('./rag'); -const { createLLM } = require('./llm'); -const { createReranker } = require('./reranker'); const prom = require('./prom'); const { ToolError } = require('./errors'); @@ -88,8 +88,6 @@ function contextFromHeaders(headers = {}) { function createServer(options = {}) { const cfg = options.config || loadConfig(); const auther = createAuther(cfg.toolsSharedKey); - // HTTP 工具入口(LibreDesk 直接调用)也必须带上 retriever/verification/client, - // 否则 search_kb / send_verification_code / handoff_to_human 会一直是 not_configured。 const verification = options.verification || createVerification(cfg); const client = options.client || createLibreDeskClient(cfg); const retriever = options.retriever || (cfg.ragPgUrl ? createRetriever(cfg) : null); @@ -273,10 +271,7 @@ if (require.main === module) { if (!cfg.toolsSharedKey) console.warn('[crm-tools] TOOLS_SHARED_KEY is not set — all /tools/* calls will return 503'); if (cfg.devBypassVerification) console.warn('[crm-tools] TOOLS_DEV_BYPASS=true — verification checks are BYPASSED (local development only)'); }); - const shutdown = () => server.close(() => { - if (retriever && retriever.pool) retriever.pool.end().catch(() => {}); - process.exit(0); - }); + const shutdown = () => server.close(() => process.exit(0)); process.on('SIGINT', shutdown); process.on('SIGTERM', shutdown); } diff --git a/bridge/src/tools.js b/bridge/src/tools.js index 498f150..3cb1ec3 100644 --- a/bridge/src/tools.js +++ b/bridge/src/tools.js @@ -377,10 +377,10 @@ function createTools(cfg, deps = {}) { const query = String(args.query || '').trim(); if (!query) throw new ToolError(400, 'invalid_arguments', 'query is required'); const limit = Math.min(Number(args.limit) || 5, 8); - // 有 reranker 时多取一些候选再重排;没有 reranker 时必须尊重调用方 limit。 + // 有 reranker 时多取候选再重排;无 reranker 时尊重调用方 limit。 const fetchLimit = reranker ? Math.max(limit, 8) : limit; let results = await retriever.searchKB(query, fetchLimit); - // parent/child 可能命中同一篇文章:按 question+answer 去重后再重排 + // parent/child 可能命中同一篇文章:按 question+answer 去重 const seen = new Set(); results = results.filter((r) => { const key = `${r.question || ''}\u0000${r.answer || ''}`; @@ -389,6 +389,7 @@ function createTools(cfg, deps = {}) { return true; }); if (reranker) results = await reranker.rerank(query, results, limit); + else results = results.slice(0, limit); return { results, count: results.length,