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

vectara_agentic/tools.py CHANGED
@@ -18,13 +18,7 @@ from llama_index.core.tools.types import ToolMetadata, ToolOutput
18
18
 
19
19
 
20
20
  from .types import ToolType
21
- from .tools_catalog import (
22
- summarize_text,
23
- rephrase_text,
24
- critique_text,
25
- get_bad_topics,
26
- db_load_sample_data
27
- )
21
+ from .tools_catalog import summarize_text, rephrase_text, critique_text, get_bad_topics, DBLoadSampleData
28
22
 
29
23
  LI_packages = {
30
24
  "yahoo_finance": ToolType.QUERY,
@@ -51,24 +45,42 @@ LI_packages = {
51
45
  }
52
46
 
53
47
 
48
+ class VectaraToolMetadata(ToolMetadata):
49
+ """
50
+ A subclass of ToolMetadata adding the tool_type attribute.
51
+ """
52
+ tool_type: ToolType
53
+
54
+ def __init__(self, tool_type: ToolType, **kwargs):
55
+ super().__init__(**kwargs)
56
+ self.tool_type = tool_type
57
+
58
+ def __repr__(self) -> str:
59
+ """
60
+ Returns a string representation of the VectaraToolMetadata object, including the tool_type attribute.
61
+ """
62
+ base_repr = super().__repr__()
63
+ return f"{base_repr}, tool_type={self.tool_type}"
64
+
54
65
  class VectaraTool(FunctionTool):
55
66
  """
56
67
  A subclass of FunctionTool adding the tool_type attribute.
57
68
  """
69
+
58
70
  def __init__(
59
71
  self,
60
72
  tool_type: ToolType,
73
+ metadata: ToolMetadata,
61
74
  fn: Optional[Callable[..., Any]] = None,
62
- metadata: Optional[ToolMetadata] = None,
63
75
  async_fn: Optional[AsyncCallable] = None,
64
76
  ) -> None:
65
- self.tool_type = tool_type
66
- super().__init__(fn, metadata, async_fn)
77
+ metadata_dict = metadata.dict() if hasattr(metadata, 'dict') else metadata.__dict__
78
+ vm = VectaraToolMetadata(tool_type=tool_type, **metadata_dict)
79
+ super().__init__(fn, vm, async_fn)
67
80
 
68
81
  @classmethod
69
82
  def from_defaults(
70
83
  cls,
71
- tool_type: ToolType,
72
84
  fn: Optional[Callable[..., Any]] = None,
73
85
  name: Optional[str] = None,
74
86
  description: Optional[str] = None,
@@ -76,18 +88,14 @@ class VectaraTool(FunctionTool):
76
88
  fn_schema: Optional[Type[BaseModel]] = None,
77
89
  async_fn: Optional[AsyncCallable] = None,
78
90
  tool_metadata: Optional[ToolMetadata] = None,
91
+ tool_type: ToolType = ToolType.QUERY,
79
92
  ) -> "VectaraTool":
80
93
  tool = FunctionTool.from_defaults(fn, name, description, return_direct, fn_schema, async_fn, tool_metadata)
81
- vectara_tool = cls(
82
- tool_type=tool_type,
83
- fn=tool._fn,
84
- metadata=tool._metadata,
85
- async_fn=tool._async_fn
86
- )
94
+ vectara_tool = cls(tool_type=tool_type, fn=tool.fn, metadata=tool.metadata, async_fn=tool.async_fn)
87
95
  return vectara_tool
88
96
 
89
97
  def __eq__(self, other):
90
- if self.tool_type != other.tool_type:
98
+ if self.metadata.tool_type != other.metadata.tool_type:
91
99
  return False
92
100
 
93
101
  # Check if fn_schema is an instance of a BaseModel or a class itself (metaclass)
@@ -98,15 +106,15 @@ class VectaraTool(FunctionTool):
98
106
  if key not in other_schema_dict:
99
107
  is_equal = False
100
108
  break
101
- if (self_schema_dict[key].annotation != other_schema_dict[key].annotation or
102
- self_schema_dict[key].description != other_schema_dict[key].description or
103
- self_schema_dict[key].is_required() != other_schema_dict[key].is_required()
109
+ if (
110
+ self_schema_dict[key].annotation != other_schema_dict[key].annotation
111
+ or self_schema_dict[key].description != other_schema_dict[key].description
112
+ or self_schema_dict[key].is_required() != other_schema_dict[key].is_required()
104
113
  ):
105
114
  is_equal = False
106
115
  break
107
116
  return is_equal
108
117
 
109
-
110
118
  class VectaraToolFactory:
111
119
  """
112
120
  A factory class for creating Vectara RAG tools.
@@ -145,7 +153,7 @@ class VectaraToolFactory:
145
153
  rerank_k: int = 50,
146
154
  mmr_diversity_bias: float = 0.2,
147
155
  include_citations: bool = True,
148
- fcs_threshold: float = 0.0
156
+ fcs_threshold: float = 0.0,
149
157
  ) -> VectaraTool:
150
158
  """
151
159
  Creates a RAG (Retrieve and Generate) tool.
@@ -175,7 +183,7 @@ class VectaraToolFactory:
175
183
  vectara_api_key=self.vectara_api_key,
176
184
  vectara_customer_id=self.vectara_customer_id,
177
185
  vectara_corpus_id=self.vectara_corpus_id,
178
- x_source_str="vectara-agentic"
186
+ x_source_str="vectara-agentic",
179
187
  )
180
188
 
181
189
  def _build_filter_string(kwargs):
@@ -225,7 +233,7 @@ class VectaraToolFactory:
225
233
  tool_name=rag_function.__name__,
226
234
  content=msg,
227
235
  raw_input={"args": args, "kwargs": kwargs},
228
- raw_output={'response': msg}
236
+ raw_output={"response": msg},
229
237
  )
230
238
  if len(response.source_nodes) == 0:
231
239
  msg = "Tool failed to generate a response since no matches were found."
@@ -233,18 +241,28 @@ class VectaraToolFactory:
233
241
  tool_name=rag_function.__name__,
234
242
  content=msg,
235
243
  raw_input={"args": args, "kwargs": kwargs},
236
- raw_output={'response': msg}
244
+ raw_output={"response": msg},
237
245
  )
238
246
 
239
247
  # Extract citation metadata
240
248
  pattern = r"\[(\d+)\]"
241
249
  matches = re.findall(pattern, response.response)
242
- citation_numbers = sorted(set([int(match) for match in matches]))
250
+ citation_numbers = sorted(set(int(match) for match in matches))
243
251
  citation_metadata = ""
244
252
  keys_to_ignore = ["lang", "offset", "len"]
245
253
  for citation_number in citation_numbers:
246
254
  metadata = response.source_nodes[citation_number - 1].metadata
247
- citation_metadata += f"""[{citation_number}]: {"; ".join([f"{k}='{v}'" for k,v in metadata.items() if k not in keys_to_ignore])}.\n"""
255
+ citation_metadata += (
256
+ f"[{citation_number}]: "
257
+ + "; ".join(
258
+ [
259
+ f"{k}='{v}'"
260
+ for k, v in metadata.items()
261
+ if k not in keys_to_ignore
262
+ ]
263
+ )
264
+ + ".\n"
265
+ )
248
266
  fcs = response.metadata["fcs"] if "fcs" in response.metadata else 0.0
249
267
  if fcs < fcs_threshold:
250
268
  msg = f"Could not answer the query due to suspected hallucination (fcs={fcs})."
@@ -252,7 +270,7 @@ class VectaraToolFactory:
252
270
  tool_name=rag_function.__name__,
253
271
  content=msg,
254
272
  raw_input={"args": args, "kwargs": kwargs},
255
- raw_output={'response': msg}
273
+ raw_output={"response": msg},
256
274
  )
257
275
  res = {
258
276
  "response": response.response,
@@ -288,16 +306,16 @@ class VectaraToolFactory:
288
306
  # Create a new signature using the extracted parameters
289
307
  sig = inspect.Signature(params)
290
308
  rag_function.__signature__ = sig
291
- rag_function.__annotations__['return'] = dict[str, Any]
309
+ rag_function.__annotations__["return"] = dict[str, Any]
292
310
  rag_function.__name__ = "_" + re.sub(r"[^A-Za-z0-9_]", "_", tool_name)
293
311
 
294
312
  # Create the tool
295
313
  tool = VectaraTool.from_defaults(
296
- tool_type=ToolType.QUERY,
297
314
  fn=rag_function,
298
315
  name=tool_name,
299
316
  description=tool_description,
300
317
  fn_schema=tool_args_schema,
318
+ tool_type=ToolType.QUERY,
301
319
  )
302
320
  return tool
303
321
 
@@ -307,9 +325,7 @@ class ToolsFactory:
307
325
  A factory class for creating agent tools.
308
326
  """
309
327
 
310
- def create_tool(
311
- self, function: Callable, tool_type: ToolType = ToolType.QUERY
312
- ) -> VectaraTool:
328
+ def create_tool(self, function: Callable, tool_type: ToolType = ToolType.QUERY) -> VectaraTool:
313
329
  """
314
330
  Create a tool from a function.
315
331
 
@@ -320,7 +336,7 @@ class ToolsFactory:
320
336
  Returns:
321
337
  VectaraTool: A VectaraTool object.
322
338
  """
323
- return VectaraTool.from_defaults(tool_type, function)
339
+ return VectaraTool.from_defaults(tool_type=tool_type, fn=function)
324
340
 
325
341
  def get_llama_index_tools(
326
342
  self,
@@ -342,10 +358,8 @@ class ToolsFactory:
342
358
  List[VectaraTool]: A list of VectaraTool objects.
343
359
  """
344
360
  # Dynamically install and import the module
345
- if tool_package_name not in LI_packages.keys():
346
- raise ValueError(
347
- f"Tool package {tool_package_name} from LlamaIndex not supported by Vectara-agentic."
348
- )
361
+ if tool_package_name not in LI_packages:
362
+ raise ValueError(f"Tool package {tool_package_name} from LlamaIndex not supported by Vectara-agentic.")
349
363
 
350
364
  module_name = f"llama_index.tools.{tool_package_name}"
351
365
  module = importlib.import_module(module_name)
@@ -358,21 +372,14 @@ class ToolsFactory:
358
372
  vtools = []
359
373
  for tool in tools:
360
374
  if len(tool_name_prefix) > 0:
361
- tool._metadata.name = tool_name_prefix + "_" + tool._metadata.name
375
+ tool.metadata.name = tool_name_prefix + "_" + tool.metadata.name
362
376
  if isinstance(func_type, dict):
363
377
  if tool_spec_name not in func_type.keys():
364
- raise ValueError(
365
- f"Tool spec {tool_spec_name} not found in package {tool_package_name}."
366
- )
378
+ raise ValueError(f"Tool spec {tool_spec_name} not found in package {tool_package_name}.")
367
379
  tool_type = func_type[tool_spec_name]
368
380
  else:
369
381
  tool_type = func_type
370
- vtool = VectaraTool(
371
- tool_type=tool_type,
372
- fn=tool.fn,
373
- metadata=tool.metadata,
374
- async_fn=tool.async_fn
375
- )
382
+ vtool = VectaraTool(tool_type=tool_type, fn=tool.fn, metadata=tool.metadata, async_fn=tool.async_fn)
376
383
  vtools.append(vtool)
377
384
  return vtools
378
385
 
@@ -386,23 +393,19 @@ class ToolsFactory:
386
393
  """
387
394
  Create a list of guardrail tools to avoid controversial topics.
388
395
  """
389
- return [
390
- self.create_tool(get_bad_topics)
391
- ]
396
+ return [self.create_tool(get_bad_topics)]
392
397
 
393
398
  def financial_tools(self):
394
399
  """
395
400
  Create a list of financial tools.
396
401
  """
397
- return self.get_llama_index_tools(
398
- tool_package_name="yahoo_finance",
399
- tool_spec_name="YahooFinanceToolSpec"
400
- )
402
+ return self.get_llama_index_tools(tool_package_name="yahoo_finance", tool_spec_name="YahooFinanceToolSpec")
401
403
 
402
404
  def legal_tools(self) -> List[FunctionTool]:
403
405
  """
404
406
  Create a list of legal tools.
405
407
  """
408
+
406
409
  def summarize_legal_text(
407
410
  text: str = Field(description="the original text."),
408
411
  ) -> str:
@@ -426,9 +429,7 @@ class ToolsFactory:
426
429
  """,
427
430
  )
428
431
 
429
- return [
430
- self.create_tool(tool) for tool in [summarize_legal_text, critique_as_judge]
431
- ]
432
+ return [self.create_tool(tool) for tool in [summarize_legal_text, critique_as_judge]]
432
433
 
433
434
  def database_tools(
434
435
  self,
@@ -482,18 +483,21 @@ class ToolsFactory:
482
483
  dbname=dbname,
483
484
  )
484
485
  else:
485
- raise Exception("Please provide a SqlDatabase option or a valid DB scheme type (postgresql, mysql, sqlite, mssql, oracle).")
486
+ raise ValueError(
487
+ "Please provide a SqlDatabase option or a valid DB scheme type "
488
+ " (postgresql, mysql, sqlite, mssql, oracle)."
489
+ )
486
490
 
487
491
  # Update tools with description
488
492
  for tool in tools:
489
493
  if content_description:
490
- tool._metadata.description = (
491
- tool._metadata.description
492
- + f"The database tables include data about {content_description}."
494
+ tool.metadata.description = (
495
+ tool.metadata.description + f"The database tables include data about {content_description}."
493
496
  )
494
497
 
495
- load_data_tool = [t for t in tools if t._metadata.name.endswith("load_data")][0]
496
- sample_data_fn = db_load_sample_data(load_data_tool)
498
+ # Update load_data_tool to return only text instead of "Document" objects (to save on space)
499
+ load_data_tool_index = next(i for i, t in enumerate(tools) if t.metadata.name.endswith("load_data"))
500
+ sample_data_fn = DBLoadSampleData(tools[load_data_tool_index])
497
501
  sample_data_fn.__name__ = f"{tool_name_prefix}_load_sample_data"
498
502
  sample_data_tool = self.create_tool(sample_data_fn, ToolType.QUERY)
499
503
  tools.append(sample_data_tool)
@@ -2,10 +2,10 @@
2
2
  This module contains the tools catalog for the Vectara Agentic.
3
3
  """
4
4
 
5
- from typing import Optional, Callable, Any, List
5
+ from typing import Callable, Any, List
6
+ from functools import lru_cache
6
7
  from pydantic import Field
7
8
  import requests
8
- from functools import lru_cache
9
9
 
10
10
  from .types import LLMRole
11
11
  from .utils import get_llm
@@ -24,7 +24,7 @@ get_headers = {
24
24
  #
25
25
  # Standard Tools
26
26
  #
27
- @lru_cache(maxsize=5)
27
+ @lru_cache(maxsize=None)
28
28
  def summarize_text(
29
29
  text: str = Field(description="the original text."),
30
30
  expertise: str = Field(
@@ -55,12 +55,11 @@ def summarize_text(
55
55
  response = llm.complete(prompt)
56
56
  return response.text
57
57
 
58
- @lru_cache(maxsize=5)
58
+
59
+ @lru_cache(maxsize=None)
59
60
  def rephrase_text(
60
61
  text: str = Field(description="the original text."),
61
- instructions: str = Field(
62
- description="the specific instructions for how to rephrase the text."
63
- ),
62
+ instructions: str = Field(description="the specific instructions for how to rephrase the text."),
64
63
  ) -> str:
65
64
  """
66
65
  This is a helper tool.
@@ -84,15 +83,12 @@ def rephrase_text(
84
83
  response = llm.complete(prompt)
85
84
  return response.text
86
85
 
87
- @lru_cache(maxsize=5)
86
+
87
+ @lru_cache(maxsize=None)
88
88
  def critique_text(
89
89
  text: str = Field(description="the original text."),
90
- role: Optional[str] = Field(
91
- None, description="the role of the person providing critique."
92
- ),
93
- point_of_view: Optional[str] = Field(
94
- None, description="the point of view with which to provide critique."
95
- ),
90
+ role: str = Field(default=None, description="the role of the person providing critique."),
91
+ point_of_view: str = Field(default=None, description="the point of view with which to provide critique."),
96
92
  ) -> str:
97
93
  """
98
94
  This is a helper tool.
@@ -109,9 +105,7 @@ def critique_text(
109
105
  if role:
110
106
  prompt = f"As a {role}, critique the provided text from the point of view of {point_of_view}."
111
107
  else:
112
- prompt = (
113
- f"Critique the provided text from the point of view of {point_of_view}."
114
- )
108
+ prompt = f"Critique the provided text from the point of view of {point_of_view}."
115
109
  prompt += "Structure the critique as bullet points.\n"
116
110
  prompt += f"Original text: {text}\nCritique:"
117
111
  llm = get_llm(LLMRole.TOOL)
@@ -126,21 +120,30 @@ def get_bad_topics() -> List[str]:
126
120
  """
127
121
  Get the list of topics to avoid in the response.
128
122
  """
129
- return ["politics", "religion", "violence", "hate speech", "adult content", "illegal activities"]
123
+ return [
124
+ "politics",
125
+ "religion",
126
+ "violence",
127
+ "hate speech",
128
+ "adult content",
129
+ "illegal activities",
130
+ ]
131
+
130
132
 
131
133
  #
132
134
  # Additional database tool
133
135
  #
134
- class db_load_sample_data:
136
+ class DBLoadSampleData:
135
137
  """
136
138
  A tool to load a sample of data from the specified database table.
137
139
 
138
- This tool fetches the first num_rows (default 25) rows from the given table using a provided database query function.
140
+ This tool fetches the first num_rows (default 25) rows from the given table
141
+ using a provided database query function.
139
142
  """
140
143
 
141
144
  def __init__(self, load_data_tool: Callable):
142
145
  """
143
- Initializes the db_load_sample_data with the provided load_data_tool function.
146
+ Initializes the DBLoadSampleData object with the provided load_data_tool function.
144
147
 
145
148
  Args:
146
149
  load_data_tool (Callable): A function to execute the SQL query.
vectara_agentic/types.py CHANGED
@@ -11,7 +11,6 @@ class AgentType(Enum):
11
11
  OPENAI = "OPENAI"
12
12
  LLMCOMPILER = "LLMCOMPILER"
13
13
 
14
-
15
14
  class ObserverType(Enum):
16
15
  """Enumeration for different types of observability integrations."""
17
16
 
vectara_agentic/utils.py CHANGED
@@ -3,8 +3,10 @@ Utilities for the Vectara agentic.
3
3
  """
4
4
 
5
5
  import os
6
- import tiktoken
7
6
  from typing import Tuple, Callable, Optional
7
+ from functools import lru_cache
8
+
9
+ import tiktoken
8
10
 
9
11
  from llama_index.core.llms import LLM
10
12
  from llama_index.llms.openai import OpenAI
@@ -24,11 +26,12 @@ provider_to_default_model_name = {
24
26
 
25
27
  DEFAULT_MODEL_PROVIDER = ModelProvider.OPENAI
26
28
 
29
+ @lru_cache(maxsize=None)
27
30
  def _get_llm_params_for_role(role: LLMRole) -> Tuple[ModelProvider, str]:
28
31
  """Get the model provider and model name for the specified role."""
29
32
  if role == LLMRole.TOOL:
30
33
  model_provider = ModelProvider(
31
- os.getenv("VECTARA_AGENTIC_TOOL_LLM_PROVIDER", DEFAULT_MODEL_PROVIDER)
34
+ os.getenv("VECTARA_AGENTIC_TOOL_LLM_PROVIDER", DEFAULT_MODEL_PROVIDER.value)
32
35
  )
33
36
  model_name = os.getenv(
34
37
  "VECTARA_AGENTIC_TOOL_MODEL_NAME",
@@ -36,14 +39,16 @@ def _get_llm_params_for_role(role: LLMRole) -> Tuple[ModelProvider, str]:
36
39
  )
37
40
  else:
38
41
  model_provider = ModelProvider(
39
- os.getenv("VECTARA_AGENTIC_MAIN_LLM_PROVIDER", DEFAULT_MODEL_PROVIDER)
42
+ os.getenv("VECTARA_AGENTIC_MAIN_LLM_PROVIDER", DEFAULT_MODEL_PROVIDER.value)
40
43
  )
41
44
  model_name = os.getenv(
42
45
  "VECTARA_AGENTIC_MAIN_MODEL_NAME",
43
46
  provider_to_default_model_name.get(model_provider),
44
47
  )
45
48
 
46
- agent_type = AgentType(os.getenv("VECTARA_AGENTIC_AGENT_TYPE", AgentType.OPENAI))
49
+ agent_type = AgentType(
50
+ os.getenv("VECTARA_AGENTIC_AGENT_TYPE", AgentType.OPENAI.value)
51
+ )
47
52
  if (
48
53
  role == LLMRole.MAIN
49
54
  and agent_type == AgentType.OPENAI
@@ -55,18 +60,18 @@ def _get_llm_params_for_role(role: LLMRole) -> Tuple[ModelProvider, str]:
55
60
 
56
61
  return model_provider, model_name
57
62
 
58
-
63
+ @lru_cache(maxsize=None)
59
64
  def get_tokenizer_for_model(role: LLMRole) -> Optional[Callable]:
60
65
  """Get the tokenizer for the specified model."""
61
66
  model_provider, model_name = _get_llm_params_for_role(role)
62
67
  if model_provider == ModelProvider.OPENAI:
63
68
  return tiktoken.encoding_for_model(model_name).encode
64
- elif model_provider == ModelProvider.ANTHROPIC:
69
+ if model_provider == ModelProvider.ANTHROPIC:
65
70
  return Anthropic().tokenizer
66
- else:
67
- return None
71
+ return None
68
72
 
69
73
 
74
+ @lru_cache(maxsize=None)
70
75
  def get_llm(role: LLMRole) -> LLM:
71
76
  """Get the LLM for the specified role."""
72
77
  model_provider, model_name = _get_llm_params_for_role(role)
@@ -74,7 +79,7 @@ def get_llm(role: LLMRole) -> LLM:
74
79
  if model_provider == ModelProvider.OPENAI:
75
80
  llm = OpenAI(model=model_name, temperature=0, is_function_calling_model=True)
76
81
  elif model_provider == ModelProvider.ANTHROPIC:
77
- llm = Anthropic(model=model_name, temperature=0, is_function_calling_model=True)
82
+ llm = Anthropic(model=model_name, temperature=0)
78
83
  elif model_provider == ModelProvider.GEMINI:
79
84
  from llama_index.llms.gemini import Gemini
80
85
  llm = Gemini(model=model_name, temperature=0, is_function_calling_model=True)
@@ -86,10 +91,10 @@ def get_llm(role: LLMRole) -> LLM:
86
91
  llm = Groq(model=model_name, temperature=0, is_function_calling_model=True)
87
92
  elif model_provider == ModelProvider.FIREWORKS:
88
93
  from llama_index.llms.fireworks import Fireworks
89
- llm = Fireworks(model=model_name, temperature=0, is_function_calling_model=True)
94
+ llm = Fireworks(model=model_name, temperature=0)
90
95
  elif model_provider == ModelProvider.COHERE:
91
96
  from llama_index.llms.cohere import Cohere
92
- llm = Cohere(model=model_name, temperature=0, is_function_calling_model=True)
97
+ llm = Cohere(model=model_name, temperature=0)
93
98
  else:
94
99
  raise ValueError(f"Unknown LLM provider: {model_provider}")
95
100
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vectara_agentic
3
- Version: 0.1.15
3
+ Version: 0.1.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,25 +16,25 @@ 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.11.13
19
+ Requires-Dist: llama-index==0.11.20
20
20
  Requires-Dist: llama-index-indices-managed-vectara==0.2.2
21
21
  Requires-Dist: llama-index-agent-llm-compiler==0.2.0
22
22
  Requires-Dist: llama-index-agent-openai==0.3.4
23
- Requires-Dist: llama-index-llms-openai==0.2.9
24
- Requires-Dist: llama-index-llms-anthropic==0.3.1
23
+ Requires-Dist: llama-index-llms-openai==0.2.16
24
+ Requires-Dist: llama-index-llms-anthropic==0.3.7
25
25
  Requires-Dist: llama-index-llms-together==0.2.0
26
26
  Requires-Dist: llama-index-llms-groq==0.2.0
27
- Requires-Dist: llama-index-llms-fireworks==0.2.0
28
- Requires-Dist: llama-index-llms-cohere==0.3.0
29
- Requires-Dist: llama-index-llms-gemini==0.3.5
27
+ Requires-Dist: llama-index-llms-fireworks==0.2.2
28
+ Requires-Dist: llama-index-llms-cohere==0.3.1
29
+ Requires-Dist: llama-index-llms-gemini==0.3.7
30
30
  Requires-Dist: llama-index-tools-yahoo-finance==0.2.0
31
31
  Requires-Dist: llama-index-tools-arxiv==0.2.0
32
32
  Requires-Dist: llama-index-tools-database==0.2.0
33
33
  Requires-Dist: llama-index-tools-google==0.2.0
34
34
  Requires-Dist: llama-index-tools-tavily-research==0.2.0
35
+ Requires-Dist: llama-index-tools-neo4j==0.2.0
35
36
  Requires-Dist: tavily-python==0.5.0
36
37
  Requires-Dist: yahoo-finance==1.4.0
37
- Requires-Dist: llama-index-tools-neo4j==0.2.0
38
38
  Requires-Dist: openinference-instrumentation-llama-index==3.0.2
39
39
  Requires-Dist: arize-phoenix==4.35.1
40
40
  Requires-Dist: arize-phoenix-otel==0.5.1
@@ -68,13 +68,29 @@ Requires-Dist: dill==0.3.8
68
68
 
69
69
  ## ✨ Overview
70
70
 
71
- `vectara-agentic` is a Python library for developing powerful AI assistants using Vectara and Agentic-RAG. It leverages the LlamaIndex Agent framework, customized for use with Vectara.
71
+ `vectara-agentic` is a Python library for developing powerful AI assistants and agents using Vectara and Agentic-RAG. It leverages the LlamaIndex Agent framework, customized for use with Vectara.
72
+
73
+ <p align="center">
74
+ <img src="https://raw.githubusercontent.com/vectara/py-vectara-agentic/main/.github/assets/diagram1.png" alt="Agentic RAG diagram" width="100%" style="vertical-align: middle;">
75
+ </p>
72
76
 
73
- ### Key Features
77
+ ### Features
74
78
 
79
+ - Enables easy creation of custom AI assistants and agents.
80
+ - Create a Vectara RAG tool with a single line of code.
75
81
  - Supports `ReAct`, `OpenAIAgent` and `LLMCompiler` agent types.
76
82
  - Includes pre-built tools for various domains (e.g., finance, legal).
77
- - Enables easy creation of custom AI assistants and agents.
83
+ - Integrates with various LLM inference services like OpenAI, Anthropic, Gemini, GROQ, Together.AI, Cohere and Fireworks
84
+ - Built-in support for observability with Arize Phoenix
85
+
86
+ ### 📚 Example AI Assistants
87
+
88
+ Check out our example AI assistants:
89
+
90
+ - [Financial Assistant](https://huggingface.co/spaces/vectara/finance-chat)
91
+ - [Justice Harvard Teaching Assistant](https://huggingface.co/spaces/vectara/Justice-Harvard)
92
+ - [Legal Assistant](https://huggingface.co/spaces/vectara/legal-agent)
93
+
78
94
 
79
95
  ### Prerequisites
80
96
 
@@ -197,7 +213,15 @@ When creating a VectaraToolFactory, you can pass in a `vectara_api_key`, `vectar
197
213
 
198
214
  ## ℹ️ Additional Information
199
215
 
200
- ### Agent Diagnostics
216
+ ### About Custom Instructions for your Agent
217
+
218
+ The custom instructions you provide to the agent guide its behavior.
219
+ Here are some guidelines when creating your instructions:
220
+ - Write precise and clear instructions, without overcomplicating.
221
+ - Consider edge cases and unusual or atypical scenarios.
222
+ - Be cautious to not over-specify behavior based on your primary use-case, as it may limit the agent's ability to behave properly in others.
223
+
224
+ ### Diagnostics
201
225
 
202
226
  The `Agent` class defines a few helpful methods to help you understand the internals of your application.
203
227
  * The `report()` method prints out the agent object’s type, the tools, and the LLMs used for the main agent and tool calling.
@@ -224,21 +248,43 @@ Then you can use Arize Phoenix in three ways:
224
248
  Now when you run your agent, all call traces are sent to Phoenix and recorded.
225
249
  In addition, vectara-agentic also records `FCS` (factual consistency score, aka HHEM) values into Arize for every Vectara RAG call. You can see those results in the `Feedback` column of the arize UI.
226
250
 
227
- ### About Custom Instructions
251
+ ## 🌐 API Endpoint
228
252
 
229
- The custom instructions you provide to the agent guide its behavior.
230
- Here are some guidelines when creating your instructions:
231
- - Write precise and clear instructions, without overcomplicating.
232
- - Consider edge cases and unusual or atypical scenarios.
233
- - Be cautious to not over-specify behavior based on your primary use-case, as it may limit the agent's ability to behave properly in others.
253
+ `vectara-agentic` can be easily hosted locally or on a remote machine behind an API endpoint, by following theses steps:
234
254
 
235
- ## 📚 Examples
255
+ ### Step 1: Setup your API key
256
+ Ensure that you have your API key set up as an environment variable:
236
257
 
237
- Check out our example AI assistants:
258
+ ```
259
+ export VECTARA_AGENTIC_API_KEY=<YOUR-ENDPOINT-API-KEY>
260
+ ```
238
261
 
239
- - [Financial Assistant](https://huggingface.co/spaces/vectara/finance-chat)
240
- - [Justice Harvard Teaching Assistant](https://huggingface.co/spaces/vectara/Justice-Harvard)
241
- - [Legal Assistant](https://huggingface.co/spaces/vectara/legal-agent)
262
+ ### Step 2: Start the API Server
263
+ Initialize the agent and start the FastAPI server by following this example:
264
+
265
+
266
+ ```
267
+ from agent import Agent
268
+ from agent_endpoint import start_app
269
+ agent = Agent(...) # Initialize your agent with appropriate parameters
270
+ start_app(agent)
271
+ ```
272
+
273
+ You can customize the host and port by passing them as arguments to `start_app()`:
274
+ * Default: host="0.0.0.0" and port=8000.
275
+ For example:
276
+ ```
277
+ start_app(agent, host="0.0.0.0", port=8000)
278
+ ```
279
+
280
+ ### Step 3: Access the API Endpoint
281
+ Once the server is running, you can interact with it using curl or any HTTP client. For example:
282
+
283
+ ```
284
+ curl -G "http://<remote-server-ip>:8000/chat" \
285
+ --data-urlencode "message=What is Vectara?" \
286
+ -H "X-API-Key: <YOUR-API-KEY>"
287
+ ```
242
288
 
243
289
  ## 🤝 Contributing
244
290
 
@@ -0,0 +1,18 @@
1
+ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ tests/test_agent.py,sha256=aQYYr_8hKlFiDgyI5Dd39TG5vkmDJe7F_nIzMTCLsTQ,2517
3
+ tests/test_tools.py,sha256=hDAlXkWKuXHnAjeQwMuTLTwNdRsM-xR7muBzFkZRefw,2942
4
+ vectara_agentic/__init__.py,sha256=FzVPx4Ti8Q5wVyUpNpsVuuRLjoyHkR563ncsfextd2k,508
5
+ vectara_agentic/_callback.py,sha256=EexD7-Qx2lZuQk4kjzwvIJAyfIzroWKz2VaVPD4TTkM,4621
6
+ vectara_agentic/_observability.py,sha256=v0xxTk8KI8nVK2rpyGqOVhyva9ymqOmZK5brKqFOwMM,3828
7
+ vectara_agentic/_prompts.py,sha256=CxSKueS4lF130VMSovFKeapTM9DZ8Ja4akEFIw7q0Ks,5670
8
+ vectara_agentic/agent.py,sha256=9nzPVb16wpeT5RiWQJiO5LuR9VTYp8yScKUqqgem7h8,19963
9
+ vectara_agentic/agent_endpoint.py,sha256=I3zTEezbAiNeW5I41r0NjIaR8Ucn4oe1XVcALekakaA,1959
10
+ vectara_agentic/tools.py,sha256=_rXEK9tuuDMM_Zf04AoehklydTMSb1esqEYkNjLvmyY,20103
11
+ vectara_agentic/tools_catalog.py,sha256=CpFTTyocsTu-Sx8KjqSsZZhLditSrV-vRZd2YMFU0AY,4940
12
+ vectara_agentic/types.py,sha256=FbZXc5oPje6kdimfrksDc8F-tYHSLK8ReAv7O291YkI,1131
13
+ vectara_agentic/utils.py,sha256=BCd5tI9LKVXuPc4WsxGwgbouLcWr200JDWSsGNUwZg0,3822
14
+ vectara_agentic-0.1.17.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
15
+ vectara_agentic-0.1.17.dist-info/METADATA,sha256=iFCMBcWNtYPnyR2RhBAnVvu-8uQWNzqJx8N3tSKL05k,13595
16
+ vectara_agentic-0.1.17.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
17
+ vectara_agentic-0.1.17.dist-info/top_level.txt,sha256=Y7TQTFdOYGYodQRltUGRieZKIYuzeZj2kHqAUpfCUfg,22
18
+ vectara_agentic-0.1.17.dist-info/RECORD,,