@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
@@ -0,0 +1,71 @@
1
+ import { getEvidenceBudget } from "./evidence-budget.js";
2
+ import { classifyIntent } from "../query/intent.js";
3
+ import { shouldReuseSearchContext } from "../query/followup.js";
4
+ import { resolveAnswerMode } from "./citation-guard.js";
5
+ function classifyQueryComplexity(text) {
6
+ const trimmed = text.trim();
7
+ if (!trimmed || trimmed.length <= 10) return "simple";
8
+ if (trimmed.length > 80) return "complex";
9
+ const tokenCount = trimmed.split(/\s+/).filter(Boolean).length;
10
+ if (tokenCount <= 1) return "simple";
11
+ if (tokenCount >= 5) return "complex";
12
+ return "moderate";
13
+ }
14
+ function mapSafetyDecision(answerContract) {
15
+ if (answerContract === "unknown") {
16
+ return { decision: "refuse", reason: "privacy" };
17
+ }
18
+ return { decision: "allow" };
19
+ }
20
+ function interpretRequest(args) {
21
+ const {
22
+ latestText,
23
+ cachedContext,
24
+ userTurnCount = 1,
25
+ now = Date.now()
26
+ } = args;
27
+ const shouldReuseContext = shouldReuseSearchContext({
28
+ latestText,
29
+ cachedContext,
30
+ userTurnCount,
31
+ now
32
+ });
33
+ const topic = classifyIntent(latestText);
34
+ const answerContract = resolveAnswerMode(latestText);
35
+ const complexity = classifyQueryComplexity(latestText);
36
+ const safety = mapSafetyDecision(answerContract);
37
+ return {
38
+ conversation: {
39
+ shouldReuseContext
40
+ },
41
+ topic: {
42
+ primary: topic
43
+ },
44
+ answer: {
45
+ contract: answerContract
46
+ },
47
+ safety,
48
+ reasoning: {
49
+ complexity
50
+ }
51
+ };
52
+ }
53
+ function resolveInterpretationBudget(interpretation) {
54
+ return getEvidenceBudget(
55
+ interpretation.reasoning.complexity,
56
+ interpretation.answer.contract
57
+ );
58
+ }
59
+ function resolveSearchInterpretation(args) {
60
+ const interpretation = interpretRequest(args);
61
+ return {
62
+ interpretation,
63
+ budget: resolveInterpretationBudget(interpretation)
64
+ };
65
+ }
66
+ export {
67
+ classifyQueryComplexity,
68
+ interpretRequest,
69
+ resolveInterpretationBudget,
70
+ resolveSearchInterpretation
71
+ };
@@ -3,6 +3,7 @@ export interface ResponseTemplate {
3
3
  en: string[];
4
4
  }
5
5
  export declare const PRIVACY_REFUSAL_TEMPLATES: Record<string, ResponseTemplate>;
6
+ export declare const UNKNOWN_REFUSAL_TEMPLATES: ResponseTemplate;
6
7
  export declare const NO_ARTICLE_TEMPLATES: ResponseTemplate;
7
8
  export declare const ARTICLE_COUNT_TEMPLATES: ResponseTemplate;
8
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"response-templates.d.ts","sourceRoot":"","sources":["../../src/intelligence/response-templates.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,EAAE,EAAE,MAAM,EAAE,CAAC;CACd;AAED,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAyEtE,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,gBAWlC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,gBAWrC,CAAC;AAEF;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI9E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,gBAAgB,EAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GACpC,MAAM,CAMR"}
1
+ {"version":3,"file":"response-templates.d.ts","sourceRoot":"","sources":["../../src/intelligence/response-templates.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,EAAE,EAAE,MAAM,EAAE,CAAC;CACd;AAED,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAyEtE,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,gBAWvC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,gBAWlC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,gBAWrC,CAAC;AAEF;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI9E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,gBAAgB,EAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GACpC,MAAM,CAMR"}
@@ -72,6 +72,18 @@ const PRIVACY_REFUSAL_TEMPLATES = {
72
72
  ]
73
73
  }
74
74
  };
75
+ const UNKNOWN_REFUSAL_TEMPLATES = {
76
+ zh: [
77
+ "\u8FD9\u4E2A\u4FE1\u606F\u672A\u5728\u535A\u5BA2\u4E2D\u516C\u5F00\u3002",
78
+ "\u8FD9\u7C7B\u79C1\u4EBA\u4FE1\u606F\u535A\u4E3B\u6CA1\u6709\u516C\u5F00\u5206\u4EAB\u3002",
79
+ "\u62B1\u6B49\uFF0C\u8FD9\u4E2A\u4FE1\u606F\u4E0D\u5728\u535A\u5BA2\u5185\u5BB9\u8303\u56F4\u5185\u3002"
80
+ ],
81
+ en: [
82
+ "This information is not disclosed on the blog.",
83
+ "The blogger has not shared this private information.",
84
+ "Sorry, this information is not available in the blog."
85
+ ]
86
+ };
75
87
  const NO_ARTICLE_TEMPLATES = {
76
88
  zh: [
77
89
  "\u6839\u636E\u535A\u5BA2\u5185\u5BB9\u641C\u7D22\uFF0C\u76EE\u524D\u6CA1\u6709\u627E\u5230\u4E0E\u8FD9\u4E2A\u4E3B\u9898\u76F4\u63A5\u76F8\u5173\u7684\u6587\u7AE0\u3002\u4F60\u53EF\u4EE5\u5C1D\u8BD5\u7528\u5176\u4ED6\u5173\u952E\u8BCD\u641C\u7D22\uFF0C\u6216\u8005\u95EE\u6211\u5176\u4ED6\u95EE\u9898\u3002",
@@ -112,6 +124,7 @@ export {
112
124
  ARTICLE_COUNT_TEMPLATES,
113
125
  NO_ARTICLE_TEMPLATES,
114
126
  PRIVACY_REFUSAL_TEMPLATES,
127
+ UNKNOWN_REFUSAL_TEMPLATES,
115
128
  pickTemplate,
116
129
  pickTemplateWithVars
117
130
  };
@@ -1,7 +1,3 @@
1
- import type { DynamicLayerConfig } from './types.js';
2
- /**
3
- * Dynamic layer: per-request search results and evidence analysis.
4
- * Built fresh on every chat request.
5
- */
1
+ import type { DynamicLayerConfig } from "./types.js";
6
2
  export declare function buildDynamicLayer(config: DynamicLayerConfig): string;
7
3
  //# sourceMappingURL=dynamic-layer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic-layer.d.ts","sourceRoot":"","sources":["../../src/prompt/dynamic-layer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAwBrD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CA+CpE"}
1
+ {"version":3,"file":"dynamic-layer.d.ts","sourceRoot":"","sources":["../../src/prompt/dynamic-layer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA8IrD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CA6HpE"}
@@ -7,7 +7,20 @@ const LABELS = {
7
7
  summary: "\u6458\u8981",
8
8
  keyPoints: "\u8981\u70B9",
9
9
  excerpt: "\u5185\u5BB9\u8282\u9009",
10
- instruction: (query) => `\u57FA\u4E8E\u4EE5\u4E0A\u5185\u5BB9\u56DE\u7B54\u7528\u6237\u5173\u4E8E\u300C${query}\u300D\u7684\u95EE\u9898\u3002\u5982\u679C\u4EE5\u4E0A\u5185\u5BB9\u4E0E\u95EE\u9898\u4E0D\u76F8\u5173\uFF0C\u5982\u5B9E\u544A\u77E5\u5E76\u63D0\u4F9B\u529B\u6240\u80FD\u53CA\u7684\u5E2E\u52A9\u3002`
10
+ readingTime: (minutes) => `\u9605\u8BFB\u65F6\u95F4\uFF1A\u7EA6 ${minutes} \u5206\u949F`,
11
+ instruction: (query) => `\u57FA\u4E8E\u4EE5\u4E0A\u5185\u5BB9\u56DE\u7B54\u7528\u6237\u5173\u4E8E\u300C${query}\u300D\u7684\u95EE\u9898\u3002\u5982\u679C\u4EE5\u4E0A\u5185\u5BB9\u4E0E\u95EE\u9898\u4E0D\u76F8\u5173\uFF0C\u5982\u5B9E\u544A\u77E5\u5E76\u63D0\u4F9B\u529B\u6240\u80FD\u53CA\u7684\u5E2E\u52A9\u3002`,
12
+ answerModeHint: (mode) => {
13
+ const hints = {
14
+ fact: "\u5F53\u524D\u4E3A\u4E8B\u5B9E\u67E5\u8BE2\u6A21\u5F0F\uFF1A\u5148\u7ED9\u7ED3\u8BBA\uFF0C\u518D\u8865\u4F9D\u636E\uFF1B\u5982\u6709\u76F4\u63A5\u5BF9\u5E94\u7684\u6587\u7AE0\uFF0C\u70B9\u660E\u6807\u9898\u6216\u7ED9\u51FA\u94FE\u63A5\u3002",
15
+ count: "\u5F53\u524D\u4E3A\u8BA1\u6570\u6A21\u5F0F\uFF1A\u7B2C\u4E00\u53E5\u5148\u8BF4\u6570\u5B57\u6216\u300C\u81F3\u5C11 X\u300D\uFF0C\u7981\u6B62\u4F2A\u7CBE\u786E\u3002",
16
+ list: "\u5F53\u524D\u4E3A\u5217\u8868\u6A21\u5F0F\uFF1A\u76F4\u63A5\u5217 2-6 \u9879\u540C\u4E00\u7EF4\u5EA6\u7684\u5185\u5BB9\u3002",
17
+ opinion: "\u5F53\u524D\u4E3A\u89C2\u70B9\u6A21\u5F0F\uFF1A\u5148\u300C\u6211\u89C9\u5F97/\u6211\u7684\u770B\u6CD5\u662F\u300D\uFF0C\u518D\u7528 2-3 \u4E2A\u89C2\u70B9\u5C55\u5F00\u3002",
18
+ recommendation: "\u5F53\u524D\u4E3A\u63A8\u8350\u6A21\u5F0F\uFF1A\u5148\u7ED9 2-4 \u4E2A\u63A8\u8350\u9879\uFF0C\u518D\u8BF4\u660E\u7406\u7531\u3002",
19
+ unknown: "\u5F53\u524D\u4E3A\u672A\u77E5/\u9690\u79C1\u6A21\u5F0F\uFF1A\u7B2C\u4E00\u53E5\u5FC5\u987B\u5305\u542B\u300C\u672A\u516C\u5F00\u300D\u6216\u300C\u4E0D\u63D0\u4F9B\u300D\uFF0C1-2 \u53E5\u6536\u5C3E\u3002",
20
+ general: ""
21
+ };
22
+ return hints[mode] || "";
23
+ }
11
24
  },
12
25
  en: {
13
26
  relatedContent: "Content related to the current question",
@@ -16,47 +29,170 @@ const LABELS = {
16
29
  summary: "Summary",
17
30
  keyPoints: "Key points",
18
31
  excerpt: "Excerpt",
19
- instruction: (query) => `Answer the user's question about "${query}" based on the content above. If the above content is not relevant, say so honestly and provide whatever help you can.`
32
+ readingTime: (minutes) => `Reading time: ~${minutes} min`,
33
+ instruction: (query) => `Answer the user's question about "${query}" based on the content above. If the above content is not relevant, say so honestly and provide whatever help you can.`,
34
+ answerModeHint: (mode) => {
35
+ const hints = {
36
+ fact: "Current mode: fact query. Give conclusion first, then supporting evidence; cite article title/link if directly relevant.",
37
+ count: 'Current mode: count query. State the number or "at least X" in the first sentence; avoid false precision.',
38
+ list: "Current mode: list query. List 2-6 items of the same dimension directly.",
39
+ opinion: 'Current mode: opinion query. Start with "I think / In my view", then expand with 2-3 clear points.',
40
+ recommendation: "Current mode: recommendation query. Give 2-4 recommendations first, then explain why.",
41
+ unknown: 'Current mode: unknown/privacy query. First sentence must include "not disclosed" or "not available", wrap up in 1-2 sentences.',
42
+ general: ""
43
+ };
44
+ return hints[mode] || "";
45
+ }
20
46
  }
21
47
  };
48
+ function matchesCondition(ctx, promptContext) {
49
+ if (!ctx.matchCondition) return true;
50
+ const { queryPatterns, categories, tags } = ctx.matchCondition;
51
+ if (queryPatterns?.length) {
52
+ const matches = queryPatterns.some((p) => p.test(promptContext.userQuery));
53
+ if (!matches) return false;
54
+ }
55
+ if (categories?.length) {
56
+ const articleCategories = new Set(
57
+ promptContext.articles.flatMap((a) => a.categories ?? [])
58
+ );
59
+ const hasMatch = categories.some((c) => articleCategories.has(c));
60
+ if (!hasMatch) return false;
61
+ }
62
+ if (tags?.length) {
63
+ const articleTags = new Set(
64
+ promptContext.articles.flatMap((a) => a.keyPoints ?? [])
65
+ );
66
+ const hasMatch = tags.some((t) => articleTags.has(t));
67
+ if (!hasMatch) return false;
68
+ }
69
+ return true;
70
+ }
71
+ function getContextSectionsByPosition(extensions, promptContext) {
72
+ const result = {
73
+ beforeArticles: [],
74
+ afterArticles: [],
75
+ beforeFacts: [],
76
+ afterFacts: []
77
+ };
78
+ if (!extensions?.context?.length) return result;
79
+ const positionMap = {
80
+ "before-articles": "beforeArticles",
81
+ "after-articles": "afterArticles",
82
+ "before-facts": "beforeFacts",
83
+ "after-facts": "afterFacts"
84
+ };
85
+ for (const ctx of extensions.context) {
86
+ if (!matchesCondition(ctx, promptContext)) continue;
87
+ const content = typeof ctx.content === "function" ? ctx.content(promptContext) : ctx.content;
88
+ if (content) {
89
+ const section = `## ${ctx.sectionTitle}
90
+ ${content}`;
91
+ const positionKey = positionMap[ctx.position];
92
+ if (positionKey) {
93
+ result[positionKey].push(section);
94
+ }
95
+ }
96
+ }
97
+ return result;
98
+ }
22
99
  function buildDynamicLayer(config) {
23
- const { userQuery, articles, projects, evidenceSection, factSection } = config;
100
+ const {
101
+ userQuery,
102
+ articles,
103
+ projects,
104
+ evidenceSection,
105
+ factSection,
106
+ answerMode,
107
+ extensions
108
+ } = config;
24
109
  const lang = getLang(config.lang);
25
110
  const l = LABELS[lang];
26
- if (!articles.length && !projects.length && !factSection) return "";
111
+ const promptContext = {
112
+ userQuery,
113
+ lang,
114
+ articles,
115
+ projects
116
+ };
117
+ const contextSections = getContextSectionsByPosition(
118
+ extensions,
119
+ promptContext
120
+ );
121
+ const hasContextSections = Object.values(contextSections).some(
122
+ (arr) => arr.length > 0
123
+ );
124
+ if (!articles.length && !projects.length && !factSection && !evidenceSection && !config.chunksSection && !hasContextSections)
125
+ return "";
27
126
  const lines = [];
28
127
  lines.push(`## ${l.relatedContent}`);
128
+ const chunksSection = config.chunksSection || "";
129
+ const preferInjectedChunks = config.preferInjectedChunks === true && !!chunksSection;
130
+ if (chunksSection) {
131
+ lines.push("");
132
+ lines.push("### \u5F53\u524D\u6587\u7AE0\u76F8\u5173\u539F\u6587\u6BB5\u843D");
133
+ lines.push(
134
+ "\u56DE\u7B54\u5F53\u524D\u6587\u7AE0\u5C40\u90E8\u9605\u8BFB\u95EE\u9898\u65F6\uFF0C\u4F18\u5148\u4F9D\u636E\u4E0B\u9762\u8FD9\u4E9B\u539F\u6587\u6BB5\u843D\uFF0C\u800C\u4E0D\u662F\u53EA\u4F9D\u636E\u6458\u8981\u3002"
135
+ );
136
+ lines.push(chunksSection);
137
+ lines.push("");
138
+ }
139
+ if (contextSections.beforeArticles.length > 0) {
140
+ lines.push("");
141
+ lines.push(contextSections.beforeArticles.join("\n\n"));
142
+ }
29
143
  if (articles.length) {
30
144
  lines.push("");
31
145
  lines.push(`### ${l.relatedArticles}`);
32
146
  for (const article of articles.slice(0, 8)) {
33
147
  lines.push(`**[${article.title}](${article.url})**`);
34
- if (article.summary) lines.push(`${l.summary}\uFF1A${article.summary.slice(0, 120)}`);
35
- if (article.keyPoints.length) {
36
- lines.push(`${l.keyPoints}\uFF1A${article.keyPoints.slice(0, 3).join("\uFF1B")}`);
148
+ if (article.readingTime) lines.push(l.readingTime(article.readingTime));
149
+ if (!preferInjectedChunks && article.summary)
150
+ lines.push(`${l.summary}\uFF1A${article.summary.slice(0, 120)}`);
151
+ if (!preferInjectedChunks && article.keyPoints.length) {
152
+ lines.push(
153
+ `${l.keyPoints}\uFF1A${article.keyPoints.slice(0, 3).join("\uFF1B")}`
154
+ );
37
155
  }
38
- if (article.fullContent) {
156
+ if (!preferInjectedChunks && article.fullContent) {
39
157
  lines.push(`${l.excerpt}\uFF1A${article.fullContent.slice(0, 600)}`);
40
158
  }
41
159
  lines.push("");
42
160
  }
43
161
  }
162
+ if (contextSections.afterArticles.length > 0) {
163
+ lines.push(contextSections.afterArticles.join("\n\n"));
164
+ }
44
165
  if (projects.length) {
45
166
  lines.push(`### ${l.relatedProjects}`);
46
167
  for (const project of projects.slice(0, 4)) {
47
- lines.push(`- **[${project.name}](${project.url})**\uFF1A${project.description.slice(0, 100)}`);
168
+ lines.push(
169
+ `- **[${project.name}](${project.url})**\uFF1A${project.description.slice(0, 100)}`
170
+ );
48
171
  }
49
172
  lines.push("");
50
173
  }
174
+ if (contextSections.beforeFacts.length > 0) {
175
+ lines.push(contextSections.beforeFacts.join("\n\n"));
176
+ }
51
177
  if (factSection) {
52
178
  lines.push(factSection);
53
179
  lines.push("");
54
180
  }
181
+ if (contextSections.afterFacts.length > 0) {
182
+ lines.push(contextSections.afterFacts.join("\n\n"));
183
+ }
55
184
  if (evidenceSection) {
56
185
  lines.push(evidenceSection);
57
186
  }
58
187
  lines.push(`---`);
59
188
  lines.push(l.instruction(userQuery.slice(0, 50)));
189
+ if (answerMode && answerMode !== "general") {
190
+ const hint = l.answerModeHint(answerMode);
191
+ if (hint) {
192
+ lines.push("");
193
+ lines.push(hint);
194
+ }
195
+ }
60
196
  return lines.join("\n");
61
197
  }
62
198
  export {
@@ -1,3 +1,3 @@
1
- import type { PromptBuildConfig } from './types.js';
1
+ import type { PromptBuildConfig } from "./types.js";
2
2
  export declare function buildSystemPrompt(config: PromptBuildConfig): string;
3
3
  //# sourceMappingURL=prompt-builder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-builder.d.ts","sourceRoot":"","sources":["../../src/prompt/prompt-builder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAUnE"}
1
+ {"version":3,"file":"prompt-builder.d.ts","sourceRoot":"","sources":["../../src/prompt/prompt-builder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAcnE"}
@@ -5,7 +5,11 @@ function buildSystemPrompt(config) {
5
5
  const lang = config.static.lang || config.dynamic.lang;
6
6
  const layers = [
7
7
  buildStaticLayer(config.static),
8
- buildSemiStaticLayer({ ...config.semiStatic, lang }),
8
+ buildSemiStaticLayer({
9
+ ...config.semiStatic,
10
+ lang,
11
+ preferArticleLocal: config.dynamic.preferInjectedChunks
12
+ }),
9
13
  buildDynamicLayer(config.dynamic)
10
14
  ].filter(Boolean);
11
15
  return layers.join("\n\n");
@@ -1,3 +1,3 @@
1
- import type { SemiStaticLayerConfig } from './types.js';
1
+ import type { SemiStaticLayerConfig } from "./types.js";
2
2
  export declare function buildSemiStaticLayer(config: SemiStaticLayerConfig): string;
3
3
  //# sourceMappingURL=semi-static-layer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"semi-static-layer.d.ts","sourceRoot":"","sources":["../../src/prompt/semi-static-layer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGxD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CA+B1E"}
1
+ {"version":3,"file":"semi-static-layer.d.ts","sourceRoot":"","sources":["../../src/prompt/semi-static-layer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGxD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CA8C1E"}
@@ -1,6 +1,6 @@
1
1
  import { t, getLang } from "../utils/i18n.js";
2
2
  function buildSemiStaticLayer(config) {
3
- const { authorContext, lang: configLang } = config;
3
+ const { authorContext, lang: configLang, preferArticleLocal } = config;
4
4
  if (!authorContext) return "";
5
5
  const lang = getLang(configLang);
6
6
  const lines = [];
@@ -9,17 +9,27 @@ function buildSemiStaticLayer(config) {
9
9
  const totalPosts = posts.length;
10
10
  const categories = [...new Set(posts.map((p) => p.category).filter(Boolean))];
11
11
  const recentPosts = posts.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()).slice(0, 10);
12
- lines.push("## " + t("ai.semiStatic.blogOverview", lang));
13
- lines.push("- " + t("ai.semiStatic.totalPosts", lang, { count: totalPosts }));
14
- if (categories.length) {
15
- lines.push("- " + t("ai.semiStatic.mainCategories", lang, { categories: categories.slice(0, 8).join(lang === "zh" ? "\u3001" : ", ") }));
16
- }
17
- lines.push("");
18
- lines.push("## " + t("ai.semiStatic.latestArticles", lang));
19
- for (const post of recentPosts) {
20
- const date = post.date ? new Date(post.date).toISOString().slice(0, 10) : "";
21
- const summary = post.summary ? ` \u2014 ${post.summary.slice(0, 60)}` : "";
22
- lines.push(`- [${post.title}](${post.url})${date ? ` (${date})` : ""}${summary}`);
12
+ if (!preferArticleLocal) {
13
+ lines.push("## " + t("ai.semiStatic.blogOverview", lang));
14
+ lines.push(
15
+ "- " + t("ai.semiStatic.totalPosts", lang, { count: totalPosts })
16
+ );
17
+ if (categories.length) {
18
+ lines.push(
19
+ "- " + t("ai.semiStatic.mainCategories", lang, {
20
+ categories: categories.slice(0, 8).join(lang === "zh" ? "\u3001" : ", ")
21
+ })
22
+ );
23
+ }
24
+ lines.push("");
25
+ lines.push("## " + t("ai.semiStatic.latestArticles", lang));
26
+ for (const post of recentPosts) {
27
+ const date = post.date ? new Date(post.date).toISOString().slice(0, 10) : "";
28
+ const summary = post.summary ? ` \u2014 ${post.summary.slice(0, 60)}` : "";
29
+ lines.push(
30
+ `- [${post.title}](${post.url})${date ? ` (${date})` : ""}${summary}`
31
+ );
32
+ }
23
33
  }
24
34
  return lines.join("\n");
25
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"static-layer.d.ts","sourceRoot":"","sources":["../../src/prompt/static-layer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAkIpD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAqClE"}
1
+ {"version":3,"file":"static-layer.d.ts","sourceRoot":"","sources":["../../src/prompt/static-layer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA4IpD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAwClE"}
@@ -11,7 +11,12 @@ const PROMPTS = {
11
11
  "\u5148\u7B80\u6D01\u56DE\u7B54\u95EE\u9898\u6838\u5FC3",
12
12
  "\u7136\u540E\u5217\u51FA\u76F8\u5173\u7684\u535A\u5BA2\u6587\u7AE0\u63A8\u8350\uFF08\u4F7F\u7528 Markdown \u94FE\u63A5\uFF1A[\u6587\u7AE0\u6807\u9898](URL)\uFF09",
13
13
  "\u5982\u6709\u76F8\u5173\u5916\u90E8\u8D44\u6E90\uFF0C\u9644\u4E0A\u63A8\u8350\uFF08\u4F7F\u7528 Markdown \u94FE\u63A5\uFF1A[\u8D44\u6E90\u540D](URL)\uFF09",
14
- "\u4FDD\u6301\u56DE\u7B54\u7D27\u51D1\uFF0C\u907F\u514D\u5197\u957F"
14
+ "\u4FDD\u6301\u56DE\u7B54\u7D27\u51D1\uFF0C\u907F\u514D\u5197\u957F",
15
+ "\u804A\u5929\u754C\u9762**\u652F\u6301\u6E32\u67D3**\u4EE5\u4E0B\u53EF\u89C6\u5316\u683C\u5F0F\uFF08\u8BF7\u5728\u5408\u9002\u65F6\u4E3B\u52A8\u4F7F\u7528\uFF09\uFF1A",
16
+ " - ````mermaid` \u4EE3\u7801\u5757 \u2192 \u6E32\u67D3\u4E3A\u4EA4\u4E92\u5F0F\u6D41\u7A0B\u56FE/\u65F6\u5E8F\u56FE/\u7C7B\u56FE\u7B49\uFF08\u652F\u6301\u7F29\u653E\u3001\u5168\u5C4F\u3001\u6E90\u7801\u67E5\u770B\uFF09",
17
+ " - ````markmap` \u4EE3\u7801\u5757 \u2192 \u6E32\u67D3\u4E3A\u4EA4\u4E92\u5F0F\u601D\u7EF4\u5BFC\u56FE/\u77E5\u8BC6\u56FE\u8C31",
18
+ " - \u5176\u4ED6\u8BED\u8A00\u7684\u4EE3\u7801\u5757 \u2192 \u8BED\u6CD5\u9AD8\u4EAE + \u590D\u5236\u6309\u94AE",
19
+ "\u5F53\u7528\u6237\u8BE2\u95EE\u67B6\u6784\u3001\u6D41\u7A0B\u3001\u5BF9\u6BD4\u5173\u7CFB\u65F6\uFF0C**\u4F18\u5148\u4F7F\u7528 Mermaid \u56FE\u8868\u8F85\u52A9\u8BF4\u660E**\uFF1B\u5F53\u7528\u6237\u8BE2\u95EE\u77E5\u8BC6\u4F53\u7CFB\u3001\u6982\u5FF5\u5C42\u7EA7\u65F6\uFF0C**\u4F18\u5148\u4F7F\u7528 Markmap \u601D\u7EF4\u5BFC\u56FE**"
15
20
  ],
16
21
  principles: [
17
22
  "\u4F18\u5148\u63A8\u8350\u4E0E\u95EE\u9898\u76F4\u63A5\u76F8\u5173\u7684\u535A\u5BA2\u6587\u7AE0",
@@ -67,7 +72,12 @@ const PROMPTS = {
67
72
  "First, answer the core question concisely",
68
73
  "Then list related blog post recommendations (using Markdown links: [Article Title](URL))",
69
74
  "If there are relevant external resources, include them (using Markdown links: [Resource Name](URL))",
70
- "Keep responses concise, avoid verbosity"
75
+ "Keep responses concise, avoid verbosity",
76
+ "The chat interface **supports rendering** these visual formats (use them proactively when appropriate):",
77
+ " - ````mermaid` code blocks \u2192 rendered as interactive flowcharts/sequence diagrams/class diagrams (with zoom, fullscreen, source view)",
78
+ " - ````markmap` code blocks \u2192 rendered as interactive mind maps/knowledge graphs",
79
+ " - Other language code blocks \u2192 syntax highlighting + copy button",
80
+ "When users ask about architecture, workflows, or comparisons, **prefer Mermaid diagrams**; for knowledge hierarchies or concept overviews, **prefer Markmap mind maps**"
71
81
  ],
72
82
  principles: [
73
83
  "Prioritize blog posts directly related to the question",
@@ -144,10 +154,33 @@ function buildStaticLayer(config) {
144
154
  ...p.answerModes.map((s) => `- ${s}`),
145
155
  "",
146
156
  "## " + t("ai.prompt.section.preOutputChecks", lang),
147
- ...p.preOutputChecks.map((s) => `- ${s}`)
148
- ];
157
+ ...p.preOutputChecks.map((s) => `- ${s}`),
158
+ "",
159
+ buildToolsSection(lang),
160
+ config.voiceStylePrompt ?? ""
161
+ ].filter(Boolean);
149
162
  return parts.join("\n").trim();
150
163
  }
164
+ function buildToolsSection(lang) {
165
+ const isZh = lang === "zh";
166
+ const header = isZh ? "## \u5DE5\u5177\u4F7F\u7528" : "## Tool Usage";
167
+ const intro = isZh ? "\u5F53\u7528\u6237\u8BF7\u6C42\u6267\u884C\u64CD\u4F5C\uFF08\u5982\u5207\u6362\u4E3B\u9898\u3001\u8DF3\u8F6C\u6587\u7AE0\u3001\u6EDA\u52A8\u5230\u7AE0\u8282\u7B49\uFF09\u65F6\uFF0C\u8BF7\u76F4\u63A5\u8C03\u7528\u76F8\u5E94\u7684\u5DE5\u5177\uFF0C\u800C\u4E0D\u662F\u89E3\u91CA\u5982\u4F55\u64CD\u4F5C\u3002" : "When the user requests an action (e.g., toggle theme, navigate to article, scroll to section), call the appropriate tool directly instead of explaining how to do it.";
168
+ const followUpRule = isZh ? "\u5DE5\u5177\u6267\u884C\u5B8C\u6210\u540E\uFF0C\u4F60\u5FC5\u987B\u6839\u636E\u5DE5\u5177\u7ED3\u679C\u7EE7\u7EED\u56DE\u590D\uFF1A\u5982\u679C\u662F\u52A8\u4F5C\u578B\u5DE5\u5177\uFF08\u5982\u5207\u6362\u4E3B\u9898\u3001\u6EDA\u52A8\u3001\u8DF3\u8F6C\u3001\u504F\u597D\u8BBE\u7F6E\uFF09\uFF0C\u7528 1 \u53E5\u7B80\u77ED\u786E\u8BA4\u8BDD\u672F\u8BF4\u660E\u5DF2\u7ECF\u5B8C\u6210\u7684\u52A8\u4F5C\uFF0C\u4E0D\u8981\u518D\u6B21\u8C03\u7528\u540C\u4E00\u4E2A\u5DE5\u5177\uFF0C\u4E5F\u4E0D\u8981\u8F93\u51FA\u201C\u65E0\u6CD5\u56DE\u7B54\u201D\u4E4B\u7C7B\u7684\u515C\u5E95\u6587\u672C\uFF1B\u5982\u679C\u662F\u67E5\u8BE2\u578B\u5DE5\u5177\uFF08\u5982 searchArticles\uFF09\uFF0C\u5148\u5229\u7528\u5DE5\u5177\u7ED3\u679C\u56DE\u7B54\uFF0C\u518D\u7ED9\u51FA\u63A8\u8350\u6216\u4E0B\u4E00\u6B65\u8BF4\u660E\u3002" : "After a tool finishes, you MUST continue the reply based on the tool result: for action tools (such as theme toggle, scrolling, navigation, or preference updates), give a single short confirmation sentence describing the completed action, do not call the same tool again, and do not output fallback text like \u201CI cannot answer\u201D; for query tools (such as searchArticles), answer using the tool result first, then provide recommendations or next steps.";
169
+ const examples = isZh ? [
170
+ "\u793A\u4F8B\uFF1A",
171
+ '- \u7528\u6237: "\u5207\u6362\u5230\u6697\u6A21\u5F0F" \u2192 \u8C03\u7528 toggleTheme({ theme: "dark" })',
172
+ "- toggleTheme \u6210\u529F\u540E \u2192 \u56DE\u590D\u201C\u5DF2\u4E3A\u4F60\u5207\u6362\u5230\u6697\u6A21\u5F0F\u3002\u201D",
173
+ '- \u7528\u6237: "\u5E2E\u6211\u627E AI \u76F8\u5173\u7684\u6587\u7AE0" \u2192 \u8C03\u7528 searchArticles({ query: "AI" })\uFF0C\u7136\u540E\u6839\u636E\u7ED3\u679C\u56DE\u7B54',
174
+ '- \u7528\u6237: "\u8DF3\u5230\u7B2C\u4E09\u7AE0" \u2192 \u8C03\u7528 scrollToSection({ sectionId: "\u4E09\u7CFB\u7EDF\u67B6\u6784\u8BBE\u8BA1" })'
175
+ ] : [
176
+ "Examples:",
177
+ '- User: "switch to dark mode" \u2192 Call toggleTheme({ theme: "dark" })',
178
+ "- After toggleTheme succeeds \u2192 Reply \u201CI\u2019ve switched the theme to dark mode.\u201D",
179
+ '- User: "find articles about AI" \u2192 Call searchArticles({ query: "AI" }), then respond based on results',
180
+ '- User: "jump to chapter 3" \u2192 Call scrollToSection({ sectionId: "chapter-3" })'
181
+ ];
182
+ return [header, "", intro, "", followUpRule, "", ...examples].join("\n");
183
+ }
151
184
  export {
152
185
  buildStaticLayer
153
186
  };
@@ -1,25 +1,30 @@
1
- import type { ArticleContext, ProjectContext } from '../search/types.js';
2
- import type { AuthorContextFile, VoiceProfile } from '../data/types.js';
1
+ import type { ArticleContext, ProjectContext } from "../search/types.js";
2
+ import type { AuthorContextFile } from "../data/types.js";
3
+ import type { LoadedExtensions } from "../extensions/types.js";
3
4
  export interface StaticLayerConfig {
4
5
  authorName: string;
5
6
  siteUrl: string;
6
7
  description?: string;
7
8
  systemPromptOverride?: string;
9
+ voiceStylePrompt?: string;
8
10
  lang?: string;
9
11
  }
10
12
  export interface SemiStaticLayerConfig {
11
13
  authorContext: AuthorContextFile | null;
12
- voiceProfile: VoiceProfile | null;
13
14
  lang?: string;
15
+ preferArticleLocal?: boolean;
14
16
  }
15
17
  export interface DynamicLayerConfig {
16
18
  userQuery: string;
17
19
  articles: ArticleContext[];
18
20
  projects: ProjectContext[];
19
21
  evidenceSection?: string;
20
- /** Pre-built verified-facts prompt section from Fact Registry */
21
22
  factSection?: string;
23
+ answerMode?: "fact" | "count" | "list" | "opinion" | "recommendation" | "unknown" | "general";
22
24
  lang?: string;
25
+ extensions?: LoadedExtensions;
26
+ chunksSection?: string;
27
+ preferInjectedChunks?: boolean;
23
28
  }
24
29
  export interface PromptBuildConfig {
25
30
  static: StaticLayerConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/prompt/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAExE,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACxC,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,UAAU,EAAE,qBAAqB,CAAC;IAClC,OAAO,EAAE,kBAAkB,CAAC;CAC7B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/prompt/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EACP,MAAM,GACN,OAAO,GACP,MAAM,GACN,SAAS,GACT,gBAAgB,GAChB,SAAS,GACT,SAAS,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,UAAU,EAAE,qBAAqB,CAAC;IAClC,OAAO,EAAE,kBAAkB,CAAC;CAC7B"}
@@ -1,7 +1,7 @@
1
1
  import type { ProviderAdapter, ProviderHealth, StreamTextOptions, StreamTextResult } from './types.js';
2
2
  export declare abstract class BaseProviderAdapter implements ProviderAdapter {
3
3
  abstract readonly id: string;
4
- abstract readonly type: 'openai' | 'workers' | 'mock';
4
+ abstract readonly type: string;
5
5
  abstract readonly weight: number;
6
6
  abstract readonly model: string;
7
7
  abstract readonly keywordModel: string;
@@ -15,6 +15,10 @@ export declare abstract class BaseProviderAdapter implements ProviderAdapter {
15
15
  healthRecoveryTTL?: number;
16
16
  });
17
17
  isAvailable(): Promise<boolean>;
18
+ isInRecovery(): boolean;
19
+ canAttemptRecovery(): boolean;
20
+ markAsRecovered(): void;
21
+ resetHealth(): void;
18
22
  abstract streamText(options: StreamTextOptions): Promise<StreamTextResult>;
19
23
  abstract getProvider(): {
20
24
  chatModel: (model: string) => unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/provider-manager/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,8BAAsB,mBAAoB,YAAW,eAAe;IAClE,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IACtD,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAElC,SAAS,CAAC,MAAM,EAAE,cAAc,CAM9B;IAEF,SAAS,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACrC,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC;gBAExB,OAAO,CAAC,EAAE;QAAE,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAAE;IAK3E,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAYrC,QAAQ,CAAC,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAE1E,QAAQ,CAAC,WAAW,IAAI;QAAE,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAA;KAAE;IAEjE,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO;IAIlC,SAAS,IAAI,cAAc;IAI3B,aAAa,IAAI,IAAI;IASrB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;CAWlC"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/provider-manager/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,8BAAsB,mBAAoB,YAAW,eAAe;IAClE,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAElC,SAAS,CAAC,MAAM,EAAE,cAAc,CAM9B;IAEF,SAAS,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACrC,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC;gBAExB,OAAO,CAAC,EAAE;QAAE,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAAE;IAK3E,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAUrC,YAAY,IAAI,OAAO;IAIvB,kBAAkB,IAAI,OAAO;IAM7B,eAAe,IAAI,IAAI;IAMvB,WAAW,IAAI,IAAI;IAUnB,QAAQ,CAAC,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAE1E,QAAQ,CAAC,WAAW,IAAI;QAAE,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAA;KAAE;IAEjE,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO;IAIlC,SAAS,IAAI,cAAc;IAI3B,aAAa,IAAI,IAAI;IASrB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;CAWlC"}
@@ -18,11 +18,31 @@ class BaseProviderAdapter {
18
18
  if (timeSinceLastError < this.healthRecoveryTTL) {
19
19
  return false;
20
20
  }
21
- this.health.healthy = true;
22
- this.health.consecutiveFailures = 0;
23
21
  }
24
22
  return true;
25
23
  }
24
+ isInRecovery() {
25
+ return !this.health.healthy;
26
+ }
27
+ canAttemptRecovery() {
28
+ if (this.health.healthy) return false;
29
+ const timeSinceLastError = Date.now() - (this.health.lastErrorTime ?? 0);
30
+ return timeSinceLastError >= this.healthRecoveryTTL;
31
+ }
32
+ markAsRecovered() {
33
+ this.health.healthy = true;
34
+ this.health.consecutiveFailures = 0;
35
+ this.health.lastChecked = Date.now();
36
+ }
37
+ resetHealth() {
38
+ this.health = {
39
+ healthy: true,
40
+ consecutiveFailures: 0,
41
+ totalRequests: 0,
42
+ successfulRequests: 0,
43
+ lastChecked: Date.now()
44
+ };
45
+ }
26
46
  chatModel(model) {
27
47
  return this.getProvider().chatModel(model ?? this.model);
28
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/provider-manager/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAGnB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,4BAA4B,cAAc,CAAC;AAuFxD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,kBAAkB,GAAG,cAAc,EAAE,CAuB9E;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CA2B5E;AAED,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,CAG1E;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAMzE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/provider-manager/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAGnB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,4BAA4B,cAAc,CAAC;AAyFxD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,kBAAkB,GAAG,cAAc,EAAE,CAuB9E;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CA2B5E;AAED,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,CAG1E;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAMzE"}
@@ -1,6 +1,7 @@
1
1
  const DEFAULT_WORKERS_BINDING_NAME = "minimaxAI";
2
- const DEFAULT_WEIGHT = 100;
3
- const DEFAULT_TIMEOUT = 3e4;
2
+ import { PROVIDER, TIMEOUTS } from "../constants.js";
3
+ const DEFAULT_WEIGHT = PROVIDER.DEFAULT_WEIGHT;
4
+ const DEFAULT_TIMEOUT = TIMEOUTS.PROVIDER_DEFAULT;
4
5
  const DEFAULT_MODEL = "gpt-4o-mini";
5
6
  function hasOpenAIConfig(env) {
6
7
  return !!(env.AI_BASE_URL && env.AI_API_KEY);
@@ -1,4 +1,4 @@
1
- export { ProviderManager, getProviderManager, resetProviderManager } from './manager.js';
1
+ export { ProviderManager, getProviderManager } from './manager.js';
2
2
  export { BaseProviderAdapter } from './base.js';
3
3
  export { OpenAIAdapter } from './openai.js';
4
4
  export { WorkersAIAdapter } from './workers.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/provider-manager/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAEnI,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,eAAe,GAChB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/provider-manager/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAEnI,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,eAAe,GAChB,MAAM,YAAY,CAAC"}
@@ -1,4 +1,4 @@
1
- import { ProviderManager, getProviderManager, resetProviderManager } from "./manager.js";
1
+ import { ProviderManager, getProviderManager } from "./manager.js";
2
2
  import { BaseProviderAdapter } from "./base.js";
3
3
  import { OpenAIAdapter } from "./openai.js";
4
4
  import { WorkersAIAdapter } from "./workers.js";
@@ -14,6 +14,5 @@ export {
14
14
  getProviderManager,
15
15
  hasAnyProviderConfigured,
16
16
  parseProviderConfigs,
17
- resetProviderManager,
18
17
  validateProviderConfig
19
18
  };