vectara-agentic 0.2.1__py3-none-any.whl → 0.2.2__py3-none-any.whl

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.

tests/endpoint.py CHANGED
@@ -1,8 +1,13 @@
1
1
  from openai import OpenAI
2
2
  from flask import Flask, request, jsonify
3
+ import logging
3
4
  from functools import wraps
4
5
 
5
6
  app = Flask(__name__)
7
+ app.config['TESTING'] = True
8
+
9
+ log = logging.getLogger('werkzeug')
10
+ log.setLevel(logging.ERROR)
6
11
 
7
12
  # Set your OpenAI API key (ensure you've set this in your environment)
8
13
 
@@ -39,4 +44,4 @@ def chat_completions():
39
44
 
40
45
  if __name__ == "__main__":
41
46
  # Run on port 5000 by default; adjust as needed.
42
- app.run(debug=True, port=5000)
47
+ app.run(debug=True, port=5000, use_reloader=False)
tests/test_agent.py CHANGED
@@ -6,6 +6,9 @@ from vectara_agentic.agent_config import AgentConfig
6
6
  from vectara_agentic.types import ModelProvider, ObserverType
7
7
  from vectara_agentic.tools import ToolsFactory
8
8
 
9
+ def mult(x, y):
10
+ return x * y
11
+
9
12
  class TestAgentPackage(unittest.TestCase):
10
13
  def test_get_prompt(self):
11
14
  prompt_template = "{chat_topic} on {today} with {custom_instructions}"
@@ -21,9 +24,6 @@ class TestAgentPackage(unittest.TestCase):
21
24
  )
22
25
 
23
26
  def test_agent_init(self):
24
- def mult(x, y):
25
- return x * y
26
-
27
27
  tools = [ToolsFactory().create_tool(mult)]
28
28
  topic = "AI"
29
29
  custom_instructions = "Always do as your mother tells you!"
@@ -41,9 +41,6 @@ class TestAgentPackage(unittest.TestCase):
41
41
  )
42
42
 
43
43
  def test_agent_config(self):
44
- def mult(x, y):
45
- return x * y
46
-
47
44
  tools = [ToolsFactory().create_tool(mult)]
48
45
  topic = "AI topic"
49
46
  instructions = "Always do as your father tells you, if your mother agrees!"
@@ -78,9 +75,6 @@ class TestAgentPackage(unittest.TestCase):
78
75
  )
79
76
 
80
77
  def test_multiturn(self):
81
- def mult(x, y):
82
- return x * y
83
-
84
78
  tools = [ToolsFactory().create_tool(mult)]
85
79
  topic = "AI topic"
86
80
  instructions = "Always do as your father tells you, if your mother agrees!"
@@ -127,6 +121,20 @@ class TestAgentPackage(unittest.TestCase):
127
121
  self.assertEqual(agent, agent_reloaded_again)
128
122
  self.assertEqual(agent.agent_type, agent_reloaded_again.agent_type)
129
123
 
124
+ def test_chat_history(self):
125
+ tools = [ToolsFactory().create_tool(mult)]
126
+ topic = "AI topic"
127
+ instructions = "Always do as your father tells you, if your mother agrees!"
128
+ agent = Agent(
129
+ tools=tools,
130
+ topic=topic,
131
+ custom_instructions=instructions,
132
+ chat_history=[("What is 5 times 10", "50"), ("What is 3 times 7", "21")]
133
+ )
134
+
135
+ res = agent.chat("multiply the results of the last two questions. Output only the answer.")
136
+ self.assertEqual(res.response, "1050")
137
+
130
138
 
131
139
  if __name__ == "__main__":
132
140
  unittest.main()
@@ -1,4 +1,4 @@
1
1
  """
2
2
  Define the version of the package.
3
3
  """
4
- __version__ = "0.2.1"
4
+ __version__ = "0.2.2"
vectara_agentic/agent.py CHANGED
@@ -11,6 +11,8 @@ import logging
11
11
  import traceback
12
12
  import asyncio
13
13
 
14
+ from collections import Counter
15
+
14
16
  import cloudpickle as pickle
15
17
 
16
18
  from dotenv import load_dotenv
@@ -144,6 +146,7 @@ class Agent:
144
146
  query_logging_callback: Optional[Callable[[str, str], None]] = None,
145
147
  agent_config: Optional[AgentConfig] = None,
146
148
  chat_history: Optional[list[Tuple[str, str]]] = None,
149
+ validate_tools: bool = False,
147
150
  ) -> None:
148
151
  """
149
152
  Initialize the agent with the specified type, tools, topic, and system message.
@@ -160,6 +163,8 @@ class Agent:
160
163
  agent_config (AgentConfig, optional): The configuration of the agent.
161
164
  Defaults to AgentConfig(), which reads from environment variables.
162
165
  chat_history (Tuple[str, str], optional): A list of user/agent chat pairs to initialize the agent memory.
166
+ validate_tools (bool, optional): Whether to validate tool inconsistency with instructions.
167
+ Defaults to False.
163
168
  """
164
169
  self.agent_config = agent_config or AgentConfig()
165
170
  self.agent_type = self.agent_config.agent_type
@@ -172,11 +177,37 @@ class Agent:
172
177
  self.agent_progress_callback = agent_progress_callback if agent_progress_callback else update_func
173
178
  self.query_logging_callback = query_logging_callback
174
179
 
180
+ # Validate tools
181
+ # Check for:
182
+ # 1. multiple copies of the same tool
183
+ # 2. Instructions for using tools that do not exist
184
+ tool_names = [tool.metadata.name for tool in self.tools]
185
+ duplicates = [tool for tool, count in Counter(tool_names).items() if count > 1]
186
+ if duplicates:
187
+ raise ValueError(f"Duplicate tools detected: {', '.join(duplicates)}")
188
+
189
+ if validate_tools:
190
+ prompt = f'''
191
+ Given the following instructions, and a list of tool names,
192
+ Please identify tools mentioned in the instructions that do not exist in the list.
193
+ Instructions:
194
+ {self._custom_instructions}
195
+ Tool names: {', '.join(tool_names)}
196
+ Your response should include a comma separated list of tool names that do not exist in the list.
197
+ Your response should be an empty string if all tools mentioned in the instructions are in the list.
198
+ '''
199
+ llm = get_llm(LLMRole.MAIN, config=self.agent_config)
200
+ bad_tools = llm.complete(prompt).text.split(", ")
201
+ if bad_tools:
202
+ raise ValueError(f"The Agent custom instructions mention these invalid tools: {', '.join(bad_tools)}")
203
+
204
+ # Create token counters for the main and tool LLMs
175
205
  main_tok = get_tokenizer_for_model(role=LLMRole.MAIN)
176
206
  self.main_token_counter = TokenCountingHandler(tokenizer=main_tok) if main_tok else None
177
207
  tool_tok = get_tokenizer_for_model(role=LLMRole.TOOL)
178
208
  self.tool_token_counter = TokenCountingHandler(tokenizer=tool_tok) if tool_tok else None
179
209
 
210
+ # Setup callback manager
180
211
  callbacks: list[BaseCallbackHandler] = [AgentCallbackHandler(self.agent_progress_callback)]
181
212
  if self.main_token_counter:
182
213
  callbacks.append(self.main_token_counter)
@@ -188,9 +219,9 @@ class Agent:
188
219
 
189
220
  if chat_history:
190
221
  msg_history = []
191
- for inx, text in enumerate(chat_history):
192
- role = MessageRole.USER if inx % 2 == 0 else MessageRole.ASSISTANT
193
- msg_history.append(ChatMessage.from_str(content=text, role=role))
222
+ for text_pairs in chat_history:
223
+ msg_history.append(ChatMessage.from_str(content=text_pairs[0], role=MessageRole.USER))
224
+ msg_history.append(ChatMessage.from_str(content=text_pairs[1], role=MessageRole.ASSISTANT))
194
225
  self.memory = ChatMemoryBuffer.from_defaults(token_limit=128000, chat_history=msg_history)
195
226
  else:
196
227
  self.memory = ChatMemoryBuffer.from_defaults(token_limit=128000)
@@ -652,7 +683,6 @@ class Agent:
652
683
 
653
684
  for tool in self.tools:
654
685
  # Serialize each tool's metadata, function, and dynamic model schema (QueryArgs)
655
- # TODO: deal with tools that have weakref (e.g. db_tools); for now those cannot be serialized.
656
686
  tool_dict = {
657
687
  "tool_type": tool.metadata.tool_type.value,
658
688
  "name": tool.metadata.name,
vectara_agentic/tools.py CHANGED
@@ -17,7 +17,6 @@ from llama_index.indices.managed.vectara import VectaraIndex
17
17
  from llama_index.core.utilities.sql_wrapper import SQLDatabase
18
18
  from llama_index.core.tools.types import ToolMetadata, ToolOutput
19
19
 
20
-
21
20
  from .types import ToolType
22
21
  from .tools_catalog import ToolsCatalog, get_bad_topics
23
22
  from .db_tools import DBLoadSampleData, DBLoadUniqueValues, DBLoadData
@@ -100,9 +99,14 @@ class VectaraTool(FunctionTool):
100
99
  fn_schema: Optional[Type[BaseModel]] = None,
101
100
  async_fn: Optional[AsyncCallable] = None,
102
101
  tool_metadata: Optional[ToolMetadata] = None,
102
+ callback: Optional[Callable[[Any], Any]] = None,
103
+ async_callback: Optional[AsyncCallable] = None,
103
104
  tool_type: ToolType = ToolType.QUERY,
104
105
  ) -> "VectaraTool":
105
- tool = FunctionTool.from_defaults(fn, name, description, return_direct, fn_schema, async_fn, tool_metadata)
106
+ tool = FunctionTool.from_defaults(
107
+ fn, name, description, return_direct, fn_schema, async_fn, tool_metadata,
108
+ callback, async_callback
109
+ )
106
110
  vectara_tool = cls(tool_type=tool_type, fn=tool.fn, metadata=tool.metadata, async_fn=tool.async_fn)
107
111
  return vectara_tool
108
112
 
@@ -302,6 +306,8 @@ class VectaraToolFactory:
302
306
  rerank_chain: List[Dict] = None,
303
307
  save_history: bool = True,
304
308
  verbose: bool = False,
309
+ vectara_base_url: str = "https://api.vectara.io",
310
+ vectara_verify_ssl: bool = True,
305
311
  ) -> VectaraTool:
306
312
  """
307
313
  Creates a Vectara search/retrieval tool
@@ -333,6 +339,8 @@ class VectaraToolFactory:
333
339
  If using slingshot/multilingual_reranker_v1, it must be first in the list.
334
340
  save_history (bool, optional): Whether to save the query in history.
335
341
  verbose (bool, optional): Whether to print verbose output.
342
+ vectara_base_url (str, optional): The base URL for the Vectara API.
343
+ vectara_verify_ssl (bool, optional): Whether to verify SSL certificates for the Vectara API.
336
344
 
337
345
  Returns:
338
346
  VectaraTool: A VectaraTool object.
@@ -342,6 +350,8 @@ class VectaraToolFactory:
342
350
  vectara_api_key=self.vectara_api_key,
343
351
  vectara_corpus_key=self.vectara_corpus_key,
344
352
  x_source_str="vectara-agentic",
353
+ base_url=vectara_base_url,
354
+ verify_ssl=vectara_verify_ssl,
345
355
  )
346
356
 
347
357
  # Dynamically generate the search function
@@ -482,6 +492,8 @@ class VectaraToolFactory:
482
492
  save_history: bool = False,
483
493
  fcs_threshold: float = 0.0,
484
494
  verbose: bool = False,
495
+ vectara_base_url: str = "https://api.vectara.io",
496
+ vectara_verify_ssl: bool = True,
485
497
  ) -> VectaraTool:
486
498
  """
487
499
  Creates a RAG (Retrieve and Generate) tool.
@@ -532,6 +544,8 @@ class VectaraToolFactory:
532
544
  fcs_threshold (float, optional): A threshold for factual consistency.
533
545
  If set above 0, the tool notifies the calling agent that it "cannot respond" if FCS is too low.
534
546
  verbose (bool, optional): Whether to print verbose output.
547
+ vectara_base_url (str, optional): The base URL for the Vectara API.
548
+ vectara_verify_ssl (bool, optional): Whether to verify SSL certificates for the Vectara API.
535
549
 
536
550
  Returns:
537
551
  VectaraTool: A VectaraTool object.
@@ -541,6 +555,8 @@ class VectaraToolFactory:
541
555
  vectara_api_key=self.vectara_api_key,
542
556
  vectara_corpus_key=self.vectara_corpus_key,
543
557
  x_source_str="vectara-agentic",
558
+ base_url=vectara_base_url,
559
+ verify_ssl=vectara_verify_ssl,
544
560
  )
545
561
 
546
562
  # Dynamically generate the RAG function
@@ -749,7 +765,6 @@ class ToolsFactory:
749
765
 
750
766
  # Get the tool spec class or function from the module
751
767
  tool_spec = getattr(module, tool_spec_name)
752
-
753
768
  func_type = LI_packages[tool_package_name]
754
769
  tools = tool_spec(**kwargs).to_tool_list()
755
770
  vtools = []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: vectara_agentic
3
- Version: 0.2.1
3
+ Version: 0.2.2
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,19 +16,19 @@ 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.11
20
- Requires-Dist: llama-index-indices-managed-vectara==0.4.0
19
+ Requires-Dist: llama-index==0.12.22
20
+ Requires-Dist: llama-index-indices-managed-vectara==0.4.1
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.3
24
- Requires-Dist: llama-index-llms-openai==0.3.18
25
- Requires-Dist: llama-index-llms-anthropic==0.6.4
23
+ Requires-Dist: llama-index-agent-openai==0.4.6
24
+ Requires-Dist: llama-index-llms-openai==0.3.25
25
+ Requires-Dist: llama-index-llms-anthropic==0.6.7
26
26
  Requires-Dist: llama-index-llms-together==0.3.1
27
27
  Requires-Dist: llama-index-llms-groq==0.3.1
28
- Requires-Dist: llama-index-llms-fireworks==0.3.1
28
+ Requires-Dist: llama-index-llms-fireworks==0.3.2
29
29
  Requires-Dist: llama-index-llms-cohere==0.4.0
30
- Requires-Dist: llama-index-llms-gemini==0.4.4
31
- Requires-Dist: llama-index-llms-bedrock==0.3.3
30
+ Requires-Dist: llama-index-llms-gemini==0.4.11
31
+ Requires-Dist: llama-index-llms-bedrock==0.3.4
32
32
  Requires-Dist: llama-index-tools-yahoo-finance==0.3.0
33
33
  Requires-Dist: llama-index-tools-arxiv==0.3.0
34
34
  Requires-Dist: llama-index-tools-database==0.3.0
@@ -38,8 +38,8 @@ Requires-Dist: llama-index-tools-neo4j==0.3.0
38
38
  Requires-Dist: llama-index-graph-stores-kuzu==0.6.0
39
39
  Requires-Dist: llama-index-tools-slack==0.3.0
40
40
  Requires-Dist: llama-index-tools-exa==0.3.0
41
- Requires-Dist: tavily-python==0.5.0
42
- Requires-Dist: exa-py==1.8.5
41
+ Requires-Dist: tavily-python==0.5.1
42
+ Requires-Dist: exa-py==1.8.9
43
43
  Requires-Dist: yahoo-finance==1.4.0
44
44
  Requires-Dist: openinference-instrumentation-llama-index==3.1.4
45
45
  Requires-Dist: opentelemetry-proto==1.26.0
@@ -50,7 +50,7 @@ Requires-Dist: tokenizers>=0.20
50
50
  Requires-Dist: pydantic==2.10.3
51
51
  Requires-Dist: retrying==1.3.4
52
52
  Requires-Dist: python-dotenv==1.0.1
53
- Requires-Dist: tiktoken==0.8.0
53
+ Requires-Dist: tiktoken==0.9.0
54
54
  Requires-Dist: cloudpickle>=3.1.1
55
55
  Requires-Dist: httpx==0.27.2
56
56
  Dynamic: author
@@ -1,23 +1,23 @@
1
1
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- tests/endpoint.py,sha256=rnHyXEZhjipyR2Stj2Mum331REChWuhmn5WPpyDryV0,1291
3
- tests/test_agent.py,sha256=SzSE1T_9PyIs-LUjj-fJjfGDlpJBzHUigyVX-KEhmJ4,4967
2
+ tests/endpoint.py,sha256=frnpdZQpnuQNNKNYgAn2rFTarNG8MCJaNA77Bw_W22A,1420
3
+ tests/test_agent.py,sha256=xd_JdSakJfbLEDm5h2Z-p8KJIZM7F7Hwqd25qMha3L8,5409
4
4
  tests/test_private_llm.py,sha256=b7RrOHHsTQKARHskCbh2I4f_LmjZmD5bdk1oEWGhP7s,2150
5
5
  tests/test_tools.py,sha256=lPihJ5mRdK66exWqDFRPEYIM2kUDeGtoaiG78UH5WMs,3499
6
6
  vectara_agentic/__init__.py,sha256=ADH4fPKLbpGNYYYszv3c3QDOjPToPE_qh3LpkH_seCU,430
7
7
  vectara_agentic/_callback.py,sha256=jpzHqnl297k2qajYc-6nkPtIPtgVLpVWYEISHS7ySlM,9186
8
8
  vectara_agentic/_observability.py,sha256=HeQYJIkqPLW3EWHiXHatkaJzo08IQGESKujdeWTuRgk,3805
9
9
  vectara_agentic/_prompts.py,sha256=7xOcRf9XNtpfFpDIUzgb-yMQ516K8X7bAzayAp406FU,6595
10
- vectara_agentic/_version.py,sha256=r1kR7ilT4Tx4v5m7GtBI1hwUMe-C5VRwnozb3l382_0,65
11
- vectara_agentic/agent.py,sha256=LMnJJfw2udDrsZAVlYpji0_rkmasHOsCuv206UJpH7Q,32007
10
+ vectara_agentic/_version.py,sha256=T1HvoeNWaV-7hM79Ns-wfsj8VWQtrCb1vYqbFa92N90,65
11
+ vectara_agentic/agent.py,sha256=g064FBJXS98Qg-pqJYkSCfqiEJ8cPtpAnInm0N8ZfBc,33494
12
12
  vectara_agentic/agent_config.py,sha256=yof3zU8OgYE5441EAwcoDBpTHDM5lNN-CyeO0LrT4-c,3350
13
13
  vectara_agentic/agent_endpoint.py,sha256=QIMejCLlpW2qzXxeDAxv3anF46XMDdVMdKGWhJh3azY,1996
14
14
  vectara_agentic/db_tools.py,sha256=3_hPrutNIGEeU2kH503GjcYbtAMsK6BidQLIm6DT6C8,3591
15
- vectara_agentic/tools.py,sha256=gI6zsVNh2SfAOqeQ5ZzAmf8NxkmtV6NUPJsTN7Cnb7o,39440
15
+ vectara_agentic/tools.py,sha256=bk4H1iUpo8Vjj9GtbNjAeZE2HpqbEpxspnnvxkqE2gs,40343
16
16
  vectara_agentic/tools_catalog.py,sha256=0gfF-JzTEnFS8e_x2uA6mvcvjVkY9ygRskxJetKGtrs,5231
17
17
  vectara_agentic/types.py,sha256=Qy7c7gSXJbvzddzhSRx2Flaf6a3go8u2LW17IKNxkKI,1603
18
18
  vectara_agentic/utils.py,sha256=ZhS82hA9yconr9yqDJ0GCBUjRxc06ZTlFaBzF67Yb3Y,5008
19
- vectara_agentic-0.2.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
20
- vectara_agentic-0.2.1.dist-info/METADATA,sha256=ZZpRSVHVy9gI9QsNHFKKtdYyl3DWbR_h_LyD6oX9bJw,21857
21
- vectara_agentic-0.2.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
22
- vectara_agentic-0.2.1.dist-info/top_level.txt,sha256=Y7TQTFdOYGYodQRltUGRieZKIYuzeZj2kHqAUpfCUfg,22
23
- vectara_agentic-0.2.1.dist-info/RECORD,,
19
+ vectara_agentic-0.2.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
20
+ vectara_agentic-0.2.2.dist-info/METADATA,sha256=TEbmq0rzQ4dLo0D3VLkajDAeicYQb3VvwY61LVdWeKA,21858
21
+ vectara_agentic-0.2.2.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
22
+ vectara_agentic-0.2.2.dist-info/top_level.txt,sha256=Y7TQTFdOYGYodQRltUGRieZKIYuzeZj2kHqAUpfCUfg,22
23
+ vectara_agentic-0.2.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (75.8.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5