vectara-agentic 0.2.15__tar.gz → 0.2.17__tar.gz

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.

Potentially problematic release.


This version of vectara-agentic might be problematic. Click here for more details.

Files changed (42) hide show
  1. {vectara_agentic-0.2.15/vectara_agentic.egg-info → vectara_agentic-0.2.17}/PKG-INFO +62 -19
  2. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/README.md +52 -11
  3. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/requirements.txt +9 -7
  4. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/tests/test_agent.py +2 -2
  5. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/tests/test_agent_planning.py +1 -1
  6. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/tests/test_groq.py +3 -1
  7. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/tests/test_tools.py +119 -17
  8. vectara_agentic-0.2.17/tests/test_workflow.py +134 -0
  9. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/_observability.py +1 -1
  10. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/_prompts.py +4 -2
  11. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/_version.py +1 -1
  12. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/agent.py +147 -69
  13. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/db_tools.py +2 -2
  14. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/llm_utils.py +10 -6
  15. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/sub_query_workflow.py +5 -2
  16. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/tool_utils.py +112 -84
  17. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/tools.py +3 -1
  18. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/tools_catalog.py +1 -0
  19. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/utils.py +1 -1
  20. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17/vectara_agentic.egg-info}/PKG-INFO +62 -19
  21. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic.egg-info/requires.txt +9 -7
  22. vectara_agentic-0.2.15/tests/test_workflow.py +0 -67
  23. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/LICENSE +0 -0
  24. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/MANIFEST.in +0 -0
  25. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/setup.cfg +0 -0
  26. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/setup.py +0 -0
  27. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/tests/__init__.py +0 -0
  28. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/tests/endpoint.py +0 -0
  29. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/tests/test_agent_type.py +0 -0
  30. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/tests/test_fallback.py +0 -0
  31. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/tests/test_private_llm.py +0 -0
  32. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/tests/test_return_direct.py +0 -0
  33. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/tests/test_serialization.py +0 -0
  34. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/tests/test_vectara_llms.py +0 -0
  35. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/__init__.py +0 -0
  36. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/_callback.py +0 -0
  37. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/agent_config.py +0 -0
  38. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/agent_endpoint.py +0 -0
  39. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic/types.py +0 -0
  40. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic.egg-info/SOURCES.txt +0 -0
  41. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic.egg-info/dependency_links.txt +0 -0
  42. {vectara_agentic-0.2.15 → vectara_agentic-0.2.17}/vectara_agentic.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vectara_agentic
3
- Version: 0.2.15
3
+ Version: 0.2.17
4
4
  Summary: A Python package for creating AI Assistants and AI Agents with Vectara
5
5
  Home-page: https://github.com/vectara/py-vectara-agentic
6
6
  Author: Ofer Mendelevitch
@@ -16,18 +16,18 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
16
  Requires-Python: >=3.10
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: llama-index==0.12.33
20
- Requires-Dist: llama-index-indices-managed-vectara==0.4.4
19
+ Requires-Dist: llama-index==0.12.35
20
+ Requires-Dist: llama-index-indices-managed-vectara==0.4.5
21
21
  Requires-Dist: llama-index-agent-llm-compiler==0.3.0
22
22
  Requires-Dist: llama-index-agent-lats==0.3.0
23
- Requires-Dist: llama-index-agent-openai==0.4.6
23
+ Requires-Dist: llama-index-agent-openai==0.4.7
24
24
  Requires-Dist: llama-index-llms-openai==0.3.38
25
25
  Requires-Dist: llama-index-llms-anthropic==0.6.10
26
26
  Requires-Dist: llama-index-llms-together==0.3.1
27
27
  Requires-Dist: llama-index-llms-groq==0.3.1
28
28
  Requires-Dist: llama-index-llms-fireworks==0.3.2
29
29
  Requires-Dist: llama-index-llms-cohere==0.4.1
30
- Requires-Dist: llama-index-llms-google-genai==0.1.8
30
+ Requires-Dist: llama-index-llms-google-genai==0.1.12
31
31
  Requires-Dist: llama-index-llms-bedrock==0.3.8
32
32
  Requires-Dist: llama-index-tools-yahoo-finance==0.3.0
33
33
  Requires-Dist: llama-index-tools-arxiv==0.3.0
@@ -36,15 +36,17 @@ Requires-Dist: llama-index-tools-google==0.3.0
36
36
  Requires-Dist: llama-index-tools-tavily_research==0.3.0
37
37
  Requires-Dist: llama_index.tools.brave_search==0.3.0
38
38
  Requires-Dist: llama-index-tools-neo4j==0.3.0
39
+ Requires-Dist: llama-index-tools-waii==0.3.0
39
40
  Requires-Dist: llama-index-graph-stores-kuzu==0.7.0
41
+ Requires-Dist: llama-index-tools-salesforce==0.3.0
40
42
  Requires-Dist: llama-index-tools-slack==0.3.0
41
43
  Requires-Dist: llama-index-tools-exa==0.3.0
42
44
  Requires-Dist: llama-index-tools-wikipedia==0.3.0
43
45
  Requires-Dist: llama-index-tools-bing-search==0.3.0
44
- Requires-Dist: tavily-python==0.5.4
45
- Requires-Dist: exa-py==1.12.0
46
+ Requires-Dist: tavily-python==0.7.2
47
+ Requires-Dist: exa-py==1.12.1
46
48
  Requires-Dist: openinference-instrumentation-llama-index==4.2.1
47
- Requires-Dist: opentelemetry-proto==1.32.1
49
+ Requires-Dist: opentelemetry-proto>=1.31.0
48
50
  Requires-Dist: arize-phoenix==8.26.1
49
51
  Requires-Dist: arize-phoenix-otel==0.9.2
50
52
  Requires-Dist: protobuf==5.29.3
@@ -365,51 +367,92 @@ vectara-agentic includes various other tools from LlamaIndex ToolSpecs:
365
367
  * Tavily Search: Real-time web search using [Tavily API](https://tavily.com/)
366
368
  ```python
367
369
  from vectara_agentic.tools_catalog import ToolsCatalog
368
- tavily_tool = ToolsCatalog(agent_config).tavily_search
370
+ tools_factory = ToolsFactory()
371
+ tavily_tools = tools_factory.get_llama_index_tools(
372
+ tool_package_name="tavily_research",
373
+ tool_spec_name="TavilyToolSpec",
374
+ api_key=str(os.environ["TAVILY_API_KEY"]),
375
+ )
369
376
  ```
370
377
  * EXA.AI: Advanced web search and data extraction
371
378
  ```python
372
- exa_tool = ToolsCatalog(agent_config).exa_search
379
+ exa_tools = tools_factory.get_llama_index_tools(
380
+ tool_package_name="exa.ai",
381
+ tool_spec_name="ExaToolSpec",
382
+ api_key=str(os.environ["EXA_API_KEY"]),
383
+ )
373
384
  ```
374
385
  * Brave Search: Web search using Brave's search engine
375
386
  ```python
376
- brave_tool = ToolsCatalog(agent_config).brave_search
387
+ brave_tools = tools_factory.get_llama_index_tools(
388
+ tool_package_name="brave_search",
389
+ tool_spec_name="BraveSearchToolSpec",
390
+ api_key=str(os.environ["BRAVE_API_KEY"]),
391
+ )
377
392
  ```
378
393
 
379
394
  * **Academic Tools**
380
395
  * arXiv: Search and retrieve academic papers
381
396
  ```python
382
- arxiv_tool = ToolsCatalog(agent_config).arxiv_search
397
+ arxiv_tools = tools_factory.get_llama_index_tools(
398
+ tool_package_name="arxiv",
399
+ tool_spec_name="ArxivToolSpec",
400
+ )
383
401
  ```
384
402
 
385
- * **Graph Database Tools**
403
+ * **Database Tools**
386
404
  * Neo4j: Graph database integration
387
405
  ```python
388
- neo4j_tool = ToolsCatalog(agent_config).neo4j_query
406
+ neo4j_tools = tools_factory.get_llama_index_tools(
407
+ tool_package_name="neo4j",
408
+ tool_spec_name="Neo4jQueryToolSpec",
409
+ )
389
410
  ```
390
411
  * Kuzu: Lightweight graph database
391
412
  ```python
392
- kuzu_tool = ToolsCatalog(agent_config).kuzu_query
413
+ kuzu_tools = tools_factory.get_llama_index_tools(
414
+ tool_package_name="kuzu",
415
+ tool_spec_name="KuzuGraphStore",
416
+ )
417
+ ```
418
+ * Waii: tools for natural langauge query of a relational database
419
+ ```python
420
+ waii_tools = tools_factory.get_llama_index_tools(
421
+ tool_package_name="waii",
422
+ tool_spec_name="WaiiToolSpec",
423
+ )
393
424
  ```
394
425
 
395
426
  * **Google Tools**
396
427
  * Gmail: Read and send emails
397
428
  ```python
398
- gmail_tool = ToolsCatalog(agent_config).gmail
429
+ gmail_tools = tools_factory.get_llama_index_tools(
430
+ tool_package_name="google",
431
+ tool_spec_name="GmailToolSpec",
432
+ )
399
433
  ```
400
434
  * Calendar: Manage calendar events
401
435
  ```python
402
- calendar_tool = ToolsCatalog(agent_config).calendar
436
+ calendar_tools = tools_factory.get_llama_index_tools(
437
+ tool_package_name="google",
438
+ tool_spec_name="GoogleCalendarToolSpec",
439
+ )
403
440
  ```
404
441
  * Search: Google search integration
405
442
  ```python
406
- google_search_tool = ToolsCatalog(agent_config).google_search
443
+ search_tools = tools_factory.get_llama_index_tools(
444
+ tool_package_name="google",
445
+ tool_spec_name="GoogleSearchToolSpec",
446
+ )
407
447
  ```
408
448
 
409
449
  * **Communication Tools**
410
450
  * Slack: Send messages and interact with Slack
411
451
  ```python
412
- slack_tool = ToolsCatalog(agent_config).slack
452
+ slack_tools = tools_factory.get_llama_index_tools(
453
+ tool_package_name="slack",
454
+ tool_spec_name="SlackToolSpec",
455
+ )
413
456
  ```
414
457
 
415
458
  For detailed setup instructions and API key requirements, please refer the instructions on [LlamaIndex hub](https://llamahub.ai/?tab=tools) for the specific tool.
@@ -295,51 +295,92 @@ vectara-agentic includes various other tools from LlamaIndex ToolSpecs:
295
295
  * Tavily Search: Real-time web search using [Tavily API](https://tavily.com/)
296
296
  ```python
297
297
  from vectara_agentic.tools_catalog import ToolsCatalog
298
- tavily_tool = ToolsCatalog(agent_config).tavily_search
298
+ tools_factory = ToolsFactory()
299
+ tavily_tools = tools_factory.get_llama_index_tools(
300
+ tool_package_name="tavily_research",
301
+ tool_spec_name="TavilyToolSpec",
302
+ api_key=str(os.environ["TAVILY_API_KEY"]),
303
+ )
299
304
  ```
300
305
  * EXA.AI: Advanced web search and data extraction
301
306
  ```python
302
- exa_tool = ToolsCatalog(agent_config).exa_search
307
+ exa_tools = tools_factory.get_llama_index_tools(
308
+ tool_package_name="exa.ai",
309
+ tool_spec_name="ExaToolSpec",
310
+ api_key=str(os.environ["EXA_API_KEY"]),
311
+ )
303
312
  ```
304
313
  * Brave Search: Web search using Brave's search engine
305
314
  ```python
306
- brave_tool = ToolsCatalog(agent_config).brave_search
315
+ brave_tools = tools_factory.get_llama_index_tools(
316
+ tool_package_name="brave_search",
317
+ tool_spec_name="BraveSearchToolSpec",
318
+ api_key=str(os.environ["BRAVE_API_KEY"]),
319
+ )
307
320
  ```
308
321
 
309
322
  * **Academic Tools**
310
323
  * arXiv: Search and retrieve academic papers
311
324
  ```python
312
- arxiv_tool = ToolsCatalog(agent_config).arxiv_search
325
+ arxiv_tools = tools_factory.get_llama_index_tools(
326
+ tool_package_name="arxiv",
327
+ tool_spec_name="ArxivToolSpec",
328
+ )
313
329
  ```
314
330
 
315
- * **Graph Database Tools**
331
+ * **Database Tools**
316
332
  * Neo4j: Graph database integration
317
333
  ```python
318
- neo4j_tool = ToolsCatalog(agent_config).neo4j_query
334
+ neo4j_tools = tools_factory.get_llama_index_tools(
335
+ tool_package_name="neo4j",
336
+ tool_spec_name="Neo4jQueryToolSpec",
337
+ )
319
338
  ```
320
339
  * Kuzu: Lightweight graph database
321
340
  ```python
322
- kuzu_tool = ToolsCatalog(agent_config).kuzu_query
341
+ kuzu_tools = tools_factory.get_llama_index_tools(
342
+ tool_package_name="kuzu",
343
+ tool_spec_name="KuzuGraphStore",
344
+ )
345
+ ```
346
+ * Waii: tools for natural langauge query of a relational database
347
+ ```python
348
+ waii_tools = tools_factory.get_llama_index_tools(
349
+ tool_package_name="waii",
350
+ tool_spec_name="WaiiToolSpec",
351
+ )
323
352
  ```
324
353
 
325
354
  * **Google Tools**
326
355
  * Gmail: Read and send emails
327
356
  ```python
328
- gmail_tool = ToolsCatalog(agent_config).gmail
357
+ gmail_tools = tools_factory.get_llama_index_tools(
358
+ tool_package_name="google",
359
+ tool_spec_name="GmailToolSpec",
360
+ )
329
361
  ```
330
362
  * Calendar: Manage calendar events
331
363
  ```python
332
- calendar_tool = ToolsCatalog(agent_config).calendar
364
+ calendar_tools = tools_factory.get_llama_index_tools(
365
+ tool_package_name="google",
366
+ tool_spec_name="GoogleCalendarToolSpec",
367
+ )
333
368
  ```
334
369
  * Search: Google search integration
335
370
  ```python
336
- google_search_tool = ToolsCatalog(agent_config).google_search
371
+ search_tools = tools_factory.get_llama_index_tools(
372
+ tool_package_name="google",
373
+ tool_spec_name="GoogleSearchToolSpec",
374
+ )
337
375
  ```
338
376
 
339
377
  * **Communication Tools**
340
378
  * Slack: Send messages and interact with Slack
341
379
  ```python
342
- slack_tool = ToolsCatalog(agent_config).slack
380
+ slack_tools = tools_factory.get_llama_index_tools(
381
+ tool_package_name="slack",
382
+ tool_spec_name="SlackToolSpec",
383
+ )
343
384
  ```
344
385
 
345
386
  For detailed setup instructions and API key requirements, please refer the instructions on [LlamaIndex hub](https://llamahub.ai/?tab=tools) for the specific tool.
@@ -1,15 +1,15 @@
1
- llama-index==0.12.33
2
- llama-index-indices-managed-vectara==0.4.4
1
+ llama-index==0.12.35
2
+ llama-index-indices-managed-vectara==0.4.5
3
3
  llama-index-agent-llm-compiler==0.3.0
4
4
  llama-index-agent-lats==0.3.0
5
- llama-index-agent-openai==0.4.6
5
+ llama-index-agent-openai==0.4.7
6
6
  llama-index-llms-openai==0.3.38
7
7
  llama-index-llms-anthropic==0.6.10
8
8
  llama-index-llms-together==0.3.1
9
9
  llama-index-llms-groq==0.3.1
10
10
  llama-index-llms-fireworks==0.3.2
11
11
  llama-index-llms-cohere==0.4.1
12
- llama-index-llms-google-genai ==0.1.8
12
+ llama-index-llms-google-genai ==0.1.12
13
13
  llama-index-llms-bedrock==0.3.8
14
14
  llama-index-tools-yahoo-finance==0.3.0
15
15
  llama-index-tools-arxiv==0.3.0
@@ -18,15 +18,17 @@ llama-index-tools-google==0.3.0
18
18
  llama-index-tools-tavily_research==0.3.0
19
19
  llama_index.tools.brave_search==0.3.0
20
20
  llama-index-tools-neo4j==0.3.0
21
+ llama-index-tools-waii==0.3.0
21
22
  llama-index-graph-stores-kuzu==0.7.0
23
+ llama-index-tools-salesforce==0.3.0
22
24
  llama-index-tools-slack==0.3.0
23
25
  llama-index-tools-exa==0.3.0
24
26
  llama-index-tools-wikipedia==0.3.0
25
27
  llama-index-tools-bing-search==0.3.0
26
- tavily-python==0.5.4
27
- exa-py==1.12.0
28
+ tavily-python==0.7.2
29
+ exa-py==1.12.1
28
30
  openinference-instrumentation-llama-index==4.2.1
29
- opentelemetry-proto==1.32.1
31
+ opentelemetry-proto>=1.31.0
30
32
  arize-phoenix==8.26.1
31
33
  arize-phoenix-otel==0.9.2
32
34
  protobuf==5.29.3
@@ -124,7 +124,7 @@ class TestAgentPackage(unittest.TestCase):
124
124
  self.assertEqual(res.response, "1050")
125
125
 
126
126
  def test_custom_general_instruction(self):
127
- general_instructions = "Always respond with 'I DIDNT DO IT'"
127
+ general_instructions = "Always respond with: I DIDN'T DO IT"
128
128
  agent = Agent.from_corpus(
129
129
  tool_name="RAG Tool",
130
130
  vectara_corpus_key="corpus_key",
@@ -135,7 +135,7 @@ class TestAgentPackage(unittest.TestCase):
135
135
  )
136
136
 
137
137
  res = agent.chat("What is the meaning of the universe?")
138
- self.assertEqual(res.response, "I DIDNT DO IT")
138
+ self.assertEqual(res.response, "I DIDN'T DO IT")
139
139
 
140
140
 
141
141
  if __name__ == "__main__":
@@ -4,7 +4,7 @@ from vectara_agentic.agent_config import AgentConfig
4
4
  from vectara_agentic.agent import Agent
5
5
  from vectara_agentic.tools import VectaraToolFactory
6
6
 
7
- # SETUP speical test account credentials for vectara
7
+ # SETUP special test account credentials for vectara
8
8
  # It's okay to expose these credentials in the test code
9
9
  vectara_corpus_key = "vectara-docs_1"
10
10
  vectara_api_key = 'zqt_UXrBcnI2UXINZkrv4g1tQPhzj02vfdtqYJIDiA'
@@ -113,7 +113,9 @@ class TestGROQ(unittest.TestCase):
113
113
  agent_config=fc_config_groq,
114
114
  )
115
115
  res = agent.chat("What is the stock price?")
116
- self.assertIn("I don't know", str(res))
116
+ self.assertTrue(
117
+ any(sub in str(res) for sub in ["I don't know", "I do not have"])
118
+ )
117
119
 
118
120
 
119
121
  if __name__ == "__main__":
@@ -1,6 +1,7 @@
1
1
  import unittest
2
2
  from pydantic import Field, BaseModel
3
-
3
+ from unittest.mock import patch, MagicMock
4
+ import requests
4
5
  from vectara_agentic.tools import (
5
6
  VectaraTool,
6
7
  VectaraToolFactory,
@@ -17,6 +18,7 @@ from llama_index.core.tools import FunctionTool
17
18
  vectara_corpus_key = "vectara-docs_1"
18
19
  vectara_api_key = "zqt_UXrBcnI2UXINZkrv4g1tQPhzj02vfdtqYJIDiA"
19
20
 
21
+ from typing import Optional
20
22
 
21
23
  class TestToolsPackage(unittest.TestCase):
22
24
 
@@ -89,7 +91,7 @@ class TestToolsPackage(unittest.TestCase):
89
91
  description="The ticker symbol for the company",
90
92
  examples=["AAPL", "GOOG"],
91
93
  )
92
- year: int | str = Field(
94
+ year: Optional[int | str] = Field(
93
95
  default=None,
94
96
  description="The year this query relates to. An integer between 2015 and 2024 or a string specifying a condition on the year",
95
97
  examples=[
@@ -109,6 +111,7 @@ class TestToolsPackage(unittest.TestCase):
109
111
  tool_args_schema=QueryToolArgs,
110
112
  )
111
113
 
114
+ # test an invalid argument name
112
115
  res = query_tool(
113
116
  query="What is the stock price?",
114
117
  the_year=2023,
@@ -126,6 +129,86 @@ class TestToolsPackage(unittest.TestCase):
126
129
  )
127
130
  self.assertIn("got an unexpected keyword argument 'the_year'", str(res))
128
131
 
132
+ @patch.object(requests.Session, "post")
133
+ def test_vectara_tool_ranges(self, mock_post):
134
+ # Configure the mock to return a dummy response.
135
+ response_text = "ALL GOOD"
136
+ mock_response = MagicMock()
137
+ mock_response.status_code = 200
138
+ mock_response.json.return_value = {
139
+ 'summary': response_text,
140
+ 'search_results': [
141
+ {'text': 'ALL GOOD', 'document_id': '12345', 'score': 0.9},
142
+ ]
143
+ }
144
+ mock_post.return_value = mock_response
145
+
146
+ vec_factory = VectaraToolFactory(vectara_corpus_key, vectara_api_key)
147
+
148
+ class QueryToolArgs(BaseModel):
149
+ ticker: str = Field(
150
+ description="The ticker symbol for the company",
151
+ examples=["AAPL", "GOOG"],
152
+ )
153
+ year: int | str = Field(
154
+ default=None,
155
+ description="The year this query relates to. An integer between 2015 and 2024 or a string specifying a condition on the year",
156
+ examples=[
157
+ 2020,
158
+ ">2021",
159
+ "<2023",
160
+ ">=2021",
161
+ "<=2023",
162
+ "[2021, 2023]",
163
+ "[2021, 2023)",
164
+ ],
165
+ )
166
+
167
+ query_tool = vec_factory.create_rag_tool(
168
+ tool_name="rag_tool",
169
+ tool_description="Returns a response (str) to the user query based on the data in this corpus.",
170
+ tool_args_schema=QueryToolArgs,
171
+ )
172
+
173
+ # test an invalid argument name
174
+ res = query_tool(
175
+ query="What is the stock price?",
176
+ year=">2023"
177
+ )
178
+ self.assertIn(response_text, str(res))
179
+
180
+ # Test a valid range
181
+ res = query_tool(
182
+ query="What is the stock price?",
183
+ year="[2021, 2023]",
184
+ )
185
+ self.assertIn(response_text, str(res))
186
+
187
+ # Test a valid half closed range
188
+ res = query_tool(
189
+ query="What is the stock price?",
190
+ year="[2020, 2023)",
191
+ )
192
+ self.assertIn(response_text, str(res))
193
+
194
+ # Test an operator
195
+ res = query_tool(
196
+ query="What is the stock price?",
197
+ year=">2022",
198
+ )
199
+ self.assertIn(response_text, str(res))
200
+
201
+ search_tool = vec_factory.create_search_tool(
202
+ tool_name="search_tool",
203
+ tool_description="Returns a list of documents (str) that match the user query.",
204
+ tool_args_schema=QueryToolArgs,
205
+ )
206
+ res = search_tool(
207
+ query="What is the stock price?",
208
+ the_year=2023,
209
+ )
210
+ self.assertIn("got an unexpected keyword argument 'the_year'", str(res))
211
+
129
212
  def test_tool_factory(self):
130
213
  def mult(x: float, y: float) -> float:
131
214
  return x * y
@@ -152,8 +235,6 @@ class TestToolsPackage(unittest.TestCase):
152
235
  self.assertEqual(tool.metadata.tool_type, ToolType.QUERY)
153
236
 
154
237
  def test_tool_with_many_arguments(self):
155
- vectara_corpus_key = "corpus_key"
156
- vectara_api_key = "api_key"
157
238
  vec_factory = VectaraToolFactory(vectara_corpus_key, vectara_api_key)
158
239
 
159
240
  class QueryToolArgs(BaseModel):
@@ -169,24 +250,18 @@ class TestToolsPackage(unittest.TestCase):
169
250
  arg10: str = Field(description="the tenth argument", examples=["val10"])
170
251
  arg11: str = Field(description="the eleventh argument", examples=["val11"])
171
252
  arg12: str = Field(description="the twelfth argument", examples=["val12"])
172
- arg13: str = Field(
173
- description="the thirteenth argument", examples=["val13"]
174
- )
175
- arg14: str = Field(
176
- description="the fourteenth argument", examples=["val14"]
177
- )
178
- arg15: str = Field(description="the fifteenth argument", examples=["val15"])
253
+ arg13: str = Field(description="the thirteenth argument", examples=["val13"])
179
254
 
180
255
  query_tool_1 = vec_factory.create_rag_tool(
181
256
  tool_name="rag_tool",
182
257
  tool_description="""
183
- A dummy tool that takes 15 arguments and returns a response (str) to the user query based on the data in this corpus.
258
+ A dummy tool that takes 13 arguments and returns a response (str) to the user query based on the data in this corpus.
184
259
  We are using this tool to test the tool factory works and does not crash with OpenAI.
185
260
  """,
186
261
  tool_args_schema=QueryToolArgs,
187
262
  )
188
263
 
189
- # Test with 15 arguments which go over the 1024 limit.
264
+ # Test with 13 arguments which go over the 1024 limit.
190
265
  config = AgentConfig(
191
266
  agent_type=AgentType.OPENAI
192
267
  )
@@ -208,7 +283,7 @@ class TestToolsPackage(unittest.TestCase):
208
283
  agent = Agent(
209
284
  tools=[query_tool_1],
210
285
  topic="Sample topic",
211
- custom_instructions="Call the tool with 15 arguments for GROQ",
286
+ custom_instructions="Call the tool with 13 arguments for GROQ",
212
287
  agent_config=config,
213
288
  )
214
289
  res = agent.chat("What is the stock price?")
@@ -223,14 +298,14 @@ class TestToolsPackage(unittest.TestCase):
223
298
  agent = Agent(
224
299
  tools=[query_tool_1],
225
300
  topic="Sample topic",
226
- custom_instructions="Call the tool with 15 arguments for ANTHROPIC",
301
+ custom_instructions="Call the tool with 13 arguments for ANTHROPIC",
227
302
  agent_config=config,
228
303
  )
229
304
  res = agent.chat("What is the stock price?")
230
305
  # ANTHROPIC does not have that 1024 limit
231
306
  self.assertIn("stock price", str(res))
232
307
 
233
- # But using Compact_docstring=True, we can pass 15 arguments successfully.
308
+ # But using Compact_docstring=True, we can pass 13 arguments successfully.
234
309
  vec_factory = VectaraToolFactory(
235
310
  vectara_corpus_key, vectara_api_key, compact_docstring=True
236
311
  )
@@ -251,7 +326,9 @@ class TestToolsPackage(unittest.TestCase):
251
326
  agent_config=config,
252
327
  )
253
328
  res = agent.chat("What is the stock price?")
254
- self.assertIn("stock price", str(res))
329
+ self.assertTrue(
330
+ any(sub in str(res) for sub in ["I don't know", "stock price"])
331
+ )
255
332
 
256
333
  def test_public_repo(self):
257
334
  vectara_corpus_key = "vectara-docs_1"
@@ -297,6 +374,31 @@ class TestToolsPackage(unittest.TestCase):
297
374
  "50",
298
375
  )
299
376
 
377
+ def test_vectara_tool_docstring(self):
378
+ class DummyArgs(BaseModel):
379
+ foo: int = Field(..., description="how many foos", examples=[1, 2, 3])
380
+ bar: str = Field(
381
+ "baz",
382
+ description="what bar to use",
383
+ examples=["x", "y"],
384
+ )
385
+
386
+ vec_factory = VectaraToolFactory(vectara_corpus_key, vectara_api_key)
387
+ dummy_tool = vec_factory.create_rag_tool(
388
+ tool_name="dummy_tool",
389
+ tool_description="A dummy tool.",
390
+ tool_args_schema=DummyArgs,
391
+ )
392
+
393
+ doc = dummy_tool.metadata.description
394
+ self.assertTrue(doc.startswith("dummy_tool(query: str, foo: int, bar: str) -> dict[str, Any]"))
395
+ self.assertIn("Args:", doc)
396
+ self.assertIn("query (str): The search query to perform, in the form of a question", doc)
397
+ self.assertIn("foo (int): how many foos (e.g., 1, 2, 3)", doc)
398
+ self.assertIn("bar (str, default='baz'): what bar to use (e.g., 'x', 'y')", doc)
399
+ self.assertIn("Returns:", doc)
400
+ self.assertIn("dict[str, Any]: A dictionary containing the result data.", doc)
401
+
300
402
 
301
403
  if __name__ == "__main__":
302
404
  unittest.main()