vectara-agentic 0.1.15__py3-none-any.whl → 0.1.16__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/__init__.py +2 -1
- vectara_agentic/_callback.py +0 -1
- vectara_agentic/_observability.py +18 -16
- vectara_agentic/_prompts.py +13 -8
- vectara_agentic/agent.py +105 -65
- vectara_agentic/agent_endpoint.py +63 -0
- vectara_agentic/tools.py +69 -65
- vectara_agentic/tools_catalog.py +24 -21
- vectara_agentic/types.py +0 -1
- vectara_agentic/utils.py +16 -11
- {vectara_agentic-0.1.15.dist-info → vectara_agentic-0.1.16.dist-info}/METADATA +68 -22
- vectara_agentic-0.1.16.dist-info/RECORD +18 -0
- {vectara_agentic-0.1.15.dist-info → vectara_agentic-0.1.16.dist-info}/WHEEL +1 -1
- vectara_agentic-0.1.15.dist-info/RECORD +0 -17
- {vectara_agentic-0.1.15.dist-info → vectara_agentic-0.1.16.dist-info}/LICENSE +0 -0
- {vectara_agentic-0.1.15.dist-info → vectara_agentic-0.1.16.dist-info}/top_level.txt +0 -0
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
|
-
|
|
66
|
-
|
|
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 (
|
|
102
|
-
self_schema_dict[key].
|
|
103
|
-
self_schema_dict[key].
|
|
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={
|
|
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={
|
|
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(
|
|
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 +=
|
|
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={
|
|
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__[
|
|
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
|
|
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.
|
|
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
|
|
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.
|
|
491
|
-
tool.
|
|
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
|
|
496
|
-
|
|
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)
|
vectara_agentic/tools_catalog.py
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
This module contains the tools catalog for the Vectara Agentic.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from typing import
|
|
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=
|
|
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
|
-
|
|
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
|
-
|
|
86
|
+
|
|
87
|
+
@lru_cache(maxsize=None)
|
|
88
88
|
def critique_text(
|
|
89
89
|
text: str = Field(description="the original text."),
|
|
90
|
-
role:
|
|
91
|
-
|
|
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 [
|
|
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
|
|
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
|
|
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
|
|
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
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", str(DEFAULT_MODEL_PROVIDER))
|
|
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", str(DEFAULT_MODEL_PROVIDER))
|
|
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(
|
|
49
|
+
agent_type = AgentType(
|
|
50
|
+
os.getenv("VECTARA_AGENTIC_AGENT_TYPE", str(AgentType.OPENAI))
|
|
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
|
-
|
|
69
|
+
if model_provider == ModelProvider.ANTHROPIC:
|
|
65
70
|
return Anthropic().tokenizer
|
|
66
|
-
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
3
|
+
Version: 0.1.16
|
|
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.11.
|
|
19
|
+
Requires-Dist: llama-index==0.11.18
|
|
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.
|
|
24
|
-
Requires-Dist: llama-index-llms-anthropic==0.3.
|
|
23
|
+
Requires-Dist: llama-index-llms-openai==0.2.15
|
|
24
|
+
Requires-Dist: llama-index-llms-anthropic==0.3.6
|
|
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.
|
|
28
|
-
Requires-Dist: llama-index-llms-cohere==0.3.
|
|
29
|
-
Requires-Dist: llama-index-llms-gemini==0.3.
|
|
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
|
|
@@ -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
72
|
|
|
73
|
-
|
|
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>
|
|
76
|
+
|
|
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
|
-
-
|
|
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
|
-
###
|
|
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
|
-
|
|
251
|
+
## 🌐 API Endpoint
|
|
228
252
|
|
|
229
|
-
|
|
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
|
-
|
|
255
|
+
### Step 1: Setup your API key
|
|
256
|
+
Ensure that you have your API key set up as an environment variable:
|
|
236
257
|
|
|
237
|
-
|
|
258
|
+
```
|
|
259
|
+
export VECTARA_AGENTIC_API_KEY=<YOUR-ENDPOINT-API-KEY>
|
|
260
|
+
```
|
|
238
261
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
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=ZlASMUqOFi5HTDFaRUEB3Egf_nUuUtr1X-TjPkZceLc,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=7DgzU_hZIODrzuEfP8HP7l2dO9zEt8BObhO2tCTijow,3819
|
|
14
|
+
vectara_agentic-0.1.16.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
15
|
+
vectara_agentic-0.1.16.dist-info/METADATA,sha256=QYMmXzZBZwLvgr9rcx4dt0aE-upuJ3mqlJi7v5vt0T0,13595
|
|
16
|
+
vectara_agentic-0.1.16.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
|
17
|
+
vectara_agentic-0.1.16.dist-info/top_level.txt,sha256=Y7TQTFdOYGYodQRltUGRieZKIYuzeZj2kHqAUpfCUfg,22
|
|
18
|
+
vectara_agentic-0.1.16.dist-info/RECORD,,
|