@illuma-ai/agents 1.1.21 → 1.1.22

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 (241) hide show
  1. package/dist/cjs/graphs/Graph.cjs +12 -1
  2. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  3. package/dist/cjs/graphs/MultiAgentGraph.cjs +85 -1
  4. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  5. package/dist/cjs/run.cjs +20 -9
  6. package/dist/cjs/run.cjs.map +1 -1
  7. package/dist/esm/graphs/Graph.mjs +12 -1
  8. package/dist/esm/graphs/Graph.mjs.map +1 -1
  9. package/dist/esm/graphs/MultiAgentGraph.mjs +85 -1
  10. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  11. package/dist/esm/run.mjs +20 -9
  12. package/dist/esm/run.mjs.map +1 -1
  13. package/dist/types/graphs/MultiAgentGraph.d.ts +17 -0
  14. package/package.json +1 -1
  15. package/src/graphs/Graph.ts +12 -1
  16. package/src/graphs/MultiAgentGraph.ts +105 -1
  17. package/src/graphs/__tests__/multi-agent-delegate.test.ts +191 -0
  18. package/src/run.ts +20 -11
  19. package/src/scripts/test-bedrock-handoff-autonomous.ts +231 -0
  20. package/src/agents/AgentContext.js +0 -782
  21. package/src/agents/AgentContext.test.js +0 -421
  22. package/src/agents/__tests__/AgentContext.test.js +0 -678
  23. package/src/agents/__tests__/resolveStructuredOutputMode.test.js +0 -117
  24. package/src/common/enum.js +0 -192
  25. package/src/common/index.js +0 -3
  26. package/src/events.js +0 -166
  27. package/src/graphs/Graph.js +0 -1857
  28. package/src/graphs/MultiAgentGraph.js +0 -1092
  29. package/src/graphs/__tests__/structured-output.integration.test.js +0 -624
  30. package/src/graphs/__tests__/structured-output.test.js +0 -144
  31. package/src/graphs/contextManagement.e2e.test.js +0 -718
  32. package/src/graphs/contextManagement.test.js +0 -485
  33. package/src/graphs/handoffValidation.test.js +0 -276
  34. package/src/graphs/index.js +0 -3
  35. package/src/index.js +0 -28
  36. package/src/instrumentation.js +0 -21
  37. package/src/llm/anthropic/index.js +0 -319
  38. package/src/llm/anthropic/types.js +0 -46
  39. package/src/llm/anthropic/utils/message_inputs.js +0 -627
  40. package/src/llm/anthropic/utils/message_outputs.js +0 -290
  41. package/src/llm/anthropic/utils/output_parsers.js +0 -89
  42. package/src/llm/anthropic/utils/tools.js +0 -25
  43. package/src/llm/bedrock/__tests__/bedrock-caching.test.js +0 -392
  44. package/src/llm/bedrock/index.js +0 -303
  45. package/src/llm/bedrock/types.js +0 -2
  46. package/src/llm/bedrock/utils/index.js +0 -6
  47. package/src/llm/bedrock/utils/message_inputs.js +0 -463
  48. package/src/llm/bedrock/utils/message_outputs.js +0 -269
  49. package/src/llm/fake.js +0 -92
  50. package/src/llm/google/index.js +0 -215
  51. package/src/llm/google/types.js +0 -12
  52. package/src/llm/google/utils/common.js +0 -670
  53. package/src/llm/google/utils/tools.js +0 -111
  54. package/src/llm/google/utils/zod_to_genai_parameters.js +0 -47
  55. package/src/llm/openai/index.js +0 -1033
  56. package/src/llm/openai/types.js +0 -2
  57. package/src/llm/openai/utils/index.js +0 -756
  58. package/src/llm/openai/utils/isReasoningModel.test.js +0 -79
  59. package/src/llm/openrouter/index.js +0 -261
  60. package/src/llm/openrouter/reasoning.test.js +0 -181
  61. package/src/llm/providers.js +0 -36
  62. package/src/llm/text.js +0 -65
  63. package/src/llm/vertexai/index.js +0 -402
  64. package/src/messages/__tests__/tools.test.js +0 -392
  65. package/src/messages/cache.js +0 -404
  66. package/src/messages/cache.test.js +0 -1167
  67. package/src/messages/content.js +0 -48
  68. package/src/messages/content.test.js +0 -314
  69. package/src/messages/core.js +0 -359
  70. package/src/messages/ensureThinkingBlock.test.js +0 -997
  71. package/src/messages/format.js +0 -973
  72. package/src/messages/formatAgentMessages.test.js +0 -2278
  73. package/src/messages/formatAgentMessages.tools.test.js +0 -362
  74. package/src/messages/formatMessage.test.js +0 -608
  75. package/src/messages/ids.js +0 -18
  76. package/src/messages/index.js +0 -9
  77. package/src/messages/labelContentByAgent.test.js +0 -725
  78. package/src/messages/prune.js +0 -438
  79. package/src/messages/reducer.js +0 -60
  80. package/src/messages/shiftIndexTokenCountMap.test.js +0 -63
  81. package/src/messages/summarize.js +0 -146
  82. package/src/messages/summarize.test.js +0 -332
  83. package/src/messages/tools.js +0 -90
  84. package/src/mockStream.js +0 -81
  85. package/src/prompts/collab.js +0 -7
  86. package/src/prompts/index.js +0 -3
  87. package/src/prompts/taskmanager.js +0 -58
  88. package/src/run.js +0 -427
  89. package/src/schemas/index.js +0 -3
  90. package/src/schemas/schema-preparation.test.js +0 -370
  91. package/src/schemas/validate.js +0 -314
  92. package/src/schemas/validate.test.js +0 -264
  93. package/src/scripts/abort.js +0 -127
  94. package/src/scripts/ant_web_search.js +0 -130
  95. package/src/scripts/ant_web_search_edge_case.js +0 -133
  96. package/src/scripts/ant_web_search_error_edge_case.js +0 -119
  97. package/src/scripts/args.js +0 -41
  98. package/src/scripts/bedrock-cache-debug.js +0 -186
  99. package/src/scripts/bedrock-content-aggregation-test.js +0 -195
  100. package/src/scripts/bedrock-merge-test.js +0 -80
  101. package/src/scripts/bedrock-parallel-tools-test.js +0 -150
  102. package/src/scripts/caching.js +0 -106
  103. package/src/scripts/cli.js +0 -152
  104. package/src/scripts/cli2.js +0 -119
  105. package/src/scripts/cli3.js +0 -163
  106. package/src/scripts/cli4.js +0 -165
  107. package/src/scripts/cli5.js +0 -165
  108. package/src/scripts/code_exec.js +0 -171
  109. package/src/scripts/code_exec_files.js +0 -180
  110. package/src/scripts/code_exec_multi_session.js +0 -185
  111. package/src/scripts/code_exec_ptc.js +0 -265
  112. package/src/scripts/code_exec_session.js +0 -217
  113. package/src/scripts/code_exec_simple.js +0 -120
  114. package/src/scripts/content.js +0 -111
  115. package/src/scripts/empty_input.js +0 -125
  116. package/src/scripts/handoff-test.js +0 -96
  117. package/src/scripts/image.js +0 -138
  118. package/src/scripts/memory.js +0 -83
  119. package/src/scripts/multi-agent-chain.js +0 -271
  120. package/src/scripts/multi-agent-conditional.js +0 -185
  121. package/src/scripts/multi-agent-document-review-chain.js +0 -171
  122. package/src/scripts/multi-agent-hybrid-flow.js +0 -264
  123. package/src/scripts/multi-agent-parallel-start.js +0 -214
  124. package/src/scripts/multi-agent-parallel.js +0 -346
  125. package/src/scripts/multi-agent-sequence.js +0 -184
  126. package/src/scripts/multi-agent-supervisor.js +0 -324
  127. package/src/scripts/multi-agent-test.js +0 -147
  128. package/src/scripts/parallel-asymmetric-tools-test.js +0 -202
  129. package/src/scripts/parallel-full-metadata-test.js +0 -176
  130. package/src/scripts/parallel-tools-test.js +0 -256
  131. package/src/scripts/programmatic_exec.js +0 -277
  132. package/src/scripts/programmatic_exec_agent.js +0 -168
  133. package/src/scripts/search.js +0 -118
  134. package/src/scripts/sequential-full-metadata-test.js +0 -143
  135. package/src/scripts/simple.js +0 -174
  136. package/src/scripts/single-agent-metadata-test.js +0 -152
  137. package/src/scripts/stream.js +0 -113
  138. package/src/scripts/test-custom-prompt-key.js +0 -132
  139. package/src/scripts/test-handoff-input.js +0 -143
  140. package/src/scripts/test-handoff-preamble.js +0 -227
  141. package/src/scripts/test-handoff-steering.js +0 -353
  142. package/src/scripts/test-multi-agent-list-handoff.js +0 -318
  143. package/src/scripts/test-parallel-agent-labeling.js +0 -253
  144. package/src/scripts/test-parallel-handoffs.js +0 -229
  145. package/src/scripts/test-thinking-handoff-bedrock.js +0 -132
  146. package/src/scripts/test-thinking-handoff.js +0 -132
  147. package/src/scripts/test-thinking-to-thinking-handoff-bedrock.js +0 -140
  148. package/src/scripts/test-tool-before-handoff-role-order.js +0 -223
  149. package/src/scripts/test-tools-before-handoff.js +0 -187
  150. package/src/scripts/test_code_api.js +0 -263
  151. package/src/scripts/thinking-bedrock.js +0 -128
  152. package/src/scripts/thinking-vertexai.js +0 -130
  153. package/src/scripts/thinking.js +0 -134
  154. package/src/scripts/tool_search.js +0 -114
  155. package/src/scripts/tools.js +0 -125
  156. package/src/specs/agent-handoffs-bedrock.integration.test.js +0 -280
  157. package/src/specs/agent-handoffs.test.js +0 -924
  158. package/src/specs/anthropic.simple.test.js +0 -287
  159. package/src/specs/azure.simple.test.js +0 -381
  160. package/src/specs/cache.simple.test.js +0 -282
  161. package/src/specs/custom-event-await.test.js +0 -148
  162. package/src/specs/deepseek.simple.test.js +0 -189
  163. package/src/specs/emergency-prune.test.js +0 -308
  164. package/src/specs/moonshot.simple.test.js +0 -237
  165. package/src/specs/observability.integration.test.js +0 -1337
  166. package/src/specs/openai.simple.test.js +0 -233
  167. package/src/specs/openrouter.simple.test.js +0 -202
  168. package/src/specs/prune.test.js +0 -733
  169. package/src/specs/reasoning.test.js +0 -144
  170. package/src/specs/spec.utils.js +0 -4
  171. package/src/specs/thinking-handoff.test.js +0 -486
  172. package/src/specs/thinking-prune.test.js +0 -600
  173. package/src/specs/token-distribution-edge-case.test.js +0 -246
  174. package/src/specs/token-memoization.test.js +0 -32
  175. package/src/specs/tokens.test.js +0 -49
  176. package/src/specs/tool-error.test.js +0 -139
  177. package/src/splitStream.js +0 -204
  178. package/src/splitStream.test.js +0 -504
  179. package/src/stream.js +0 -650
  180. package/src/stream.test.js +0 -225
  181. package/src/test/mockTools.js +0 -340
  182. package/src/tools/BrowserTools.js +0 -245
  183. package/src/tools/Calculator.js +0 -38
  184. package/src/tools/Calculator.test.js +0 -225
  185. package/src/tools/CodeExecutor.js +0 -233
  186. package/src/tools/ProgrammaticToolCalling.js +0 -602
  187. package/src/tools/StreamingToolCallBuffer.js +0 -179
  188. package/src/tools/ToolNode.js +0 -930
  189. package/src/tools/ToolSearch.js +0 -904
  190. package/src/tools/__tests__/BrowserTools.test.js +0 -306
  191. package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.js +0 -276
  192. package/src/tools/__tests__/ProgrammaticToolCalling.test.js +0 -807
  193. package/src/tools/__tests__/StreamingToolCallBuffer.test.js +0 -175
  194. package/src/tools/__tests__/ToolApproval.test.js +0 -675
  195. package/src/tools/__tests__/ToolNode.recovery.test.js +0 -200
  196. package/src/tools/__tests__/ToolNode.session.test.js +0 -319
  197. package/src/tools/__tests__/ToolSearch.integration.test.js +0 -125
  198. package/src/tools/__tests__/ToolSearch.test.js +0 -812
  199. package/src/tools/__tests__/handlers.test.js +0 -799
  200. package/src/tools/__tests__/truncation-recovery.integration.test.js +0 -362
  201. package/src/tools/handlers.js +0 -306
  202. package/src/tools/schema.js +0 -25
  203. package/src/tools/search/anthropic.js +0 -34
  204. package/src/tools/search/content.js +0 -116
  205. package/src/tools/search/content.test.js +0 -133
  206. package/src/tools/search/firecrawl.js +0 -173
  207. package/src/tools/search/format.js +0 -198
  208. package/src/tools/search/highlights.js +0 -241
  209. package/src/tools/search/index.js +0 -3
  210. package/src/tools/search/jina-reranker.test.js +0 -106
  211. package/src/tools/search/rerankers.js +0 -165
  212. package/src/tools/search/schema.js +0 -102
  213. package/src/tools/search/search.js +0 -561
  214. package/src/tools/search/serper-scraper.js +0 -126
  215. package/src/tools/search/test.js +0 -129
  216. package/src/tools/search/tool.js +0 -453
  217. package/src/tools/search/types.js +0 -2
  218. package/src/tools/search/utils.js +0 -59
  219. package/src/types/graph.js +0 -24
  220. package/src/types/graph.test.js +0 -192
  221. package/src/types/index.js +0 -7
  222. package/src/types/llm.js +0 -2
  223. package/src/types/messages.js +0 -2
  224. package/src/types/run.js +0 -2
  225. package/src/types/stream.js +0 -2
  226. package/src/types/tools.js +0 -2
  227. package/src/utils/contextAnalytics.js +0 -79
  228. package/src/utils/contextAnalytics.test.js +0 -166
  229. package/src/utils/events.js +0 -26
  230. package/src/utils/graph.js +0 -11
  231. package/src/utils/handlers.js +0 -65
  232. package/src/utils/index.js +0 -10
  233. package/src/utils/llm.js +0 -21
  234. package/src/utils/llmConfig.js +0 -205
  235. package/src/utils/logging.js +0 -37
  236. package/src/utils/misc.js +0 -51
  237. package/src/utils/run.js +0 -69
  238. package/src/utils/schema.js +0 -21
  239. package/src/utils/title.js +0 -119
  240. package/src/utils/tokens.js +0 -92
  241. package/src/utils/toonFormat.js +0 -379
@@ -1,241 +0,0 @@
1
- // 2. Pre-compile all regular expressions (only do this once)
2
- // Group patterns by priority for early returns
3
- const priorityPatterns = [
4
- // High priority patterns (structural)
5
- [
6
- { regex: /\n\n/g }, // Double newline (paragraph break)
7
- { regex: /\n/g }, // Single newline
8
- { regex: /={3,}\s*\n|-{3,}\s*\n/g }, // Section separators
9
- ],
10
- // Medium priority (semantic)
11
- [
12
- { regex: /[.!?][")\]]?\s/g }, // End of sentence
13
- { regex: /;\s/g }, // Semicolon
14
- { regex: /:\s/g }, // Colon
15
- ],
16
- // Low priority (any breaks)
17
- [
18
- { regex: /,\s/g }, // Comma
19
- { regex: /\s-\s/g }, // Dash surrounded by spaces
20
- { regex: /\s/g }, // Any space
21
- ],
22
- ];
23
- function findFirstMatch(text, regex) {
24
- // Reset regex
25
- regex.lastIndex = 0;
26
- // For very long texts, try chunking
27
- if (text.length > 10000) {
28
- const chunkSize = 2000;
29
- let position = 0;
30
- while (position < text.length) {
31
- const chunk = text.substring(position, position + chunkSize);
32
- regex.lastIndex = 0;
33
- const match = regex.exec(chunk);
34
- if (match) {
35
- return position + match.index;
36
- }
37
- // Move to next chunk with some overlap
38
- position += chunkSize - 100;
39
- if (position >= text.length)
40
- break;
41
- }
42
- return -1;
43
- }
44
- // For shorter texts, normal regex search
45
- const match = regex.exec(text);
46
- return match ? match.index : -1;
47
- }
48
- // 3. Optimized boundary finding functions
49
- function findLastMatch(text, regex) {
50
- // Reset regex state
51
- regex.lastIndex = 0;
52
- let lastIndex = -1;
53
- let lastLength = 0;
54
- let match;
55
- // For very long texts, use a different approach to avoid regex engine slowdowns
56
- if (text.length > 10000) {
57
- // Try dividing the text into chunks for faster processing
58
- const chunkSize = 2000;
59
- let startPosition = Math.max(0, text.length - chunkSize);
60
- while (startPosition >= 0) {
61
- const chunk = text.substring(startPosition, startPosition + chunkSize);
62
- regex.lastIndex = 0;
63
- let chunkLastIndex = -1;
64
- let chunkLastLength = 0;
65
- while ((match = regex.exec(chunk)) !== null) {
66
- chunkLastIndex = match.index;
67
- chunkLastLength = match[0].length;
68
- }
69
- if (chunkLastIndex !== -1) {
70
- return startPosition + chunkLastIndex + chunkLastLength;
71
- }
72
- // Move to previous chunk with some overlap
73
- startPosition = Math.max(0, startPosition - chunkSize + 100) - 1;
74
- if (startPosition <= 0)
75
- break;
76
- }
77
- return -1;
78
- }
79
- // For shorter texts, normal regex search
80
- while ((match = regex.exec(text)) !== null) {
81
- lastIndex = match.index;
82
- lastLength = match[0].length;
83
- }
84
- return lastIndex === -1 ? -1 : lastIndex + lastLength;
85
- }
86
- // 4. Find the best boundary with priority groups
87
- function findBestBoundary(text, direction = 'backward') {
88
- if (!text || text.length === 0)
89
- return 0;
90
- // Try each priority group
91
- for (const patternGroup of priorityPatterns) {
92
- for (const pattern of patternGroup) {
93
- const position = direction === 'backward'
94
- ? findLastMatch(text, pattern.regex)
95
- : findFirstMatch(text, pattern.regex);
96
- if (position !== -1) {
97
- return position;
98
- }
99
- }
100
- }
101
- // No match found, use character boundary
102
- return direction === 'backward' ? text.length : 0;
103
- }
104
- /**
105
- * Tracks references used in a highlight without changing their numbers
106
- */
107
- function trackReferencesInHighlight(text, sourceResult // Source containing the original references
108
- ) {
109
- // Track used references
110
- const references = [];
111
- if (!text || text.length === 0 || !text.includes('#')) {
112
- return { references }; // Early return
113
- }
114
- // Quick check for reference markers
115
- if (!text.includes('link#') &&
116
- !text.includes('image#') &&
117
- !text.includes('video#')) {
118
- return { references };
119
- }
120
- // Get references from the source if available
121
- const sourceRefs = sourceResult.references || {
122
- links: [],
123
- images: [],
124
- videos: [],
125
- };
126
- // Find references but don't modify text
127
- const refRegex = /\((link|image|video)#(\d+)(?:\s+"([^"]*)")?\)/g;
128
- let match;
129
- while ((match = refRegex.exec(text)) !== null) {
130
- const [, type, indexStr] = match;
131
- const originalIndex = parseInt(indexStr, 10) - 1; // Convert to 0-based
132
- // Get the source array for this type
133
- const refType = type;
134
- const sourceArray = sourceRefs[`${refType}s`];
135
- // Skip if invalid reference
136
- if (!sourceArray ||
137
- originalIndex < 0 ||
138
- originalIndex >= sourceArray.length) {
139
- continue; // Skip invalid references
140
- }
141
- // Get original reference
142
- const reference = sourceArray[originalIndex];
143
- // Track if not already tracked
144
- const alreadyTracked = references.some((ref) => ref.type === refType && ref.originalIndex === originalIndex);
145
- if (!alreadyTracked) {
146
- references.push({
147
- type: refType,
148
- originalIndex,
149
- reference,
150
- });
151
- }
152
- }
153
- return { references };
154
- }
155
- /**
156
- * Expand highlights in search results using smart boundary detection.
157
- *
158
- * This implementation finds natural text boundaries like paragraphs, sentences,
159
- * and phrases to provide context while maintaining readability.
160
- *
161
- * @param searchResults - Search results object
162
- * @param mainExpandBy - Primary expansion size on each side (default: 300)
163
- * @param separatorExpandBy - Additional range to look for separators (default: 150)
164
- * @returns Copy of search results with expanded highlights and tracked references
165
- */
166
- export function expandHighlights(searchResults, mainExpandBy = 300, separatorExpandBy = 150) {
167
- // Avoid deep copy - only copy what we modify
168
- const resultCopy = { ...searchResults };
169
- if (resultCopy.organic)
170
- resultCopy.organic = [...resultCopy.organic];
171
- if (resultCopy.topStories)
172
- resultCopy.topStories = [...resultCopy.topStories];
173
- // Process the results efficiently
174
- const processResultTypes = ['organic', 'topStories'];
175
- for (const resultType of processResultTypes) {
176
- if (!resultCopy[resultType])
177
- continue;
178
- // Map results to new array with modified highlights
179
- resultCopy[resultType] = resultCopy[resultType]?.map((result) => {
180
- if (result.content == null ||
181
- result.content === '' ||
182
- !result.highlights ||
183
- result.highlights.length === 0) {
184
- return result; // No modification needed
185
- }
186
- // Create a shallow copy with expanded highlights
187
- const resultCopy = { ...result };
188
- const content = result.content;
189
- const highlights = [];
190
- // Process each highlight
191
- for (const highlight of result.highlights) {
192
- const { references } = trackReferencesInHighlight(highlight.text, result);
193
- let startPos = content.indexOf(highlight.text);
194
- let highlightLen = highlight.text.length;
195
- if (startPos === -1) {
196
- // Try with stripped whitespace
197
- const strippedHighlight = highlight.text.trim();
198
- startPos = content.indexOf(strippedHighlight);
199
- if (startPos === -1) {
200
- highlights.push({
201
- text: highlight.text,
202
- score: highlight.score,
203
- references,
204
- });
205
- continue;
206
- }
207
- highlightLen = strippedHighlight.length;
208
- }
209
- // Calculate boundaries
210
- const mainStart = Math.max(0, startPos - mainExpandBy);
211
- const mainEnd = Math.min(content.length, startPos + highlightLen + mainExpandBy);
212
- const separatorStart = Math.max(0, mainStart - separatorExpandBy);
213
- const separatorEnd = Math.min(content.length, mainEnd + separatorExpandBy);
214
- // Extract text segments
215
- const headText = content.substring(separatorStart, mainStart);
216
- const tailText = content.substring(mainEnd, separatorEnd);
217
- // Find natural boundaries
218
- const bestHeadBoundary = findBestBoundary(headText, 'backward');
219
- const bestTailBoundary = findBestBoundary(tailText, 'forward');
220
- // Calculate final positions
221
- const finalStart = separatorStart + bestHeadBoundary;
222
- const finalEnd = mainEnd + bestTailBoundary;
223
- // Extract the expanded highlight
224
- const expandedHighlightText = content
225
- .substring(finalStart, finalEnd)
226
- .trim();
227
- highlights.push({
228
- text: expandedHighlightText,
229
- score: highlight.score,
230
- references,
231
- });
232
- }
233
- resultCopy.highlights = highlights;
234
- delete resultCopy.content;
235
- delete resultCopy.references;
236
- return resultCopy;
237
- });
238
- }
239
- return resultCopy;
240
- }
241
- //# sourceMappingURL=highlights.js.map
@@ -1,3 +0,0 @@
1
- export * from './tool';
2
- export * from './schema';
3
- //# sourceMappingURL=index.js.map
@@ -1,106 +0,0 @@
1
- import { JinaReranker, createReranker } from './rerankers';
2
- import { createDefaultLogger } from './utils';
3
- // Helper to access private apiUrl property for testing
4
- const getApiUrl = (reranker) => reranker.apiUrl;
5
- describe('JinaReranker', () => {
6
- const mockLogger = createDefaultLogger();
7
- describe('constructor', () => {
8
- it('should use default API URL when no apiUrl is provided', () => {
9
- const reranker = new JinaReranker({
10
- apiKey: 'test-key',
11
- logger: mockLogger,
12
- });
13
- // Access private property for testing
14
- const apiUrl = getApiUrl(reranker);
15
- expect(apiUrl).toBe('https://api.jina.ai/v1/rerank');
16
- });
17
- it('should use custom API URL when provided', () => {
18
- const customUrl = 'https://custom-jina-endpoint.com/v1/rerank';
19
- const reranker = new JinaReranker({
20
- apiKey: 'test-key',
21
- apiUrl: customUrl,
22
- logger: mockLogger,
23
- });
24
- const apiUrl = getApiUrl(reranker);
25
- expect(apiUrl).toBe(customUrl);
26
- });
27
- it('should use environment variable JINA_API_URL when available', () => {
28
- const originalEnv = process.env.JINA_API_URL;
29
- process.env.JINA_API_URL = 'https://env-jina-endpoint.com/v1/rerank';
30
- const reranker = new JinaReranker({
31
- apiKey: 'test-key',
32
- logger: mockLogger,
33
- });
34
- const apiUrl = getApiUrl(reranker);
35
- expect(apiUrl).toBe('https://env-jina-endpoint.com/v1/rerank');
36
- // Restore original environment
37
- if (originalEnv != null && originalEnv !== '') {
38
- process.env.JINA_API_URL = originalEnv;
39
- }
40
- else {
41
- delete process.env.JINA_API_URL;
42
- }
43
- });
44
- it('should prioritize explicit apiUrl over environment variable', () => {
45
- const originalEnv = process.env.JINA_API_URL;
46
- process.env.JINA_API_URL = 'https://env-jina-endpoint.com/v1/rerank';
47
- const customUrl = 'https://explicit-jina-endpoint.com/v1/rerank';
48
- const reranker = new JinaReranker({
49
- apiKey: 'test-key',
50
- apiUrl: customUrl,
51
- logger: mockLogger,
52
- });
53
- const apiUrl = getApiUrl(reranker);
54
- expect(apiUrl).toBe(customUrl);
55
- // Restore original environment
56
- if (originalEnv != null && originalEnv !== '') {
57
- process.env.JINA_API_URL = originalEnv;
58
- }
59
- else {
60
- delete process.env.JINA_API_URL;
61
- }
62
- });
63
- });
64
- describe('rerank method', () => {
65
- it('should log the API URL being used', async () => {
66
- const customUrl = 'https://test-jina-endpoint.com/v1/rerank';
67
- const reranker = new JinaReranker({
68
- apiKey: 'test-key',
69
- apiUrl: customUrl,
70
- logger: mockLogger,
71
- });
72
- const logSpy = jest.spyOn(mockLogger, 'debug');
73
- try {
74
- await reranker.rerank('test query', ['document1', 'document2'], 2);
75
- }
76
- catch (_error) {
77
- // Expected to fail due to missing API key, but we can check the log
78
- }
79
- expect(logSpy).toHaveBeenCalledWith(expect.stringContaining(`Reranking 2 chunks with Jina using API URL: ${customUrl}`));
80
- logSpy.mockRestore();
81
- });
82
- });
83
- });
84
- describe('createReranker', () => {
85
- it('should create JinaReranker with jinaApiUrl when provided', () => {
86
- const customUrl = 'https://custom-jina-endpoint.com/v1/rerank';
87
- const reranker = createReranker({
88
- rerankerType: 'jina',
89
- jinaApiKey: 'test-key',
90
- jinaApiUrl: customUrl,
91
- });
92
- expect(reranker).toBeInstanceOf(JinaReranker);
93
- const apiUrl = getApiUrl(reranker);
94
- expect(apiUrl).toBe(customUrl);
95
- });
96
- it('should create JinaReranker with default URL when jinaApiUrl is not provided', () => {
97
- const reranker = createReranker({
98
- rerankerType: 'jina',
99
- jinaApiKey: 'test-key',
100
- });
101
- expect(reranker).toBeInstanceOf(JinaReranker);
102
- const apiUrl = getApiUrl(reranker);
103
- expect(apiUrl).toBe('https://api.jina.ai/v1/rerank');
104
- });
105
- });
106
- //# sourceMappingURL=jina-reranker.test.js.map
@@ -1,165 +0,0 @@
1
- import axios from 'axios';
2
- import { createDefaultLogger } from './utils';
3
- export class BaseReranker {
4
- apiKey;
5
- logger;
6
- constructor(logger) {
7
- // Each specific reranker will set its API key
8
- this.logger = logger || createDefaultLogger();
9
- }
10
- getDefaultRanking(documents, topK) {
11
- return documents
12
- .slice(0, Math.min(topK, documents.length))
13
- .map((doc) => ({ text: doc, score: 0 }));
14
- }
15
- }
16
- export class JinaReranker extends BaseReranker {
17
- apiUrl;
18
- constructor({ apiKey = process.env.JINA_API_KEY, apiUrl = process.env.JINA_API_URL || 'https://api.jina.ai/v1/rerank', logger, }) {
19
- super(logger);
20
- this.apiKey = apiKey;
21
- this.apiUrl = apiUrl;
22
- }
23
- async rerank(query, documents, topK = 5) {
24
- this.logger.debug(`Reranking ${documents.length} chunks with Jina using API URL: ${this.apiUrl}`);
25
- try {
26
- if (this.apiKey == null || this.apiKey === '') {
27
- this.logger.warn('JINA_API_KEY is not set. Using default ranking.');
28
- return this.getDefaultRanking(documents, topK);
29
- }
30
- const requestData = {
31
- model: 'jina-reranker-v2-base-multilingual',
32
- query: query,
33
- top_n: topK,
34
- documents: documents,
35
- return_documents: true,
36
- };
37
- const response = await axios.post(this.apiUrl, requestData, {
38
- headers: {
39
- 'Content-Type': 'application/json',
40
- Authorization: `Bearer ${this.apiKey}`,
41
- },
42
- });
43
- this.logger.debug('Jina API Model:', response.data?.model);
44
- this.logger.debug('Jina API Usage:', response.data?.usage);
45
- if (response.data && response.data.results.length) {
46
- return response.data.results.map((result) => {
47
- const docIndex = result.index;
48
- const score = result.relevance_score;
49
- let text = '';
50
- // If return_documents is true, the document field will be present
51
- if (result.document != null) {
52
- const doc = result.document;
53
- if (typeof doc === 'object' && 'text' in doc) {
54
- text = doc.text;
55
- }
56
- else if (typeof doc === 'string') {
57
- text = doc;
58
- }
59
- }
60
- else {
61
- // Otherwise, use the index to get the document
62
- text = documents[docIndex];
63
- }
64
- return { text, score };
65
- });
66
- }
67
- else {
68
- this.logger.warn('Unexpected response format from Jina API. Using default ranking.');
69
- return this.getDefaultRanking(documents, topK);
70
- }
71
- }
72
- catch (error) {
73
- this.logger.error('Error using Jina reranker:', error);
74
- // Fallback to default ranking on error
75
- return this.getDefaultRanking(documents, topK);
76
- }
77
- }
78
- }
79
- export class CohereReranker extends BaseReranker {
80
- constructor({ apiKey = process.env.COHERE_API_KEY, logger, }) {
81
- super(logger);
82
- this.apiKey = apiKey;
83
- }
84
- async rerank(query, documents, topK = 5) {
85
- this.logger.debug(`Reranking ${documents.length} chunks with Cohere`);
86
- try {
87
- if (this.apiKey == null || this.apiKey === '') {
88
- this.logger.warn('COHERE_API_KEY is not set. Using default ranking.');
89
- return this.getDefaultRanking(documents, topK);
90
- }
91
- const requestData = {
92
- model: 'rerank-v3.5',
93
- query: query,
94
- top_n: topK,
95
- documents: documents,
96
- };
97
- const response = await axios.post('https://api.cohere.com/v2/rerank', requestData, {
98
- headers: {
99
- 'Content-Type': 'application/json',
100
- Authorization: `Bearer ${this.apiKey}`,
101
- },
102
- });
103
- this.logger.debug('Cohere API ID:', response.data?.id);
104
- this.logger.debug('Cohere API Meta:', response.data?.meta);
105
- if (response.data && response.data.results.length) {
106
- return response.data.results.map((result) => {
107
- const docIndex = result.index;
108
- const score = result.relevance_score;
109
- const text = documents[docIndex];
110
- return { text, score };
111
- });
112
- }
113
- else {
114
- this.logger.warn('Unexpected response format from Cohere API. Using default ranking.');
115
- return this.getDefaultRanking(documents, topK);
116
- }
117
- }
118
- catch (error) {
119
- this.logger.error('Error using Cohere reranker:', error);
120
- // Fallback to default ranking on error
121
- return this.getDefaultRanking(documents, topK);
122
- }
123
- }
124
- }
125
- export class InfinityReranker extends BaseReranker {
126
- constructor(logger) {
127
- super(logger);
128
- // No API key needed for the placeholder implementation
129
- }
130
- async rerank(query, documents, topK = 5) {
131
- this.logger.debug(`Reranking ${documents.length} chunks with Infinity (placeholder)`);
132
- // This would be replaced with actual Infinity reranker implementation
133
- return this.getDefaultRanking(documents, topK);
134
- }
135
- }
136
- /**
137
- * Creates the appropriate reranker based on type and configuration
138
- */
139
- export const createReranker = (config) => {
140
- const { rerankerType, jinaApiKey, jinaApiUrl, cohereApiKey, logger } = config;
141
- // Create a default logger if none is provided
142
- const defaultLogger = logger || createDefaultLogger();
143
- switch (rerankerType.toLowerCase()) {
144
- case 'jina':
145
- return new JinaReranker({ apiKey: jinaApiKey, apiUrl: jinaApiUrl, logger: defaultLogger });
146
- case 'cohere':
147
- return new CohereReranker({
148
- apiKey: cohereApiKey,
149
- logger: defaultLogger,
150
- });
151
- case 'infinity':
152
- return new InfinityReranker(defaultLogger);
153
- case 'none':
154
- defaultLogger.debug('Skipping reranking as reranker is set to "none"');
155
- return undefined;
156
- default:
157
- defaultLogger.warn(`Unknown reranker type: ${rerankerType}. Defaulting to InfinityReranker.`);
158
- return new JinaReranker({ apiKey: jinaApiKey, apiUrl: jinaApiUrl, logger: defaultLogger });
159
- }
160
- };
161
- // Example usage:
162
- // const jinaReranker = new JinaReranker();
163
- // const cohereReranker = new CohereReranker();
164
- // const infinityReranker = new InfinityReranker();
165
- //# sourceMappingURL=rerankers.js.map
@@ -1,102 +0,0 @@
1
- export var DATE_RANGE;
2
- (function (DATE_RANGE) {
3
- DATE_RANGE["PAST_HOUR"] = "h";
4
- DATE_RANGE["PAST_24_HOURS"] = "d";
5
- DATE_RANGE["PAST_WEEK"] = "w";
6
- DATE_RANGE["PAST_MONTH"] = "m";
7
- DATE_RANGE["PAST_YEAR"] = "y";
8
- })(DATE_RANGE || (DATE_RANGE = {}));
9
- export const DEFAULT_QUERY_DESCRIPTION = `
10
- GUIDELINES:
11
- - Start broad, then narrow: Begin with key concepts, then refine with specifics
12
- - Think like sources: Use terminology experts would use in the field
13
- - Consider perspective: Frame queries from different viewpoints for better results
14
- - Quality over quantity: A precise 3-4 word query often beats lengthy sentences
15
-
16
- TECHNIQUES (combine for power searches):
17
- - EXACT PHRASES: Use quotes ("climate change report")
18
- - EXCLUDE TERMS: Use minus to remove unwanted results (-wikipedia)
19
- - SITE-SPECIFIC: Restrict to websites (site:edu research)
20
- - FILETYPE: Find specific documents (filetype:pdf study)
21
- - OR OPERATOR: Find alternatives (electric OR hybrid cars)
22
- - DATE RANGE: Recent information (data after:2020)
23
- - WILDCARDS: Use * for unknown terms (how to * bread)
24
- - SPECIFIC QUESTIONS: Use who/what/when/where/why/how
25
- - DOMAIN TERMS: Include technical terminology for specialized topics
26
- - CONCISE TERMS: Prioritize keywords over sentences
27
- `.trim();
28
- export const DEFAULT_COUNTRY_DESCRIPTION = `Country code to localize search results.
29
- Use standard 2-letter country codes: "us", "uk", "ca", "de", "fr", "jp", "br", etc.
30
- Provide this when the search should return results specific to a particular country.
31
- Examples:
32
- - "us" for United States (default)
33
- - "de" for Germany
34
- - "in" for India
35
- `.trim();
36
- export const querySchema = {
37
- type: 'string',
38
- description: DEFAULT_QUERY_DESCRIPTION,
39
- };
40
- export const dateSchema = {
41
- type: 'string',
42
- enum: Object.values(DATE_RANGE),
43
- description: 'Date range for search results.',
44
- };
45
- export const countrySchema = {
46
- type: 'string',
47
- description: DEFAULT_COUNTRY_DESCRIPTION,
48
- };
49
- export const imagesSchema = {
50
- type: 'boolean',
51
- description: 'Whether to also run an image search.',
52
- };
53
- export const videosSchema = {
54
- type: 'boolean',
55
- description: 'Whether to also run a video search.',
56
- };
57
- export const newsSchema = {
58
- type: 'boolean',
59
- description: 'Whether to also run a news search.',
60
- };
61
- /** Combined web search tool schema with all properties */
62
- export const WebSearchToolSchema = {
63
- type: 'object',
64
- properties: {
65
- query: querySchema,
66
- date: dateSchema,
67
- country: countrySchema,
68
- images: imagesSchema,
69
- videos: videosSchema,
70
- news: newsSchema,
71
- },
72
- required: ['query'],
73
- };
74
- export const WebSearchToolName = 'web_search';
75
- export const WebSearchToolDescription = `Real-time search. Results have required citation anchors.
76
-
77
- Note: Use ONCE per reply unless instructed otherwise.
78
-
79
- Anchors:
80
- - \\ue202turnXtypeY
81
- - X = turn idx, type = 'search' | 'news' | 'image' | 'ref', Y = item idx
82
-
83
- Special Markers:
84
- - \\ue203...\\ue204 — highlight start/end of cited text (for Standalone or Group citations)
85
- - \\ue200...\\ue201 — group block (e.g. \\ue200\\ue202turn0search1\\ue202turn0news2\\ue201)
86
-
87
- **CITE EVERY NON-OBVIOUS FACT/QUOTE:**
88
- Use anchor marker(s) immediately after the statement:
89
- - Standalone: "Pure functions produce same output. \\ue202turn0search0"
90
- - Standalone (multiple): "Today's News \\ue202turn0search0\\ue202turn0news0"
91
- - Highlight: "\\ue203Highlight text.\\ue204\\ue202turn0news1"
92
- - Group: "Sources. \\ue200\\ue202turn0search0\\ue202turn0news1\\ue201"
93
- - Group Highlight: "\\ue203Highlight for group.\\ue204 \\ue200\\ue202turn0search0\\ue202turn0news1\\ue201"
94
- - Image: "See photo \\ue202turn0image0."
95
-
96
- **NEVER use markdown links, [1], or footnotes. CITE ONLY with anchors provided.**`;
97
- export const WebSearchToolDefinition = {
98
- name: WebSearchToolName,
99
- description: WebSearchToolDescription,
100
- schema: WebSearchToolSchema,
101
- };
102
- //# sourceMappingURL=schema.js.map