@astro-minimax/ai 0.9.0 → 0.9.3

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.
Files changed (251) hide show
  1. package/README.md +108 -18
  2. package/dist/cache/global-cache.d.ts +6 -2
  3. package/dist/cache/global-cache.d.ts.map +1 -1
  4. package/dist/cache/global-cache.js +24 -9
  5. package/dist/cache/index.d.ts +7 -6
  6. package/dist/cache/index.d.ts.map +1 -1
  7. package/dist/cache/index.js +12 -4
  8. package/dist/cache/injection-cache.d.ts +36 -0
  9. package/dist/cache/injection-cache.d.ts.map +1 -0
  10. package/dist/cache/injection-cache.js +90 -0
  11. package/dist/cache/kv-adapter.d.ts.map +1 -1
  12. package/dist/cache/kv-adapter.js +2 -1
  13. package/dist/cache/memory-adapter.d.ts.map +1 -1
  14. package/dist/cache/memory-adapter.js +2 -1
  15. package/dist/cache/response-cache.d.ts +10 -5
  16. package/dist/cache/response-cache.d.ts.map +1 -1
  17. package/dist/cache/response-cache.js +18 -6
  18. package/dist/components/AIChatContainer.d.ts +2 -2
  19. package/dist/components/AIChatContainer.d.ts.map +1 -1
  20. package/dist/components/AIChatContainer.js +8 -920
  21. package/dist/components/ChatInput.d.ts +15 -0
  22. package/dist/components/ChatInput.d.ts.map +1 -0
  23. package/dist/components/ChatInput.js +72 -0
  24. package/dist/components/ChatPanel.d.ts +1 -1
  25. package/dist/components/ChatPanel.d.ts.map +1 -1
  26. package/dist/components/ChatPanel.js +210 -672
  27. package/dist/components/CodeBlock.d.ts +31 -0
  28. package/dist/components/CodeBlock.d.ts.map +1 -0
  29. package/dist/components/CodeBlock.js +143 -0
  30. package/dist/components/MarkmapBlock.d.ts +4 -0
  31. package/dist/components/MarkmapBlock.d.ts.map +1 -0
  32. package/dist/components/MarkmapBlock.js +180 -0
  33. package/dist/components/MermaidBlock.d.ts +4 -0
  34. package/dist/components/MermaidBlock.d.ts.map +1 -0
  35. package/dist/components/MermaidBlock.js +193 -0
  36. package/dist/components/MessageBubble.d.ts +21 -0
  37. package/dist/components/MessageBubble.d.ts.map +1 -0
  38. package/dist/components/MessageBubble.js +233 -0
  39. package/dist/components/ReasoningBlock.d.ts +6 -0
  40. package/dist/components/ReasoningBlock.d.ts.map +1 -0
  41. package/dist/components/ReasoningBlock.js +11 -0
  42. package/dist/components/RichText.d.ts +41 -0
  43. package/dist/components/RichText.d.ts.map +1 -0
  44. package/dist/components/RichText.js +202 -0
  45. package/dist/components/VizShared.d.ts +57 -0
  46. package/dist/components/VizShared.d.ts.map +1 -0
  47. package/dist/components/VizShared.js +233 -0
  48. package/dist/components/tool-auto-continue.d.ts +5 -0
  49. package/dist/components/tool-auto-continue.d.ts.map +1 -0
  50. package/dist/components/tool-auto-continue.js +33 -0
  51. package/dist/constants.d.ts +61 -0
  52. package/dist/constants.d.ts.map +1 -0
  53. package/dist/constants.js +72 -0
  54. package/dist/data/index.d.ts +4 -3
  55. package/dist/data/index.d.ts.map +1 -1
  56. package/dist/data/index.js +4 -10
  57. package/dist/data/knowledge-types.d.ts +8 -0
  58. package/dist/data/knowledge-types.d.ts.map +1 -0
  59. package/dist/data/knowledge-types.js +14 -0
  60. package/dist/data/metadata-loader.d.ts +4 -28
  61. package/dist/data/metadata-loader.d.ts.map +1 -1
  62. package/dist/data/metadata-loader.js +11 -34
  63. package/dist/data/types.d.ts +17 -2
  64. package/dist/data/types.d.ts.map +1 -1
  65. package/dist/extensions/index.d.ts +5 -0
  66. package/dist/extensions/index.d.ts.map +1 -0
  67. package/dist/extensions/index.js +24 -0
  68. package/dist/extensions/injector.d.ts +14 -0
  69. package/dist/extensions/injector.d.ts.map +1 -0
  70. package/dist/extensions/injector.js +146 -0
  71. package/dist/extensions/loader.d.ts +5 -0
  72. package/dist/extensions/loader.d.ts.map +1 -0
  73. package/dist/extensions/loader.js +45 -0
  74. package/dist/extensions/registry.d.ts +4 -0
  75. package/dist/extensions/registry.d.ts.map +1 -0
  76. package/dist/extensions/registry.js +144 -0
  77. package/dist/extensions/types.d.ts +126 -0
  78. package/dist/extensions/types.d.ts.map +1 -0
  79. package/dist/extensions/types.js +0 -0
  80. package/dist/fact-registry/prompt-injector.d.ts +1 -1
  81. package/dist/fact-registry/prompt-injector.d.ts.map +1 -1
  82. package/dist/fact-registry/prompt-injector.js +2 -1
  83. package/dist/index.d.ts +3 -2
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +3 -2
  86. package/dist/intelligence/citation-guard.d.ts +2 -13
  87. package/dist/intelligence/citation-guard.d.ts.map +1 -1
  88. package/dist/intelligence/citation-guard.js +52 -23
  89. package/dist/intelligence/evidence-analysis.d.ts +24 -16
  90. package/dist/intelligence/evidence-analysis.d.ts.map +1 -1
  91. package/dist/intelligence/evidence-analysis.js +118 -20
  92. package/dist/intelligence/evidence-budget.d.ts +13 -0
  93. package/dist/intelligence/evidence-budget.d.ts.map +1 -0
  94. package/dist/intelligence/evidence-budget.js +49 -0
  95. package/dist/intelligence/index.d.ts +10 -4
  96. package/dist/intelligence/index.d.ts.map +1 -1
  97. package/dist/intelligence/index.js +27 -3
  98. package/dist/intelligence/keyword-extract.d.ts +1 -1
  99. package/dist/intelligence/keyword-extract.d.ts.map +1 -1
  100. package/dist/intelligence/keyword-extract.js +5 -9
  101. package/dist/intelligence/request-interpretation.d.ts +40 -0
  102. package/dist/intelligence/request-interpretation.d.ts.map +1 -0
  103. package/dist/intelligence/request-interpretation.js +71 -0
  104. package/dist/intelligence/response-templates.d.ts +1 -0
  105. package/dist/intelligence/response-templates.d.ts.map +1 -1
  106. package/dist/intelligence/response-templates.js +13 -0
  107. package/dist/prompt/dynamic-layer.d.ts +1 -5
  108. package/dist/prompt/dynamic-layer.d.ts.map +1 -1
  109. package/dist/prompt/dynamic-layer.js +145 -9
  110. package/dist/prompt/prompt-builder.d.ts +1 -1
  111. package/dist/prompt/prompt-builder.d.ts.map +1 -1
  112. package/dist/prompt/prompt-builder.js +5 -1
  113. package/dist/prompt/semi-static-layer.d.ts +1 -1
  114. package/dist/prompt/semi-static-layer.d.ts.map +1 -1
  115. package/dist/prompt/semi-static-layer.js +22 -12
  116. package/dist/prompt/static-layer.d.ts.map +1 -1
  117. package/dist/prompt/static-layer.js +37 -4
  118. package/dist/prompt/types.d.ts +9 -4
  119. package/dist/prompt/types.d.ts.map +1 -1
  120. package/dist/provider-manager/base.d.ts +5 -1
  121. package/dist/provider-manager/base.d.ts.map +1 -1
  122. package/dist/provider-manager/base.js +22 -2
  123. package/dist/provider-manager/config.d.ts.map +1 -1
  124. package/dist/provider-manager/config.js +3 -2
  125. package/dist/provider-manager/index.d.ts +1 -1
  126. package/dist/provider-manager/index.d.ts.map +1 -1
  127. package/dist/provider-manager/index.js +1 -2
  128. package/dist/provider-manager/manager.d.ts +10 -1
  129. package/dist/provider-manager/manager.d.ts.map +1 -1
  130. package/dist/provider-manager/manager.js +26 -10
  131. package/dist/provider-manager/openai.d.ts +2 -2
  132. package/dist/provider-manager/openai.d.ts.map +1 -1
  133. package/dist/provider-manager/openai.js +19 -4
  134. package/dist/provider-manager/types.d.ts +18 -38
  135. package/dist/provider-manager/types.d.ts.map +1 -1
  136. package/dist/provider-manager/workers.d.ts +2 -2
  137. package/dist/provider-manager/workers.d.ts.map +1 -1
  138. package/dist/provider-manager/workers.js +15 -4
  139. package/dist/query/followup.d.ts +7 -0
  140. package/dist/query/followup.d.ts.map +1 -0
  141. package/dist/query/followup.js +46 -0
  142. package/dist/query/intent.d.ts +6 -0
  143. package/dist/query/intent.d.ts.map +1 -0
  144. package/dist/query/intent.js +137 -0
  145. package/dist/query/types.d.ts +8 -0
  146. package/dist/query/types.d.ts.map +1 -0
  147. package/dist/query/types.js +0 -0
  148. package/dist/search/hybrid-search.d.ts +111 -0
  149. package/dist/search/hybrid-search.d.ts.map +1 -0
  150. package/dist/search/hybrid-search.js +326 -0
  151. package/dist/search/index.d.ts +11 -9
  152. package/dist/search/index.d.ts.map +1 -1
  153. package/dist/search/index.js +46 -10
  154. package/dist/search/scoring.d.ts +18 -0
  155. package/dist/search/scoring.d.ts.map +1 -0
  156. package/dist/search/{search-utils.js → scoring.js} +14 -27
  157. package/dist/search/search-api.d.ts +16 -1
  158. package/dist/search/search-api.d.ts.map +1 -1
  159. package/dist/search/search-api.js +118 -15
  160. package/dist/search/search-index.d.ts +2 -2
  161. package/dist/search/search-index.d.ts.map +1 -1
  162. package/dist/search/search-index.js +4 -2
  163. package/dist/search/session-cache.d.ts +4 -10
  164. package/dist/search/session-cache.d.ts.map +1 -1
  165. package/dist/search/session-cache.js +12 -45
  166. package/dist/search/types.d.ts +28 -0
  167. package/dist/search/types.d.ts.map +1 -1
  168. package/dist/search/vector-reranker.d.ts +3 -3
  169. package/dist/search/vector-reranker.d.ts.map +1 -1
  170. package/dist/search/vector-reranker.js +14 -2
  171. package/dist/server/chat-handler.d.ts +86 -1
  172. package/dist/server/chat-handler.d.ts.map +1 -1
  173. package/dist/server/chat-handler.js +835 -401
  174. package/dist/server/chat-message-utils.d.ts +6 -0
  175. package/dist/server/chat-message-utils.d.ts.map +1 -0
  176. package/dist/server/chat-message-utils.js +40 -0
  177. package/dist/server/chat-utils.d.ts +30 -0
  178. package/dist/server/chat-utils.d.ts.map +1 -0
  179. package/dist/server/chat-utils.js +88 -0
  180. package/dist/server/dev-server.js +238 -101
  181. package/dist/server/env-config.d.ts +22 -0
  182. package/dist/server/env-config.d.ts.map +1 -0
  183. package/dist/server/env-config.js +25 -0
  184. package/dist/server/errors.d.ts +1 -0
  185. package/dist/server/errors.d.ts.map +1 -1
  186. package/dist/server/errors.js +14 -7
  187. package/dist/server/index.d.ts +2 -4
  188. package/dist/server/index.d.ts.map +1 -1
  189. package/dist/server/index.js +4 -25
  190. package/dist/server/metadata-init.d.ts +10 -5
  191. package/dist/server/metadata-init.d.ts.map +1 -1
  192. package/dist/server/metadata-init.js +78 -34
  193. package/dist/server/notify.d.ts +12 -11
  194. package/dist/server/notify.d.ts.map +1 -1
  195. package/dist/server/notify.js +46 -48
  196. package/dist/server/prompt-runtime.d.ts +60 -0
  197. package/dist/server/prompt-runtime.d.ts.map +1 -0
  198. package/dist/server/prompt-runtime.js +284 -0
  199. package/dist/server/stream-helpers.d.ts +30 -16
  200. package/dist/server/stream-helpers.d.ts.map +1 -1
  201. package/dist/server/stream-helpers.js +152 -15
  202. package/dist/server/types.d.ts +47 -12
  203. package/dist/server/types.d.ts.map +1 -1
  204. package/dist/structured-output/generator.d.ts +6 -0
  205. package/dist/structured-output/generator.d.ts.map +1 -0
  206. package/dist/structured-output/generator.js +164 -0
  207. package/dist/structured-output/index.d.ts +4 -0
  208. package/dist/structured-output/index.d.ts.map +1 -0
  209. package/dist/structured-output/index.js +6 -0
  210. package/dist/structured-output/schemas/evidence.d.ts +88 -0
  211. package/dist/structured-output/schemas/evidence.d.ts.map +1 -0
  212. package/dist/structured-output/schemas/evidence.js +65 -0
  213. package/dist/structured-output/types.d.ts +69 -0
  214. package/dist/structured-output/types.d.ts.map +1 -0
  215. package/dist/structured-output/types.js +0 -0
  216. package/dist/tools/action-tools.d.ts +63 -0
  217. package/dist/tools/action-tools.d.ts.map +1 -0
  218. package/dist/tools/action-tools.js +158 -0
  219. package/dist/tools/index.d.ts +2 -0
  220. package/dist/tools/index.d.ts.map +1 -0
  221. package/dist/tools/index.js +30 -0
  222. package/dist/utils/i18n.d.ts +1 -1
  223. package/dist/utils/i18n.d.ts.map +1 -1
  224. package/dist/utils/i18n.js +1 -1
  225. package/dist/utils/logger.d.ts +11 -0
  226. package/dist/utils/logger.d.ts.map +1 -0
  227. package/dist/utils/logger.js +36 -0
  228. package/dist/utils/text.d.ts +11 -0
  229. package/dist/utils/text.d.ts.map +1 -0
  230. package/dist/utils/text.js +87 -0
  231. package/dist/utils/url.d.ts +19 -0
  232. package/dist/utils/url.d.ts.map +1 -0
  233. package/dist/utils/url.js +13 -0
  234. package/package.json +46 -12
  235. package/dist/intelligence/intent-detect.d.ts +0 -40
  236. package/dist/intelligence/intent-detect.d.ts.map +0 -1
  237. package/dist/intelligence/intent-detect.js +0 -93
  238. package/dist/providers/index.d.ts +0 -2
  239. package/dist/providers/index.d.ts.map +0 -1
  240. package/dist/providers/index.js +0 -5
  241. package/dist/search/search-utils.d.ts +0 -47
  242. package/dist/search/search-utils.d.ts.map +0 -1
  243. package/dist/stream/index.d.ts +0 -3
  244. package/dist/stream/index.d.ts.map +0 -1
  245. package/dist/stream/index.js +0 -8
  246. package/dist/stream/mock-stream.d.ts +0 -12
  247. package/dist/stream/mock-stream.d.ts.map +0 -1
  248. package/dist/stream/mock-stream.js +0 -26
  249. package/dist/stream/response.d.ts +0 -10
  250. package/dist/stream/response.d.ts.map +0 -1
  251. package/dist/stream/response.js +0 -21
@@ -2,19 +2,26 @@ import {
2
2
  PRIVACY_REFUSAL_TEMPLATES,
3
3
  NO_ARTICLE_TEMPLATES,
4
4
  ARTICLE_COUNT_TEMPLATES,
5
+ UNKNOWN_REFUSAL_TEMPLATES,
5
6
  pickTemplate,
6
7
  pickTemplateWithVars
7
8
  } from "./response-templates.js";
8
9
  const PRIVACY_PATTERNS = [
9
- { regex: /(住址|地址|住在哪|address|where.*live)/iu, key: "address" },
10
- { regex: /(收入|工资|薪资|salary|income|earn)/iu, key: "income" },
11
- { regex: /(家人|妻子|丈夫|孩子|父母|family|wife|husband|children|parent)/iu, key: "family" },
12
- { regex: /(电话|手机号|phone|mobile)/iu, key: "phone" },
13
- { regex: /(身份证|id\s*card|passport)/iu, key: "id" },
14
- { regex: /(年龄|多大了|几岁|how old|age)/iu, key: "age" }
10
+ /具体住在哪|哪个小区|门牌号|家庭住址|具体地址|住址信息/u,
11
+ /赚多少钱|月收入|年收入|工资多少|薪资多少|收入多少/u,
12
+ /老婆叫什么|妻子叫什么|丈夫叫什么|孩子叫什么|父母叫什么|家人姓名/u,
13
+ /手机号码|电话号码|联系方式|微信号|QQ号/u,
14
+ /身份证号|护照号|证件号/u,
15
+ /你多大了|你几岁|年龄多大|今年多大|今年几岁/u
15
16
  ];
17
+ function hasPrivacyIntent(query) {
18
+ const normalized = query.trim().toLowerCase();
19
+ if (!normalized) return false;
20
+ return PRIVACY_PATTERNS.some((pattern) => pattern.test(normalized));
21
+ }
16
22
  function resolveAnswerMode(query) {
17
23
  const q = query.toLowerCase();
24
+ if (hasPrivacyIntent(query)) return "unknown";
18
25
  if (/几次|多少|几篇|数量|count|how many/u.test(q)) return "count";
19
26
  if (/哪些|哪几个|列表|列举|list|what are/u.test(q)) return "list";
20
27
  if (/怎么看|怎么想|看法|观点|opinion|think about/u.test(q)) return "opinion";
@@ -23,24 +30,31 @@ function resolveAnswerMode(query) {
23
30
  if (/有没有|是否|是不是|真的吗|does|is there/u.test(q)) return "fact";
24
31
  return "general";
25
32
  }
26
- function checkPrivacyRefusal(query, lang) {
27
- for (const pattern of PRIVACY_PATTERNS) {
28
- if (pattern.regex.test(query)) {
29
- const templates = PRIVACY_REFUSAL_TEMPLATES[pattern.key];
30
- const text = templates ? pickTemplate(templates, lang) : "";
31
- return {
32
- text,
33
- actions: ["preflight_reject"]
34
- };
35
- }
33
+ function buildUnknownRefusal(query, lang = "zh") {
34
+ const normalized = query.trim().toLowerCase();
35
+ if (/(具体住在哪|哪个小区|门牌号|家庭住址|具体地址|住址)/u.test(normalized)) {
36
+ return pickTemplate(PRIVACY_REFUSAL_TEMPLATES.address, lang);
36
37
  }
37
- return null;
38
+ if (/(赚多少钱|月收入|年收入|工资多少|薪资多少|收入)/u.test(normalized)) {
39
+ return pickTemplate(PRIVACY_REFUSAL_TEMPLATES.income, lang);
40
+ }
41
+ if (/(老婆叫什么|妻子叫什么|丈夫叫什么|孩子叫什么|父母叫什么|家人姓名|家人)/u.test(normalized)) {
42
+ return pickTemplate(PRIVACY_REFUSAL_TEMPLATES.family, lang);
43
+ }
44
+ if (/(手机号码|电话号码|联系方式|微信号|QQ号|电话|手机)/u.test(normalized)) {
45
+ return pickTemplate(PRIVACY_REFUSAL_TEMPLATES.phone, lang);
46
+ }
47
+ if (/(身份证号|护照号|证件号|身份证)/u.test(normalized)) {
48
+ return pickTemplate(PRIVACY_REFUSAL_TEMPLATES.id, lang);
49
+ }
50
+ if (/(你多大了|你几岁|年龄多大|今年多大|今年几岁|年龄)/u.test(normalized)) {
51
+ return pickTemplate(PRIVACY_REFUSAL_TEMPLATES.age, lang);
52
+ }
53
+ return pickTemplate(UNKNOWN_REFUSAL_TEMPLATES, lang);
38
54
  }
39
55
  function getCitationGuardPreflight(params) {
40
56
  const { userQuery, articles, projects, lang = "zh" } = params;
41
57
  const q = userQuery.toLowerCase();
42
- const privacyRefusal = checkPrivacyRefusal(userQuery, lang);
43
- if (privacyRefusal) return privacyRefusal;
44
58
  if (/有几篇|有多少篇|文章数量|总共.*文章|how many.*article/u.test(q)) {
45
59
  const total = articles.length;
46
60
  if (total > 0) {
@@ -57,11 +71,21 @@ function getCitationGuardPreflight(params) {
57
71
  return null;
58
72
  }
59
73
  function createCitationGuardTransform(params) {
60
- const { articles, projects, onApplied } = params;
74
+ const { articles, projects, siteUrl = "", onApplied } = params;
75
+ const normalizeUrl = (url) => {
76
+ if (url.startsWith("/")) return `${siteUrl}${url}`;
77
+ if (url.startsWith("http://") || url.startsWith("https://")) return url;
78
+ return `${siteUrl}/${url}`;
79
+ };
61
80
  const validUrls = /* @__PURE__ */ new Set([
62
- ...articles.map((a) => a.url),
63
- ...projects.map((p) => p.url)
81
+ ...articles.map((a) => normalizeUrl(a.url)),
82
+ ...projects.map((p) => normalizeUrl(p.url))
64
83
  ]);
84
+ const isValidInternalUrl = (url) => {
85
+ if (url.startsWith("/") && !url.startsWith("//")) return true;
86
+ if (siteUrl && url.startsWith(siteUrl)) return true;
87
+ return validUrls.has(normalizeUrl(url));
88
+ };
65
89
  return (stream) => {
66
90
  const actions = [];
67
91
  let buffer = "";
@@ -75,7 +99,11 @@ function createCitationGuardTransform(params) {
75
99
  while ((match = linkPattern.exec(buffer)) !== null) {
76
100
  const [fullMatch, text, url] = match;
77
101
  output += buffer.slice(lastIndex, match.index);
78
- if (url.startsWith("http") && !validUrls.has(url)) {
102
+ const normalizedUrl = normalizeUrl(url);
103
+ const isExternal = url.startsWith("http://") || url.startsWith("https://");
104
+ const isInternalValid = isValidInternalUrl(url);
105
+ const isInValidList = validUrls.has(normalizedUrl);
106
+ if (isExternal && !isInValidList && !isInternalValid) {
79
107
  output += text;
80
108
  actions.push("stream_rewrite");
81
109
  } else {
@@ -102,6 +130,7 @@ function createCitationGuardTransform(params) {
102
130
  };
103
131
  }
104
132
  export {
133
+ buildUnknownRefusal,
105
134
  createCitationGuardTransform,
106
135
  getCitationGuardPreflight,
107
136
  resolveAnswerMode
@@ -1,16 +1,27 @@
1
- import type { ArticleContext, ProjectContext } from '../search/types.js';
2
- import type { EvidenceAnalysisResult, QueryComplexity } from './types.js';
3
- export declare const EVIDENCE_ANALYSIS_TIMEOUT_MS = 8000;
4
- export declare const EVIDENCE_ANALYSIS_MAX_TOKENS = 360;
5
- /**
6
- * Determines whether evidence analysis should be skipped.
7
- * Skips for simple queries or when there's insufficient content to analyze.
8
- */
1
+ import type { ArticleContext, ProjectContext } from "../search/types.js";
2
+ import type { EvidenceAnalysisResult, TokenUsageStats, QueryComplexity } from "./types.js";
3
+ import { EvidenceAnalysis } from "../structured-output/index.js";
4
+ export declare const EVIDENCE_ANALYSIS_TIMEOUT_MS: 8000;
5
+ export declare const EVIDENCE_ANALYSIS_MAX_TOKENS: 360;
9
6
  export declare function shouldSkipAnalysis(latestText: string, articleCount: number, complexity: QueryComplexity): boolean;
10
- /**
11
- * Uses an LLM to pre-analyze retrieved evidence and identify the most relevant pieces.
12
- * This improves the quality of the final system prompt by pre-filtering noise.
13
- */
7
+ export interface StructuredEvidenceResult {
8
+ analysis: EvidenceAnalysis | null;
9
+ parseStatus: string;
10
+ usage?: TokenUsageStats;
11
+ error?: string;
12
+ rawText?: string;
13
+ }
14
+ export declare function analyzeRetrievedEvidenceStructured(params: {
15
+ userQuery: string;
16
+ articles: ArticleContext[];
17
+ projects: ProjectContext[];
18
+ provider: {
19
+ chatModel: (model: string) => unknown;
20
+ };
21
+ model: string;
22
+ maxOutputTokens?: number;
23
+ abortSignal?: AbortSignal;
24
+ }): Promise<StructuredEvidenceResult>;
14
25
  export declare function analyzeRetrievedEvidence(params: {
15
26
  userQuery: string;
16
27
  articles: ArticleContext[];
@@ -22,8 +33,5 @@ export declare function analyzeRetrievedEvidence(params: {
22
33
  maxOutputTokens?: number;
23
34
  abortSignal?: AbortSignal;
24
35
  }): Promise<EvidenceAnalysisResult>;
25
- /**
26
- * Formats the evidence analysis for injection into the system prompt.
27
- */
28
- export declare function buildEvidenceSection(analysis: string): string;
36
+ export declare function buildEvidenceSection(analysis: string | EvidenceAnalysis | null): string;
29
37
  //# sourceMappingURL=evidence-analysis.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"evidence-analysis.d.ts","sourceRoot":"","sources":["../../src/intelligence/evidence-analysis.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE1E,eAAO,MAAM,4BAA4B,OAAO,CAAC;AACjD,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,eAAe,GAC1B,OAAO,CAKT;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAAC,MAAM,EAAE;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE;QAAE,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAA;KAAE,CAAC;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAgDlC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG7D"}
1
+ {"version":3,"file":"evidence-analysis.d.ts","sourceRoot":"","sources":["../../src/intelligence/evidence-analysis.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,KAAK,EACV,sBAAsB,EACtB,eAAe,EACf,eAAe,EAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAEL,gBAAgB,EAEjB,MAAM,+BAA+B,CAAC;AAGvC,eAAO,MAAM,4BAA4B,MAA6B,CAAC;AACvE,eAAO,MAAM,4BAA4B,KACE,CAAC;AAE5C,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,eAAe,GAC1B,OAAO,CAKT;AAsDD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,kCAAkC,CAAC,MAAM,EAAE;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE;QAAE,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAA;KAAE,CAAC;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,GAAG,OAAO,CAAC,wBAAwB,CAAC,CA2CpC;AAED,wBAAsB,wBAAwB,CAAC,MAAM,EAAE;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE;QAAE,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAA;KAAE,CAAC;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAoDlC;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,GACzC,MAAM,CA+CR"}
@@ -1,14 +1,93 @@
1
1
  import { generateText } from "ai";
2
- const EVIDENCE_ANALYSIS_TIMEOUT_MS = 8e3;
3
- const EVIDENCE_ANALYSIS_MAX_TOKENS = 360;
2
+ import {
3
+ EvidenceAnalysisSchema,
4
+ EVIDENCE_ANALYSIS_SYSTEM_PROMPT
5
+ } from "../structured-output/index.js";
6
+ import { TIMEOUTS, INTELLIGENCE } from "../constants.js";
7
+ const EVIDENCE_ANALYSIS_TIMEOUT_MS = TIMEOUTS.EVIDENCE_ANALYSIS;
8
+ const EVIDENCE_ANALYSIS_MAX_TOKENS = INTELLIGENCE.EVIDENCE_ANALYSIS_MAX_TOKENS;
4
9
  function shouldSkipAnalysis(latestText, articleCount, complexity) {
5
10
  if (articleCount < 2) return true;
6
11
  if (complexity === "simple") return true;
7
12
  if (latestText.length < 15) return true;
8
13
  return false;
9
14
  }
15
+ function buildEvidenceSummary(articles, projects) {
16
+ const lines = [];
17
+ for (const article of articles.slice(0, 6)) {
18
+ lines.push(`\u6587\u7AE0: ${article.title}`);
19
+ if (article.summary) lines.push(` \u6458\u8981: ${article.summary}`);
20
+ if (article.keyPoints.length)
21
+ lines.push(` \u8981\u70B9: ${article.keyPoints.slice(0, 3).join(", ")}`);
22
+ if (article.url) lines.push(` URL: ${article.url}`);
23
+ }
24
+ for (const project of projects.slice(0, 3)) {
25
+ lines.push(`\u9879\u76EE: ${project.name} - ${project.description.slice(0, 100)}`);
26
+ if (project.url) lines.push(` URL: ${project.url}`);
27
+ }
28
+ return lines.join("\n");
29
+ }
30
+ async function extractUsage(result) {
31
+ const usagePromise = typeof result === "object" && result !== null && "usage" in result ? result.usage : void 0;
32
+ if (!usagePromise) return void 0;
33
+ try {
34
+ const u = await Promise.resolve(usagePromise);
35
+ return {
36
+ inputTokens: u.inputTokens ?? 0,
37
+ outputTokens: u.outputTokens ?? 0,
38
+ totalTokens: u.totalTokens ?? 0
39
+ };
40
+ } catch {
41
+ return void 0;
42
+ }
43
+ }
44
+ async function analyzeRetrievedEvidenceStructured(params) {
45
+ const { userQuery, articles, projects, provider, model, abortSignal } = params;
46
+ if (articles.length === 0 && projects.length === 0) {
47
+ return { analysis: null, parseStatus: "no_content" };
48
+ }
49
+ const evidenceSummary = buildEvidenceSummary(articles, projects);
50
+ const userPrompt = `\u7528\u6237\u95EE\u9898\uFF1A${userQuery}
51
+
52
+ \u68C0\u7D22\u5230\u7684\u76F8\u5173\u5185\u5BB9\uFF1A
53
+ ${evidenceSummary}`;
54
+ try {
55
+ const { generateObject } = await import("ai");
56
+ const result = await generateObject({
57
+ model: provider.chatModel(model),
58
+ schema: EvidenceAnalysisSchema,
59
+ schemaName: "evidence_analysis",
60
+ schemaDescription: "Structured evidence analysis for answer planning",
61
+ system: EVIDENCE_ANALYSIS_SYSTEM_PROMPT,
62
+ prompt: userPrompt,
63
+ temperature: 0,
64
+ abortSignal
65
+ });
66
+ const usage = await extractUsage(result);
67
+ return {
68
+ analysis: result.object,
69
+ parseStatus: "ok",
70
+ usage,
71
+ rawText: JSON.stringify(result.object)
72
+ };
73
+ } catch (error) {
74
+ return {
75
+ analysis: null,
76
+ parseStatus: "error",
77
+ error: error instanceof Error ? error.message : String(error)
78
+ };
79
+ }
80
+ }
10
81
  async function analyzeRetrievedEvidence(params) {
11
- const { userQuery, articles, projects, provider, model, maxOutputTokens = EVIDENCE_ANALYSIS_MAX_TOKENS, abortSignal } = params;
82
+ const {
83
+ userQuery,
84
+ articles,
85
+ projects,
86
+ provider,
87
+ model,
88
+ maxOutputTokens = EVIDENCE_ANALYSIS_MAX_TOKENS,
89
+ abortSignal
90
+ } = params;
12
91
  const evidenceSummary = buildEvidenceSummary(articles, projects);
13
92
  const prompt = `\u7528\u6237\u95EE\u9898\uFF1A${userQuery}
14
93
 
@@ -33,16 +112,12 @@ ${evidenceSummary}
33
112
  const rawText = result.text?.trim() ?? "";
34
113
  const match = rawText.match(/<evidence>([\s\S]*?)<\/evidence>/);
35
114
  const analysis = match?.[1]?.trim();
36
- const u = result.usage;
115
+ const usage = await extractUsage(result);
37
116
  return {
38
117
  analysis,
39
118
  parseStatus: analysis ? "ok" : "no_match",
40
119
  rawText,
41
- usage: u ? {
42
- inputTokens: u.inputTokens ?? 0,
43
- outputTokens: u.outputTokens ?? 0,
44
- totalTokens: (u.inputTokens ?? 0) + (u.outputTokens ?? 0)
45
- } : void 0
120
+ usage
46
121
  };
47
122
  } catch (error) {
48
123
  return {
@@ -52,21 +127,43 @@ ${evidenceSummary}
52
127
  }
53
128
  }
54
129
  function buildEvidenceSection(analysis) {
55
- if (!analysis.trim()) return "";
56
- return `
130
+ if (!analysis) return "";
131
+ if (typeof analysis === "string") {
132
+ if (!analysis.trim()) return "";
133
+ return `
57
134
  ## \u5173\u952E\u8BC1\u636E\u5206\u6790
58
135
  ${analysis}
59
136
  `;
60
- }
61
- function buildEvidenceSummary(articles, projects) {
62
- const lines = [];
63
- for (const article of articles.slice(0, 6)) {
64
- lines.push(`\u6587\u7AE0: ${article.title}`);
65
- if (article.summary) lines.push(` \u6458\u8981: ${article.summary}`);
66
- if (article.keyPoints.length) lines.push(` \u8981\u70B9: ${article.keyPoints.slice(0, 3).join(", ")}`);
67
137
  }
68
- for (const project of projects.slice(0, 3)) {
69
- lines.push(`\u9879\u76EE: ${project.name} - ${project.description.slice(0, 100)}`);
138
+ const lines = ["## \u5173\u952E\u8BC1\u636E\u5206\u6790"];
139
+ if (analysis.directAnswer) {
140
+ lines.push(`- \u76F4\u63A5\u7ED3\u8BBA\uFF1A${analysis.directAnswer}`);
141
+ }
142
+ if (analysis.entities.length > 0) {
143
+ lines.push("");
144
+ lines.push("### \u76F8\u5173\u5B9E\u4F53");
145
+ for (const entity of analysis.entities) {
146
+ const parts = [entity.name];
147
+ if (entity.count) {
148
+ const countStr = entity.countMode === "at_least" ? `\u81F3\u5C11 ${entity.count}` : `${entity.count}`;
149
+ parts.push(`(${countStr})`);
150
+ }
151
+ lines.push(`- ${parts.join(" ")}`);
152
+ }
153
+ }
154
+ if (analysis.keyFindings.length > 0) {
155
+ lines.push("");
156
+ lines.push("### \u5173\u952E\u53D1\u73B0");
157
+ for (const finding of analysis.keyFindings) {
158
+ lines.push(`- ${finding.claim} (\u7F6E\u4FE1\u5EA6: ${finding.confidence})`);
159
+ }
160
+ }
161
+ if (analysis.uncertainties.length > 0) {
162
+ lines.push("");
163
+ lines.push("### \u4E0D\u786E\u5B9A\u9879");
164
+ for (const item of analysis.uncertainties) {
165
+ lines.push(`- ${item}`);
166
+ }
70
167
  }
71
168
  return lines.join("\n");
72
169
  }
@@ -74,6 +171,7 @@ export {
74
171
  EVIDENCE_ANALYSIS_MAX_TOKENS,
75
172
  EVIDENCE_ANALYSIS_TIMEOUT_MS,
76
173
  analyzeRetrievedEvidence,
174
+ analyzeRetrievedEvidenceStructured,
77
175
  buildEvidenceSection,
78
176
  shouldSkipAnalysis
79
177
  };
@@ -0,0 +1,13 @@
1
+ import type { QueryComplexity } from './types.js';
2
+ import type { AnswerMode } from './citation-guard.js';
3
+ import type { ArticleContext } from '../search/types.js';
4
+ export interface EvidenceBudget {
5
+ maxArticles: number;
6
+ summaryMaxLength: number;
7
+ keyPointsMaxCount: number;
8
+ enableDeepContent: boolean;
9
+ analysisMaxTokens: number;
10
+ }
11
+ export declare function getEvidenceBudget(complexity: QueryComplexity, answerMode?: AnswerMode): EvidenceBudget;
12
+ export declare function applyBudgetToArticles(articles: ArticleContext[], budget: EvidenceBudget): ArticleContext[];
13
+ //# sourceMappingURL=evidence-budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence-budget.d.ts","sourceRoot":"","sources":["../../src/intelligence/evidence-budget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAkCD,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,eAAe,EAC3B,UAAU,CAAC,EAAE,UAAU,GACtB,cAAc,CAQhB;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,cAAc,EAAE,EAC1B,MAAM,EAAE,cAAc,GACrB,cAAc,EAAE,CAOlB"}
@@ -0,0 +1,49 @@
1
+ const BUDGET_PRESETS = {
2
+ simple: {
3
+ maxArticles: 4,
4
+ summaryMaxLength: 48,
5
+ keyPointsMaxCount: 2,
6
+ enableDeepContent: false,
7
+ analysisMaxTokens: 200
8
+ },
9
+ moderate: {
10
+ maxArticles: 6,
11
+ summaryMaxLength: 56,
12
+ keyPointsMaxCount: 3,
13
+ enableDeepContent: true,
14
+ analysisMaxTokens: 360
15
+ },
16
+ complex: {
17
+ maxArticles: 8,
18
+ summaryMaxLength: 64,
19
+ keyPointsMaxCount: 4,
20
+ enableDeepContent: true,
21
+ analysisMaxTokens: 500
22
+ }
23
+ };
24
+ const MODE_ADJUSTMENTS = {
25
+ count: { maxArticles: 2, enableDeepContent: false },
26
+ list: { maxArticles: 8, summaryMaxLength: 80 },
27
+ opinion: { analysisMaxTokens: 200 },
28
+ recommendation: { maxArticles: 6, keyPointsMaxCount: 2 },
29
+ unknown: { maxArticles: 2, enableDeepContent: false }
30
+ };
31
+ function getEvidenceBudget(complexity, answerMode) {
32
+ const base = { ...BUDGET_PRESETS[complexity] };
33
+ if (answerMode && MODE_ADJUSTMENTS[answerMode]) {
34
+ Object.assign(base, MODE_ADJUSTMENTS[answerMode]);
35
+ }
36
+ return base;
37
+ }
38
+ function applyBudgetToArticles(articles, budget) {
39
+ return articles.slice(0, budget.maxArticles).map((article) => ({
40
+ ...article,
41
+ summary: article.summary?.slice(0, budget.summaryMaxLength),
42
+ keyPoints: article.keyPoints.slice(0, budget.keyPointsMaxCount),
43
+ fullContent: budget.enableDeepContent ? article.fullContent : void 0
44
+ }));
45
+ }
46
+ export {
47
+ applyBudgetToArticles,
48
+ getEvidenceBudget
49
+ };
@@ -1,8 +1,14 @@
1
- export { isLikelyFollowUp, hasNewSignificantTokens, hasQueryOverlap, shouldReuseSearchContext, buildLocalSearchQuery, classifyIntent, rankArticlesByIntent, } from './intent-detect.js';
2
- export type { IntentCategory } from './intent-detect.js';
1
+ export { isLikelyFollowUp, hasNewSignificantTokens, hasQueryOverlap, shouldReuseSearchContext, buildLocalSearchQuery, } from '../query/followup.js';
2
+ export { classifyIntent, rankArticlesByCategory, rankArticlesByIntent, } from '../query/intent.js';
3
+ export type { QueryIntentCategory as IntentCategory } from '../query/types.js';
3
4
  export { shouldRunKeywordExtraction, extractSearchKeywords, KEYWORD_EXTRACTION_TIMEOUT_MS, } from './keyword-extract.js';
4
- export { shouldSkipAnalysis, analyzeRetrievedEvidence, buildEvidenceSection, EVIDENCE_ANALYSIS_TIMEOUT_MS, EVIDENCE_ANALYSIS_MAX_TOKENS, } from './evidence-analysis.js';
5
- export { getCitationGuardPreflight, createCitationGuardTransform, resolveAnswerMode, } from './citation-guard.js';
5
+ export { shouldSkipAnalysis, analyzeRetrievedEvidence, analyzeRetrievedEvidenceStructured, buildEvidenceSection, EVIDENCE_ANALYSIS_TIMEOUT_MS, EVIDENCE_ANALYSIS_MAX_TOKENS, } from './evidence-analysis.js';
6
+ export type { StructuredEvidenceResult } from './evidence-analysis.js';
7
+ export { getEvidenceBudget, applyBudgetToArticles, } from './evidence-budget.js';
8
+ export type { EvidenceBudget } from './evidence-budget.js';
9
+ export { interpretRequest, resolveInterpretationBudget, classifyQueryComplexity, resolveSearchInterpretation, } from './request-interpretation.js';
10
+ export type { SafetyDecision, SafetyReason, RequestInterpretation, InterpretRequestArgs, SearchInterpretation, } from './request-interpretation.js';
11
+ export { getCitationGuardPreflight, createCitationGuardTransform, resolveAnswerMode, buildUnknownRefusal, } from './citation-guard.js';
6
12
  export type { AnswerMode } from './citation-guard.js';
7
13
  export { createCitationAppenderTransform, shouldAppendCitations, selectCitations, formatCitationBlock, } from './citation-appender.js';
8
14
  export type { CitationAppenderConfig } from './citation-appender.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/intelligence/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,eAAe,EACf,wBAAwB,EACxB,qBAAqB,EACrB,cAAc,EACd,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,6BAA6B,GAC9B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,oBAAoB,EACpB,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,yBAAyB,EACzB,4BAA4B,EAC5B,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EACL,+BAA+B,EAC/B,qBAAqB,EACrB,eAAe,EACf,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAErE,YAAY,EACV,eAAe,EACf,uBAAuB,EACvB,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/intelligence/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,eAAe,EACf,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EAAE,mBAAmB,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE/E,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,6BAA6B,GAC9B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,kCAAkC,EAClC,oBAAoB,EACpB,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EACL,gBAAgB,EAChB,2BAA2B,EAC3B,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC;AAErC,YAAY,EACV,cAAc,EACd,YAAY,EACZ,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,yBAAyB,EACzB,4BAA4B,EAC5B,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EACL,+BAA+B,EAC/B,qBAAqB,EACrB,eAAe,EACf,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAErE,YAAY,EACV,eAAe,EACf,uBAAuB,EACvB,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
@@ -3,10 +3,13 @@ import {
3
3
  hasNewSignificantTokens,
4
4
  hasQueryOverlap,
5
5
  shouldReuseSearchContext,
6
- buildLocalSearchQuery,
6
+ buildLocalSearchQuery
7
+ } from "../query/followup.js";
8
+ import {
7
9
  classifyIntent,
10
+ rankArticlesByCategory,
8
11
  rankArticlesByIntent
9
- } from "./intent-detect.js";
12
+ } from "../query/intent.js";
10
13
  import {
11
14
  shouldRunKeywordExtraction,
12
15
  extractSearchKeywords,
@@ -15,14 +18,26 @@ import {
15
18
  import {
16
19
  shouldSkipAnalysis,
17
20
  analyzeRetrievedEvidence,
21
+ analyzeRetrievedEvidenceStructured,
18
22
  buildEvidenceSection,
19
23
  EVIDENCE_ANALYSIS_TIMEOUT_MS,
20
24
  EVIDENCE_ANALYSIS_MAX_TOKENS
21
25
  } from "./evidence-analysis.js";
26
+ import {
27
+ getEvidenceBudget,
28
+ applyBudgetToArticles
29
+ } from "./evidence-budget.js";
30
+ import {
31
+ interpretRequest,
32
+ resolveInterpretationBudget,
33
+ classifyQueryComplexity,
34
+ resolveSearchInterpretation
35
+ } from "./request-interpretation.js";
22
36
  import {
23
37
  getCitationGuardPreflight,
24
38
  createCitationGuardTransform,
25
- resolveAnswerMode
39
+ resolveAnswerMode,
40
+ buildUnknownRefusal
26
41
  } from "./citation-guard.js";
27
42
  import {
28
43
  createCitationAppenderTransform,
@@ -35,19 +50,28 @@ export {
35
50
  EVIDENCE_ANALYSIS_TIMEOUT_MS,
36
51
  KEYWORD_EXTRACTION_TIMEOUT_MS,
37
52
  analyzeRetrievedEvidence,
53
+ analyzeRetrievedEvidenceStructured,
54
+ applyBudgetToArticles,
38
55
  buildEvidenceSection,
39
56
  buildLocalSearchQuery,
57
+ buildUnknownRefusal,
40
58
  classifyIntent,
59
+ classifyQueryComplexity,
41
60
  createCitationAppenderTransform,
42
61
  createCitationGuardTransform,
43
62
  extractSearchKeywords,
44
63
  formatCitationBlock,
45
64
  getCitationGuardPreflight,
65
+ getEvidenceBudget,
46
66
  hasNewSignificantTokens,
47
67
  hasQueryOverlap,
68
+ interpretRequest,
48
69
  isLikelyFollowUp,
70
+ rankArticlesByCategory,
49
71
  rankArticlesByIntent,
50
72
  resolveAnswerMode,
73
+ resolveInterpretationBudget,
74
+ resolveSearchInterpretation,
51
75
  selectCitations,
52
76
  shouldAppendCitations,
53
77
  shouldReuseSearchContext,
@@ -1,5 +1,5 @@
1
1
  import type { KeywordExtractionResult } from './types.js';
2
- export declare const KEYWORD_EXTRACTION_TIMEOUT_MS = 5000;
2
+ export declare const KEYWORD_EXTRACTION_TIMEOUT_MS: 5000;
3
3
  /**
4
4
  * Determines whether to run LLM-based keyword extraction.
5
5
  * Skips extraction for simple single-turn queries with a clear local query.
@@ -1 +1 @@
1
- {"version":3,"file":"keyword-extract.d.ts","sourceRoot":"","sources":["../../src/intelligence/keyword-extract.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAmB,MAAM,YAAY,CAAC;AAE3E,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAElD;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CASV;AAYD;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpG,QAAQ,EAAE;QAAE,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAA;KAAE,CAAC;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAkEnC"}
1
+ {"version":3,"file":"keyword-extract.d.ts","sourceRoot":"","sources":["../../src/intelligence/keyword-extract.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAmB,MAAM,YAAY,CAAC;AAI3E,eAAO,MAAM,6BAA6B,MAA8B,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CASV;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpG,QAAQ,EAAE;QAAE,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAA;KAAE,CAAC;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAkEnC"}
@@ -1,6 +1,8 @@
1
1
  import { generateText } from "ai";
2
- import { tokenize } from "../search/search-utils.js";
3
- const KEYWORD_EXTRACTION_TIMEOUT_MS = 5e3;
2
+ import { tokenize } from "../utils/text.js";
3
+ import { TIMEOUTS } from "../constants.js";
4
+ import { classifyQueryComplexity } from "./request-interpretation.js";
5
+ const KEYWORD_EXTRACTION_TIMEOUT_MS = TIMEOUTS.KEYWORD_EXTRACTION;
4
6
  function shouldRunKeywordExtraction(params) {
5
7
  const { messageCount, localQuery, latestText } = params;
6
8
  if (messageCount < 3) return false;
@@ -9,17 +11,11 @@ function shouldRunKeywordExtraction(params) {
9
11
  if (tokens.length >= 3) return false;
10
12
  return true;
11
13
  }
12
- function classifyComplexity(text) {
13
- const tokens = tokenize(text);
14
- if (tokens.length <= 1 || text.length <= 10) return "simple";
15
- if (tokens.length >= 5 || text.length > 80) return "complex";
16
- return "moderate";
17
- }
18
14
  async function extractSearchKeywords(params) {
19
15
  const { messages, provider, model, abortSignal } = params;
20
16
  const latestMessage = messages[messages.length - 1];
21
17
  const latestText = getMessageText(latestMessage);
22
- const complexity = classifyComplexity(latestText);
18
+ const complexity = classifyQueryComplexity(latestText);
23
19
  const conversationText = messages.slice(-6).map((m) => `${m.role}: ${getMessageText(m)}`).join("\n");
24
20
  const prompt = `\u4F60\u662F\u4E00\u4E2A\u641C\u7D22\u5173\u952E\u8BCD\u63D0\u53D6\u52A9\u624B\u3002\u5206\u6790\u4EE5\u4E0B\u5BF9\u8BDD\uFF0C\u63D0\u53D6\u6700\u4F73\u641C\u7D22\u5173\u952E\u8BCD\u3002
25
21
 
@@ -0,0 +1,40 @@
1
+ import { type EvidenceBudget } from './evidence-budget.js';
2
+ import type { QueryIntentCategory } from '../query/types.js';
3
+ import type { AnswerMode } from './citation-guard.js';
4
+ import type { CachedSearchContext } from '../search/types.js';
5
+ import type { QueryComplexity } from './types.js';
6
+ export type SafetyDecision = 'allow' | 'constrain' | 'refuse';
7
+ export type SafetyReason = 'privacy' | 'policy' | 'unsupported_capability' | 'insufficient_public_evidence';
8
+ export interface RequestInterpretation {
9
+ conversation: {
10
+ shouldReuseContext: boolean;
11
+ };
12
+ topic: {
13
+ primary: QueryIntentCategory;
14
+ };
15
+ answer: {
16
+ contract: AnswerMode;
17
+ };
18
+ safety: {
19
+ decision: SafetyDecision;
20
+ reason?: SafetyReason;
21
+ };
22
+ reasoning: {
23
+ complexity: QueryComplexity;
24
+ };
25
+ }
26
+ export interface InterpretRequestArgs {
27
+ latestText: string;
28
+ cachedContext?: CachedSearchContext;
29
+ userTurnCount?: number;
30
+ now?: number;
31
+ }
32
+ export interface SearchInterpretation {
33
+ interpretation: RequestInterpretation;
34
+ budget: EvidenceBudget;
35
+ }
36
+ export declare function classifyQueryComplexity(text: string): QueryComplexity;
37
+ export declare function interpretRequest(args: InterpretRequestArgs): RequestInterpretation;
38
+ export declare function resolveInterpretationBudget(interpretation: RequestInterpretation): EvidenceBudget;
39
+ export declare function resolveSearchInterpretation(args: InterpretRequestArgs): SearchInterpretation;
40
+ //# sourceMappingURL=request-interpretation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-interpretation.d.ts","sourceRoot":"","sources":["../../src/intelligence/request-interpretation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAG7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE9D,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,QAAQ,GACR,wBAAwB,GACxB,8BAA8B,CAAC;AAEnC,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE;QACZ,kBAAkB,EAAE,OAAO,CAAC;KAC7B,CAAC;IACF,KAAK,EAAE;QACL,OAAO,EAAE,mBAAmB,CAAC;KAC9B,CAAC;IACF,MAAM,EAAE;QACN,QAAQ,EAAE,UAAU,CAAC;KACtB,CAAC;IACF,MAAM,EAAE;QACN,QAAQ,EAAE,cAAc,CAAC;QACzB,MAAM,CAAC,EAAE,YAAY,CAAC;KACvB,CAAC;IACF,SAAS,EAAE;QACT,UAAU,EAAE,eAAe,CAAC;KAC7B,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,qBAAqB,CAAC;IACtC,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAQrE;AAYD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,qBAAqB,CAkClF;AAED,wBAAgB,2BAA2B,CACzC,cAAc,EAAE,qBAAqB,GACpC,cAAc,CAKhB;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,oBAAoB,GACzB,oBAAoB,CAMtB"}