vectara-agentic 0.2.11__py3-none-any.whl → 0.2.12__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.

@@ -22,8 +22,8 @@ GENERAL_INSTRUCTIONS = """
22
22
  3) If a tool fails, try other tools that might be appropriate to gain the information you need.
23
23
  - If after retrying you can't get the information or answer the question, respond with "I don't know".
24
24
  - If a tool provides citations or references in markdown as part of its response, include the references in your response.
25
- - Ensure that every URL in your responses includes descriptive anchor text that clearly explains what the user can expect from the linked content.
26
- Avoid using generic terms like “source” or “reference as the anchor text.
25
+ - Ensure that every URL in your response includes descriptive anchor text that clearly explains what the user can expect from the linked content.
26
+ Avoid using generic terms like “source” or “reference”, or the full URL, as the anchor text.
27
27
  - If a tool returns in the metadata a valid URL pointing to a PDF file, along with page number - then combine the URL and page number in the response.
28
28
  For example, if the URL returned from the tool is "https://example.com/doc.pdf" and "page=5", then the combined URL would be "https://example.com/doc.pdf#page=5".
29
29
  If a tool returns in the metadata invalid URLs or an URL empty (e.g. "[[1]()]"), ignore it and do not include that citation or reference in your response.
@@ -1,4 +1,4 @@
1
1
  """
2
2
  Define the version of the package.
3
3
  """
4
- __version__ = "0.2.11"
4
+ __version__ = "0.2.12"
vectara_agentic/agent.py CHANGED
@@ -661,7 +661,7 @@ class Agent:
661
661
  for tool in self.tools:
662
662
  if hasattr(tool, 'metadata'):
663
663
  if detailed:
664
- print(f"- {tool.metadata.name} - {tool.metadata.description}")
664
+ print(f"- {tool.metadata.description}")
665
665
  else:
666
666
  print(f"- {tool.metadata.name}")
667
667
  else:
@@ -118,7 +118,7 @@ class DatabaseTools:
118
118
  try:
119
119
  count_rows = self._load_data(count_query)
120
120
  except Exception as e:
121
- return [f"Error ({str(e)}) occurred while counting number of rows"]
121
+ return [f"Error ({str(e)}) occurred while counting number of rows, check your query."]
122
122
  num_rows = int(count_rows[0].text)
123
123
  if num_rows > self.max_rows:
124
124
  return [
@@ -128,7 +128,7 @@ class DatabaseTools:
128
128
  try:
129
129
  res = self._load_data(sql_query)
130
130
  except Exception as e:
131
- return [f"Error ({str(e)}) occurred while executing the query {sql_query}"]
131
+ return [f"Error ({str(e)}) occurred while executing the query {sql_query}, check your query."]
132
132
  return [d.text for d in res]
133
133
 
134
134
  def load_sample_data(self, table_name: str, num_rows: int = 25) -> Any:
vectara_agentic/tools.py CHANGED
@@ -173,6 +173,21 @@ class VectaraTool(FunctionTool):
173
173
  ) -> ToolOutput:
174
174
  try:
175
175
  return super().call(*args, ctx=ctx, **kwargs)
176
+ except TypeError as e:
177
+ sig = inspect.signature(self.metadata.fn_schema)
178
+ valid_parameters = list(sig.parameters.keys())
179
+ params_str = ", ".join(valid_parameters)
180
+
181
+ err_output = ToolOutput(
182
+ tool_name=self.metadata.name,
183
+ content=(
184
+ f"Wrong argument used when calling {self.metadata.name}: {str(e)}. "
185
+ f"Valid arguments: {params_str}. please call the tool again with the correct arguments."
186
+ ),
187
+ raw_input={"args": args, "kwargs": kwargs},
188
+ raw_output={"response": str(e)},
189
+ )
190
+ return err_output
176
191
  except Exception as e:
177
192
  err_output = ToolOutput(
178
193
  tool_name=self.metadata.name,
@@ -187,6 +202,21 @@ class VectaraTool(FunctionTool):
187
202
  ) -> ToolOutput:
188
203
  try:
189
204
  return await super().acall(*args, ctx=ctx, **kwargs)
205
+ except TypeError as e:
206
+ sig = inspect.signature(self.metadata.fn_schema)
207
+ valid_parameters = list(sig.parameters.keys())
208
+ params_str = ", ".join(valid_parameters)
209
+
210
+ err_output = ToolOutput(
211
+ tool_name=self.metadata.name,
212
+ content=(
213
+ f"Wrong argument used when calling {self.metadata.name}: {str(e)}. "
214
+ f"Valid arguments: {params_str}. please call the tool again with the correct arguments."
215
+ ),
216
+ raw_input={"args": args, "kwargs": kwargs},
217
+ raw_output={"response": str(e)},
218
+ )
219
+ return err_output
190
220
  except Exception as e:
191
221
  err_output = ToolOutput(
192
222
  tool_name=self.metadata.name,
@@ -201,74 +231,115 @@ def _create_tool_from_dynamic_function(
201
231
  function: Callable[..., ToolOutput],
202
232
  tool_name: str,
203
233
  tool_description: str,
204
- base_params: list[inspect.Parameter],
205
- tool_args_schema: type[BaseModel],
234
+ base_params_model: Type[BaseModel], # Now a Pydantic BaseModel
235
+ tool_args_schema: Type[BaseModel],
206
236
  ) -> VectaraTool:
207
- """
208
- Create a VectaraTool from a dynamic function, including
209
- setting the function signature and creating the tool schema.
210
- """
211
237
  fields = {}
212
- for param in base_params:
238
+ base_params = []
239
+
240
+ # Create inspect.Parameter objects for base_params_model fields.
241
+ for param_name, model_field in base_params_model.model_fields.items():
242
+ field_type = base_params_model.__annotations__.get(
243
+ param_name, str
244
+ ) # default to str if not found
213
245
  default_value = (
214
- param.default if param.default != inspect.Parameter.empty else ...
246
+ model_field.default
247
+ if model_field.default is not None
248
+ else inspect.Parameter.empty
249
+ )
250
+ base_params.append(
251
+ inspect.Parameter(
252
+ param_name,
253
+ inspect.Parameter.POSITIONAL_OR_KEYWORD,
254
+ default=default_value,
255
+ annotation=field_type,
256
+ )
257
+ )
258
+ fields[param_name] = (
259
+ field_type,
260
+ model_field.default if model_field.default is not None else ...,
215
261
  )
216
- fields[param.name] = (param.annotation, default_value)
262
+
263
+ # Add tool_args_schema fields to the fields dict if not already included.
264
+ # Also add them to the function signature by creating new inspect.Parameter objects.
217
265
  for field_name, field_info in tool_args_schema.model_fields.items():
218
266
  if field_name not in fields:
219
267
  default_value = (
220
- field_info.default
221
- if field_info.default is not PydanticUndefined
222
- else ...
268
+ field_info.default if field_info.default is not None else ...
223
269
  )
224
- fields[field_name] = (field_info.annotation, default_value)
225
- fn_schema = create_model(f"{tool_name}", **fields)
226
-
227
- schema_params = [
228
- inspect.Parameter(
229
- name=field_name,
230
- kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
231
- default=(
232
- field_info.default
233
- if field_info.default is not PydanticUndefined
234
- else inspect.Parameter.empty
235
- ),
236
- annotation=(
237
- field_info.annotation
238
- if hasattr(field_info, "annotation")
239
- else field_info
240
- ),
241
- )
242
- for field_name, field_info in tool_args_schema.model_fields.items()
243
- if field_name not in [p.name for p in base_params]
244
- ]
245
- all_params = base_params + schema_params
270
+ field_type = tool_args_schema.__annotations__.get(field_name, None)
271
+ fields[field_name] = (field_type, default_value)
272
+ # Append these fields to the signature.
273
+ base_params.append(
274
+ inspect.Parameter(
275
+ field_name,
276
+ inspect.Parameter.POSITIONAL_OR_KEYWORD,
277
+ default=(
278
+ default_value
279
+ if default_value is not ...
280
+ else inspect.Parameter.empty
281
+ ),
282
+ annotation=field_type,
283
+ )
284
+ )
285
+
286
+ # Create the dynamic schema with both base_params_model and tool_args_schema fields.
287
+ fn_schema = create_model(f"{tool_name}_schema", **fields)
246
288
 
289
+ # Combine parameters into a function signature.
290
+ all_params = base_params[:] # Now all_params contains parameters from both models.
247
291
  required_params = [p for p in all_params if p.default is inspect.Parameter.empty]
248
292
  optional_params = [
249
293
  p for p in all_params if p.default is not inspect.Parameter.empty
250
294
  ]
251
- sig = inspect.Signature(required_params + optional_params)
252
- function.__signature__ = sig
295
+ function.__signature__ = inspect.Signature(required_params + optional_params)
253
296
  function.__annotations__["return"] = dict[str, Any]
254
297
  function.__name__ = re.sub(r"[^A-Za-z0-9_]", "_", tool_name)
255
298
 
256
- # Create the tool function signature string
257
- param_strs = []
299
+ # Build a docstring using parameter descriptions from the BaseModels.
300
+ params_str = ",\n ".join(
301
+ f"{p.name}: {p.annotation.__name__ if hasattr(p.annotation, '__name__') else p.annotation}"
302
+ for p in all_params
303
+ )
304
+ signature_line = f"{tool_name}(\n {params_str}\n) -> dict[str, Any]"
305
+ doc_lines = [
306
+ signature_line,
307
+ "",
308
+ tool_description.strip(),
309
+ "",
310
+ "Args:",
311
+ ]
258
312
  for param in all_params:
259
- annotation = param.annotation
313
+ description = ""
314
+ if param.name in base_params_model.model_fields:
315
+ description = base_params_model.model_fields[param.name].description
316
+ elif param.name in tool_args_schema.model_fields:
317
+ description = tool_args_schema.model_fields[param.name].description
318
+ if not description:
319
+ description = "No description provided."
260
320
  type_name = (
261
- annotation.__name__ if hasattr(annotation, "__name__") else str(annotation)
321
+ param.annotation.__name__
322
+ if hasattr(param.annotation, "__name__")
323
+ else str(param.annotation)
324
+ )
325
+ default_text = (
326
+ f", default={param.default!r}"
327
+ if param.default is not inspect.Parameter.empty
328
+ else ""
262
329
  )
263
- param_strs.append(f"{param.name}: {type_name}")
264
- args_str = ", ".join(param_strs)
265
- function_str = f"{tool_name}({args_str}) -> str"
330
+ doc_lines.append(f" {param.name} ({type_name}){default_text}: {description}")
331
+ doc_lines.append("")
332
+ doc_lines.append("Returns:")
333
+ return_desc = getattr(
334
+ function, "__return_description__", "A dictionary containing the result data."
335
+ )
336
+ doc_lines.append(f" dict[str, Any]: {return_desc}")
337
+ function.__doc__ = "\n".join(doc_lines)
266
338
 
267
- # Create the tool
268
339
  tool = VectaraTool.from_defaults(
269
340
  fn=function,
270
341
  name=tool_name,
271
- description=function_str + "\n" + tool_description,
342
+ description=function.__doc__,
272
343
  fn_schema=fn_schema,
273
344
  tool_type=ToolType.QUERY,
274
345
  )
@@ -592,36 +663,31 @@ class VectaraToolFactory:
592
663
  )
593
664
  return out
594
665
 
595
- base_params = [
596
- inspect.Parameter(
597
- "query", inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=str
598
- ),
599
- inspect.Parameter(
600
- "top_k", inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=int
601
- ),
602
- inspect.Parameter(
603
- "summarize",
604
- inspect.Parameter.POSITIONAL_OR_KEYWORD,
605
- default=True,
606
- annotation=bool,
607
- ),
608
- ]
666
+ class SearchToolBaseParams(BaseModel):
667
+ """Model for the base parameters of the search tool."""
668
+ query: str = Field(
669
+ ...,
670
+ description="The search query to perform, always in the form of a question.",
671
+ )
672
+ top_k: int = Field(
673
+ 10, description="The number of top documents to retrieve."
674
+ )
675
+ summarize: bool = Field(
676
+ True,
677
+ description="Flag that indicates whether to summarize the retrieved documents.",
678
+ )
679
+
609
680
  search_tool_extra_desc = (
610
681
  tool_description
611
682
  + "\n"
612
- + """
613
- This tool is meant to perform a search for relevant documents, it is not meant for asking questions.
614
- The response includes metadata about each relevant document.
615
- If summarize=True, it also includes a summary of each document, but takes a lot longer to respond,
616
- so avoid using it unless necessary.
617
- """
683
+ + "This tool is meant to perform a search for relevant documents, it is not meant for asking questions."
618
684
  )
619
685
 
620
686
  tool = _create_tool_from_dynamic_function(
621
687
  search_function,
622
688
  tool_name,
623
689
  search_tool_extra_desc,
624
- base_params,
690
+ SearchToolBaseParams,
625
691
  tool_args_schema,
626
692
  )
627
693
  return tool
@@ -852,16 +918,18 @@ class VectaraToolFactory:
852
918
  )
853
919
  return out
854
920
 
855
- base_params = [
856
- inspect.Parameter(
857
- "query", inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=str
858
- ),
859
- ]
921
+ class RagToolBaseParams(BaseModel):
922
+ """Model for the base parameters of the RAG tool."""
923
+ query: str = Field(
924
+ ...,
925
+ description="The search query to perform, always in the form of a question",
926
+ )
927
+
860
928
  tool = _create_tool_from_dynamic_function(
861
929
  rag_function,
862
930
  tool_name,
863
931
  tool_description,
864
- base_params,
932
+ RagToolBaseParams,
865
933
  tool_args_schema,
866
934
  )
867
935
  return tool
vectara_agentic/utils.py CHANGED
@@ -103,7 +103,7 @@ def get_llm(
103
103
  elif model_provider == ModelProvider.ANTHROPIC:
104
104
  llm = Anthropic(
105
105
  model=model_name, temperature=0,
106
- max_tokens=max_tokens, cache_idx=2,
106
+ max_tokens=max_tokens,
107
107
  )
108
108
  elif model_provider == ModelProvider.GEMINI:
109
109
  from llama_index.llms.gemini import Gemini
@@ -124,7 +124,8 @@ def get_llm(
124
124
  from llama_index.llms.groq import Groq
125
125
  llm = Groq(
126
126
  model=model_name, temperature=0,
127
- is_function_calling_model=True, max_tokens=max_tokens
127
+ is_function_calling_model=True,
128
+ max_tokens=max_tokens
128
129
  )
129
130
  elif model_provider == ModelProvider.FIREWORKS:
130
131
  from llama_index.llms.fireworks import Fireworks
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vectara_agentic
3
- Version: 0.2.11
3
+ Version: 0.2.12
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,17 +16,17 @@ 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.29
19
+ Requires-Dist: llama-index==0.12.30
20
20
  Requires-Dist: llama-index-indices-managed-vectara==0.4.2
21
21
  Requires-Dist: llama-index-agent-llm-compiler==0.3.0
22
22
  Requires-Dist: llama-index-agent-lats==0.3.0
23
23
  Requires-Dist: llama-index-agent-openai==0.4.6
24
- Requires-Dist: llama-index-llms-openai==0.3.32
24
+ Requires-Dist: llama-index-llms-openai==0.3.35
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
- Requires-Dist: llama-index-llms-cohere==0.4.0
29
+ Requires-Dist: llama-index-llms-cohere==0.4.1
30
30
  Requires-Dist: llama-index-llms-gemini==0.4.14
31
31
  Requires-Dist: llama-index-llms-bedrock==0.3.8
32
32
  Requires-Dist: llama-index-tools-yahoo-finance==0.3.0
@@ -141,7 +141,6 @@ from vectara_agentic.tools import VectaraToolFactory
141
141
 
142
142
  vec_factory = VectaraToolFactory(
143
143
  vectara_api_key=os.environ['VECTARA_API_KEY'],
144
- vectara_customer_id=os.environ['VECTARA_CUSTOMER_ID'],
145
144
  vectara_corpus_key=os.environ['VECTARA_CORPUS_KEY']
146
145
  )
147
146
  ```
@@ -162,7 +161,6 @@ tickers = {
162
161
  }
163
162
 
164
163
  class QueryFinancialReportsArgs(BaseModel):
165
- query: str = Field(..., description="The user query.")
166
164
  year: int | str = Field(..., description=f"The year this query relates to. An integer between {min(years)} and {max(years)} or a string specifying a condition on the year (example: '>2020').")
167
165
  ticker: str = Field(..., description=f"The company ticker. Must be a valid ticket symbol from the list {tickers.keys()}.")
168
166
 
@@ -176,6 +174,8 @@ query_financial_reports_tool = vec_factory.create_rag_tool(
176
174
  )
177
175
  ```
178
176
 
177
+ Note that we only defined the `year` and `ticker` arguments. The `query` argument is automatically added by `vectara-agentic`.
178
+
179
179
  See the [docs](https://vectara.github.io/py-vectara-agentic/latest/) for additional arguments to customize your Vectara RAG tool.
180
180
 
181
181
  ### 3. Create other tools (optional)
@@ -11,19 +11,19 @@ tests/test_workflow.py,sha256=lVyrVHdRO5leYNbYtHTmKqMX0c8_xehCpUA7cXQKVsc,2175
11
11
  vectara_agentic/__init__.py,sha256=2GLDS3U6KckK-dBRl9v_x1kSV507gEhjOfuMmmu0Qxg,850
12
12
  vectara_agentic/_callback.py,sha256=ron49t1t-ox-736WaXzrZ99vhN4NI9bMiHFyj0iIPqg,13062
13
13
  vectara_agentic/_observability.py,sha256=BA2zhwa5930aaDUJxHefPlmIPt8kZOuLHVBc9PtYNuU,3839
14
- vectara_agentic/_prompts.py,sha256=CKbsFrosoM6bPH02t2R5_K3jzVzaxJAl85qO3mEAQ3U,9439
15
- vectara_agentic/_version.py,sha256=uneBdCHiroBsYz5R-8jYqrJU6UuA9Nu4vCqLtO0VSsE,66
16
- vectara_agentic/agent.py,sha256=KX0VYQuGFkK_CELjUFdxXWYHng32GFjsLdRdH-gR7aM,43970
14
+ vectara_agentic/_prompts.py,sha256=8vlT0jfS6Pc204KXMVg9SG7U61vqjtq1DObd2ewj2vQ,9456
15
+ vectara_agentic/_version.py,sha256=41ILS5AP8Yb7_UDVGW_HSrCI_wqeKaH8UUYkrgu369c,66
16
+ vectara_agentic/agent.py,sha256=5KKjl1IJasvDFwBu7yLHXoBmYioQA7BmqP2r-Vl-iZ0,43947
17
17
  vectara_agentic/agent_config.py,sha256=E-rtYMcpoGxnEAyy8231bizo2n0uGQ2qWxuSgTEfwdQ,4327
18
18
  vectara_agentic/agent_endpoint.py,sha256=QIMejCLlpW2qzXxeDAxv3anF46XMDdVMdKGWhJh3azY,1996
19
- vectara_agentic/db_tools.py,sha256=zhP1KIRNiE6BKD69VGmUdcjeKSZ6g0kTIsJdTDNCuv4,11141
19
+ vectara_agentic/db_tools.py,sha256=bAgqQMrpmu7KBaiAjJ4tpH8JwsFGEDk8iru5Deu0SEk,11179
20
20
  vectara_agentic/sub_query_workflow.py,sha256=xjySd2qjLAKwK6XuS0R0PTyk2uXraHCgCbDP1xDoFVI,12175
21
- vectara_agentic/tools.py,sha256=n06CwlEqOHlawEJj6BX8xHM5-kMrBQO48Jo68GKRKes,43874
21
+ vectara_agentic/tools.py,sha256=vwTlGQvbsGTAs2CtsyMOEyIXqR_nKq9fSv8t34zlMBc,47043
22
22
  vectara_agentic/tools_catalog.py,sha256=oiw3wAfbpFhh0_6rMvZsyPqWV6QIzHqhZCNzqRxuyV8,4818
23
23
  vectara_agentic/types.py,sha256=HcS7vR8P2v2xQTlOc6ZFV2vvlr3OpzSNWhtcLMxqUZc,1792
24
- vectara_agentic/utils.py,sha256=4vA5MyNoG47_7eHuLFQByiG_FHWbrQ6ZJDsdqHUwiJA,7720
25
- vectara_agentic-0.2.11.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
26
- vectara_agentic-0.2.11.dist-info/METADATA,sha256=c0ue2vnkkIwgNueoHQILYkui5eTDbXB7-SnBBnbWK0A,25088
27
- vectara_agentic-0.2.11.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
28
- vectara_agentic-0.2.11.dist-info/top_level.txt,sha256=Y7TQTFdOYGYodQRltUGRieZKIYuzeZj2kHqAUpfCUfg,22
29
- vectara_agentic-0.2.11.dist-info/RECORD,,
24
+ vectara_agentic/utils.py,sha256=Ku18_uSTmOOuWctXZJN67DbBb118-4KC_CsuVJyF1dc,7719
25
+ vectara_agentic-0.2.12.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
26
+ vectara_agentic-0.2.12.dist-info/METADATA,sha256=4R92R_XSohT4B2OZswbayIHCfvokLNFO9M_KB5ITniY,25098
27
+ vectara_agentic-0.2.12.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
28
+ vectara_agentic-0.2.12.dist-info/top_level.txt,sha256=Y7TQTFdOYGYodQRltUGRieZKIYuzeZj2kHqAUpfCUfg,22
29
+ vectara_agentic-0.2.12.dist-info/RECORD,,