@illuma-ai/agents 1.1.20 → 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 (246) 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/llm/bedrock/index.cjs +14 -0
  6. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  7. package/dist/cjs/run.cjs +20 -9
  8. package/dist/cjs/run.cjs.map +1 -1
  9. package/dist/esm/graphs/Graph.mjs +12 -1
  10. package/dist/esm/graphs/Graph.mjs.map +1 -1
  11. package/dist/esm/graphs/MultiAgentGraph.mjs +85 -1
  12. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  13. package/dist/esm/llm/bedrock/index.mjs +14 -0
  14. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  15. package/dist/esm/run.mjs +20 -9
  16. package/dist/esm/run.mjs.map +1 -1
  17. package/dist/types/graphs/MultiAgentGraph.d.ts +17 -0
  18. package/package.json +1 -1
  19. package/src/graphs/Graph.ts +12 -1
  20. package/src/graphs/MultiAgentGraph.ts +105 -1
  21. package/src/graphs/__tests__/multi-agent-delegate.test.ts +191 -0
  22. package/src/llm/bedrock/index.ts +17 -0
  23. package/src/run.ts +20 -11
  24. package/src/scripts/test-bedrock-handoff-autonomous.ts +231 -0
  25. package/src/agents/AgentContext.js +0 -782
  26. package/src/agents/AgentContext.test.js +0 -421
  27. package/src/agents/__tests__/AgentContext.test.js +0 -678
  28. package/src/agents/__tests__/resolveStructuredOutputMode.test.js +0 -117
  29. package/src/common/enum.js +0 -192
  30. package/src/common/index.js +0 -3
  31. package/src/events.js +0 -166
  32. package/src/graphs/Graph.js +0 -1857
  33. package/src/graphs/MultiAgentGraph.js +0 -1092
  34. package/src/graphs/__tests__/structured-output.integration.test.js +0 -624
  35. package/src/graphs/__tests__/structured-output.test.js +0 -144
  36. package/src/graphs/contextManagement.e2e.test.js +0 -718
  37. package/src/graphs/contextManagement.test.js +0 -485
  38. package/src/graphs/handoffValidation.test.js +0 -276
  39. package/src/graphs/index.js +0 -3
  40. package/src/index.js +0 -28
  41. package/src/instrumentation.js +0 -21
  42. package/src/llm/anthropic/index.js +0 -319
  43. package/src/llm/anthropic/types.js +0 -46
  44. package/src/llm/anthropic/utils/message_inputs.js +0 -627
  45. package/src/llm/anthropic/utils/message_outputs.js +0 -290
  46. package/src/llm/anthropic/utils/output_parsers.js +0 -89
  47. package/src/llm/anthropic/utils/tools.js +0 -25
  48. package/src/llm/bedrock/__tests__/bedrock-caching.test.js +0 -392
  49. package/src/llm/bedrock/index.js +0 -303
  50. package/src/llm/bedrock/types.js +0 -2
  51. package/src/llm/bedrock/utils/index.js +0 -6
  52. package/src/llm/bedrock/utils/message_inputs.js +0 -463
  53. package/src/llm/bedrock/utils/message_outputs.js +0 -269
  54. package/src/llm/fake.js +0 -92
  55. package/src/llm/google/index.js +0 -215
  56. package/src/llm/google/types.js +0 -12
  57. package/src/llm/google/utils/common.js +0 -670
  58. package/src/llm/google/utils/tools.js +0 -111
  59. package/src/llm/google/utils/zod_to_genai_parameters.js +0 -47
  60. package/src/llm/openai/index.js +0 -1033
  61. package/src/llm/openai/types.js +0 -2
  62. package/src/llm/openai/utils/index.js +0 -756
  63. package/src/llm/openai/utils/isReasoningModel.test.js +0 -79
  64. package/src/llm/openrouter/index.js +0 -261
  65. package/src/llm/openrouter/reasoning.test.js +0 -181
  66. package/src/llm/providers.js +0 -36
  67. package/src/llm/text.js +0 -65
  68. package/src/llm/vertexai/index.js +0 -402
  69. package/src/messages/__tests__/tools.test.js +0 -392
  70. package/src/messages/cache.js +0 -404
  71. package/src/messages/cache.test.js +0 -1167
  72. package/src/messages/content.js +0 -48
  73. package/src/messages/content.test.js +0 -314
  74. package/src/messages/core.js +0 -359
  75. package/src/messages/ensureThinkingBlock.test.js +0 -997
  76. package/src/messages/format.js +0 -973
  77. package/src/messages/formatAgentMessages.test.js +0 -2278
  78. package/src/messages/formatAgentMessages.tools.test.js +0 -362
  79. package/src/messages/formatMessage.test.js +0 -608
  80. package/src/messages/ids.js +0 -18
  81. package/src/messages/index.js +0 -9
  82. package/src/messages/labelContentByAgent.test.js +0 -725
  83. package/src/messages/prune.js +0 -438
  84. package/src/messages/reducer.js +0 -60
  85. package/src/messages/shiftIndexTokenCountMap.test.js +0 -63
  86. package/src/messages/summarize.js +0 -146
  87. package/src/messages/summarize.test.js +0 -332
  88. package/src/messages/tools.js +0 -90
  89. package/src/mockStream.js +0 -81
  90. package/src/prompts/collab.js +0 -7
  91. package/src/prompts/index.js +0 -3
  92. package/src/prompts/taskmanager.js +0 -58
  93. package/src/run.js +0 -427
  94. package/src/schemas/index.js +0 -3
  95. package/src/schemas/schema-preparation.test.js +0 -370
  96. package/src/schemas/validate.js +0 -314
  97. package/src/schemas/validate.test.js +0 -264
  98. package/src/scripts/abort.js +0 -127
  99. package/src/scripts/ant_web_search.js +0 -130
  100. package/src/scripts/ant_web_search_edge_case.js +0 -133
  101. package/src/scripts/ant_web_search_error_edge_case.js +0 -119
  102. package/src/scripts/args.js +0 -41
  103. package/src/scripts/bedrock-cache-debug.js +0 -186
  104. package/src/scripts/bedrock-content-aggregation-test.js +0 -195
  105. package/src/scripts/bedrock-merge-test.js +0 -80
  106. package/src/scripts/bedrock-parallel-tools-test.js +0 -150
  107. package/src/scripts/caching.js +0 -106
  108. package/src/scripts/cli.js +0 -152
  109. package/src/scripts/cli2.js +0 -119
  110. package/src/scripts/cli3.js +0 -163
  111. package/src/scripts/cli4.js +0 -165
  112. package/src/scripts/cli5.js +0 -165
  113. package/src/scripts/code_exec.js +0 -171
  114. package/src/scripts/code_exec_files.js +0 -180
  115. package/src/scripts/code_exec_multi_session.js +0 -185
  116. package/src/scripts/code_exec_ptc.js +0 -265
  117. package/src/scripts/code_exec_session.js +0 -217
  118. package/src/scripts/code_exec_simple.js +0 -120
  119. package/src/scripts/content.js +0 -111
  120. package/src/scripts/empty_input.js +0 -125
  121. package/src/scripts/handoff-test.js +0 -96
  122. package/src/scripts/image.js +0 -138
  123. package/src/scripts/memory.js +0 -83
  124. package/src/scripts/multi-agent-chain.js +0 -271
  125. package/src/scripts/multi-agent-conditional.js +0 -185
  126. package/src/scripts/multi-agent-document-review-chain.js +0 -171
  127. package/src/scripts/multi-agent-hybrid-flow.js +0 -264
  128. package/src/scripts/multi-agent-parallel-start.js +0 -214
  129. package/src/scripts/multi-agent-parallel.js +0 -346
  130. package/src/scripts/multi-agent-sequence.js +0 -184
  131. package/src/scripts/multi-agent-supervisor.js +0 -324
  132. package/src/scripts/multi-agent-test.js +0 -147
  133. package/src/scripts/parallel-asymmetric-tools-test.js +0 -202
  134. package/src/scripts/parallel-full-metadata-test.js +0 -176
  135. package/src/scripts/parallel-tools-test.js +0 -256
  136. package/src/scripts/programmatic_exec.js +0 -277
  137. package/src/scripts/programmatic_exec_agent.js +0 -168
  138. package/src/scripts/search.js +0 -118
  139. package/src/scripts/sequential-full-metadata-test.js +0 -143
  140. package/src/scripts/simple.js +0 -174
  141. package/src/scripts/single-agent-metadata-test.js +0 -152
  142. package/src/scripts/stream.js +0 -113
  143. package/src/scripts/test-custom-prompt-key.js +0 -132
  144. package/src/scripts/test-handoff-input.js +0 -143
  145. package/src/scripts/test-handoff-preamble.js +0 -227
  146. package/src/scripts/test-handoff-steering.js +0 -353
  147. package/src/scripts/test-multi-agent-list-handoff.js +0 -318
  148. package/src/scripts/test-parallel-agent-labeling.js +0 -253
  149. package/src/scripts/test-parallel-handoffs.js +0 -229
  150. package/src/scripts/test-thinking-handoff-bedrock.js +0 -132
  151. package/src/scripts/test-thinking-handoff.js +0 -132
  152. package/src/scripts/test-thinking-to-thinking-handoff-bedrock.js +0 -140
  153. package/src/scripts/test-tool-before-handoff-role-order.js +0 -223
  154. package/src/scripts/test-tools-before-handoff.js +0 -187
  155. package/src/scripts/test_code_api.js +0 -263
  156. package/src/scripts/thinking-bedrock.js +0 -128
  157. package/src/scripts/thinking-vertexai.js +0 -130
  158. package/src/scripts/thinking.js +0 -134
  159. package/src/scripts/tool_search.js +0 -114
  160. package/src/scripts/tools.js +0 -125
  161. package/src/specs/agent-handoffs-bedrock.integration.test.js +0 -280
  162. package/src/specs/agent-handoffs.test.js +0 -924
  163. package/src/specs/anthropic.simple.test.js +0 -287
  164. package/src/specs/azure.simple.test.js +0 -381
  165. package/src/specs/cache.simple.test.js +0 -282
  166. package/src/specs/custom-event-await.test.js +0 -148
  167. package/src/specs/deepseek.simple.test.js +0 -189
  168. package/src/specs/emergency-prune.test.js +0 -308
  169. package/src/specs/moonshot.simple.test.js +0 -237
  170. package/src/specs/observability.integration.test.js +0 -1337
  171. package/src/specs/openai.simple.test.js +0 -233
  172. package/src/specs/openrouter.simple.test.js +0 -202
  173. package/src/specs/prune.test.js +0 -733
  174. package/src/specs/reasoning.test.js +0 -144
  175. package/src/specs/spec.utils.js +0 -4
  176. package/src/specs/thinking-handoff.test.js +0 -486
  177. package/src/specs/thinking-prune.test.js +0 -600
  178. package/src/specs/token-distribution-edge-case.test.js +0 -246
  179. package/src/specs/token-memoization.test.js +0 -32
  180. package/src/specs/tokens.test.js +0 -49
  181. package/src/specs/tool-error.test.js +0 -139
  182. package/src/splitStream.js +0 -204
  183. package/src/splitStream.test.js +0 -504
  184. package/src/stream.js +0 -650
  185. package/src/stream.test.js +0 -225
  186. package/src/test/mockTools.js +0 -340
  187. package/src/tools/BrowserTools.js +0 -245
  188. package/src/tools/Calculator.js +0 -38
  189. package/src/tools/Calculator.test.js +0 -225
  190. package/src/tools/CodeExecutor.js +0 -233
  191. package/src/tools/ProgrammaticToolCalling.js +0 -602
  192. package/src/tools/StreamingToolCallBuffer.js +0 -179
  193. package/src/tools/ToolNode.js +0 -930
  194. package/src/tools/ToolSearch.js +0 -904
  195. package/src/tools/__tests__/BrowserTools.test.js +0 -306
  196. package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.js +0 -276
  197. package/src/tools/__tests__/ProgrammaticToolCalling.test.js +0 -807
  198. package/src/tools/__tests__/StreamingToolCallBuffer.test.js +0 -175
  199. package/src/tools/__tests__/ToolApproval.test.js +0 -675
  200. package/src/tools/__tests__/ToolNode.recovery.test.js +0 -200
  201. package/src/tools/__tests__/ToolNode.session.test.js +0 -319
  202. package/src/tools/__tests__/ToolSearch.integration.test.js +0 -125
  203. package/src/tools/__tests__/ToolSearch.test.js +0 -812
  204. package/src/tools/__tests__/handlers.test.js +0 -799
  205. package/src/tools/__tests__/truncation-recovery.integration.test.js +0 -362
  206. package/src/tools/handlers.js +0 -306
  207. package/src/tools/schema.js +0 -25
  208. package/src/tools/search/anthropic.js +0 -34
  209. package/src/tools/search/content.js +0 -116
  210. package/src/tools/search/content.test.js +0 -133
  211. package/src/tools/search/firecrawl.js +0 -173
  212. package/src/tools/search/format.js +0 -198
  213. package/src/tools/search/highlights.js +0 -241
  214. package/src/tools/search/index.js +0 -3
  215. package/src/tools/search/jina-reranker.test.js +0 -106
  216. package/src/tools/search/rerankers.js +0 -165
  217. package/src/tools/search/schema.js +0 -102
  218. package/src/tools/search/search.js +0 -561
  219. package/src/tools/search/serper-scraper.js +0 -126
  220. package/src/tools/search/test.js +0 -129
  221. package/src/tools/search/tool.js +0 -453
  222. package/src/tools/search/types.js +0 -2
  223. package/src/tools/search/utils.js +0 -59
  224. package/src/types/graph.js +0 -24
  225. package/src/types/graph.test.js +0 -192
  226. package/src/types/index.js +0 -7
  227. package/src/types/llm.js +0 -2
  228. package/src/types/messages.js +0 -2
  229. package/src/types/run.js +0 -2
  230. package/src/types/stream.js +0 -2
  231. package/src/types/tools.js +0 -2
  232. package/src/utils/contextAnalytics.js +0 -79
  233. package/src/utils/contextAnalytics.test.js +0 -166
  234. package/src/utils/events.js +0 -26
  235. package/src/utils/graph.js +0 -11
  236. package/src/utils/handlers.js +0 -65
  237. package/src/utils/index.js +0 -10
  238. package/src/utils/llm.js +0 -21
  239. package/src/utils/llmConfig.js +0 -205
  240. package/src/utils/logging.js +0 -37
  241. package/src/utils/misc.js +0 -51
  242. package/src/utils/run.js +0 -69
  243. package/src/utils/schema.js +0 -21
  244. package/src/utils/title.js +0 -119
  245. package/src/utils/tokens.js +0 -92
  246. 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