vectara-agentic 0.1.24__py3-none-any.whl → 0.1.25__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 +7 -0
- vectara_agentic/_prompts.py +3 -2
- vectara_agentic/_version.py +1 -1
- vectara_agentic/agent.py +107 -28
- vectara_agentic/agent_config.py +2 -2
- vectara_agentic/tools.py +266 -113
- vectara_agentic/tools_catalog.py +8 -1
- vectara_agentic/types.py +10 -0
- vectara_agentic/utils.py +4 -0
- {vectara_agentic-0.1.24.dist-info → vectara_agentic-0.1.25.dist-info}/METADATA +100 -31
- vectara_agentic-0.1.25.dist-info/RECORD +21 -0
- vectara_agentic-0.1.24.dist-info/RECORD +0 -21
- {vectara_agentic-0.1.24.dist-info → vectara_agentic-0.1.25.dist-info}/LICENSE +0 -0
- {vectara_agentic-0.1.24.dist-info → vectara_agentic-0.1.25.dist-info}/WHEEL +0 -0
- {vectara_agentic-0.1.24.dist-info → vectara_agentic-0.1.25.dist-info}/top_level.txt +0 -0
vectara_agentic/__init__.py
CHANGED
|
@@ -7,3 +7,10 @@ from .tools import VectaraToolFactory, VectaraTool
|
|
|
7
7
|
|
|
8
8
|
# Define the __all__ variable for wildcard imports
|
|
9
9
|
__all__ = ['Agent', 'VectaraToolFactory', 'VectaraTool']
|
|
10
|
+
|
|
11
|
+
# Ensure package version is available
|
|
12
|
+
try:
|
|
13
|
+
import importlib.metadata
|
|
14
|
+
__version__ = importlib.metadata.version("vectara_agentic")
|
|
15
|
+
except Exception:
|
|
16
|
+
__version__ = "0.0.0" # fallback if not installed
|
vectara_agentic/_prompts.py
CHANGED
|
@@ -5,6 +5,7 @@ This file contains the prompt templates for the different types of agents.
|
|
|
5
5
|
# General (shared) instructions
|
|
6
6
|
GENERAL_INSTRUCTIONS = """
|
|
7
7
|
- Use tools as your main source of information, do not respond without using a tool. Do not respond based on pre-trained knowledge.
|
|
8
|
+
- Always call the 'get_current_date' tool to ensure you know the exact date when a user asks a question.
|
|
8
9
|
- When using a tool with arguments, simplify the query as much as possible if you use the tool with arguments.
|
|
9
10
|
For example, if the original query is "revenue for apple in 2021", you can use the tool with a query "revenue" with arguments year=2021 and company=apple.
|
|
10
11
|
- If a tool responds with "I do not have enough information", try one of the following:
|
|
@@ -43,7 +44,7 @@ GENERAL_PROMPT_TEMPLATE = """
|
|
|
43
44
|
You are a helpful chatbot in conversation with a user, with expertise in {chat_topic}.
|
|
44
45
|
|
|
45
46
|
## Date
|
|
46
|
-
|
|
47
|
+
Your birth date is {today}.
|
|
47
48
|
|
|
48
49
|
## INSTRUCTIONS:
|
|
49
50
|
IMPORTANT - FOLLOW THESE INSTRUCTIONS CAREFULLY:
|
|
@@ -63,7 +64,7 @@ You are designed to help with a variety of tasks, from answering questions to pr
|
|
|
63
64
|
You have expertise in {chat_topic}.
|
|
64
65
|
|
|
65
66
|
## Date
|
|
66
|
-
|
|
67
|
+
Your birth date is {today}.
|
|
67
68
|
|
|
68
69
|
## Tools
|
|
69
70
|
You have access to a wide variety of tools.
|
vectara_agentic/_version.py
CHANGED
vectara_agentic/agent.py
CHANGED
|
@@ -8,6 +8,7 @@ import time
|
|
|
8
8
|
import json
|
|
9
9
|
import logging
|
|
10
10
|
import traceback
|
|
11
|
+
import asyncio
|
|
11
12
|
|
|
12
13
|
import dill
|
|
13
14
|
from dotenv import load_dotenv
|
|
@@ -25,12 +26,13 @@ from llama_index.core.callbacks.base_handler import BaseCallbackHandler
|
|
|
25
26
|
from llama_index.agent.openai import OpenAIAgent
|
|
26
27
|
from llama_index.core.memory import ChatMemoryBuffer
|
|
27
28
|
|
|
28
|
-
from .types import AgentType, AgentStatusType, LLMRole, ToolType
|
|
29
|
+
from .types import AgentType, AgentStatusType, LLMRole, ToolType, AgentResponse, AgentStreamingResponse
|
|
29
30
|
from .utils import get_llm, get_tokenizer_for_model
|
|
30
31
|
from ._prompts import REACT_PROMPT_TEMPLATE, GENERAL_PROMPT_TEMPLATE, GENERAL_INSTRUCTIONS
|
|
31
32
|
from ._callback import AgentCallbackHandler
|
|
32
33
|
from ._observability import setup_observer, eval_fcs
|
|
33
|
-
from .tools import VectaraToolFactory, VectaraTool
|
|
34
|
+
from .tools import VectaraToolFactory, VectaraTool, ToolsFactory
|
|
35
|
+
from .tools_catalog import get_current_date
|
|
34
36
|
from .agent_config import AgentConfig
|
|
35
37
|
|
|
36
38
|
logger = logging.getLogger("opentelemetry.exporter.otlp.proto.http.trace_exporter")
|
|
@@ -92,6 +94,7 @@ class Agent:
|
|
|
92
94
|
verbose: bool = True,
|
|
93
95
|
update_func: Optional[Callable[[AgentStatusType, str], None]] = None,
|
|
94
96
|
agent_progress_callback: Optional[Callable[[AgentStatusType, str], None]] = None,
|
|
97
|
+
query_logging_callback: Optional[Callable[[str, str], None]] = None,
|
|
95
98
|
agent_config: Optional[AgentConfig] = None,
|
|
96
99
|
) -> None:
|
|
97
100
|
"""
|
|
@@ -105,16 +108,18 @@ class Agent:
|
|
|
105
108
|
verbose (bool, optional): Whether the agent should print its steps. Defaults to True.
|
|
106
109
|
agent_progress_callback (Callable): A callback function the code calls on any agent updates.
|
|
107
110
|
update_func (Callable): old name for agent_progress_callback. Will be deprecated in future.
|
|
111
|
+
query_logging_callback (Callable): A callback function the code calls upon completion of a query
|
|
108
112
|
agent_config (AgentConfig, optional): The configuration of the agent.
|
|
109
113
|
Defaults to AgentConfig(), which reads from environment variables.
|
|
110
114
|
"""
|
|
111
115
|
self.agent_config = agent_config or AgentConfig()
|
|
112
116
|
self.agent_type = self.agent_config.agent_type
|
|
113
|
-
self.tools = tools
|
|
117
|
+
self.tools = tools + [ToolsFactory().create_tool(get_current_date)]
|
|
114
118
|
self.llm = get_llm(LLMRole.MAIN, config=self.agent_config)
|
|
115
119
|
self._custom_instructions = custom_instructions
|
|
116
120
|
self._topic = topic
|
|
117
121
|
self.agent_progress_callback = agent_progress_callback if agent_progress_callback else update_func
|
|
122
|
+
self.query_logging_callback = query_logging_callback
|
|
118
123
|
|
|
119
124
|
main_tok = get_tokenizer_for_model(role=LLMRole.MAIN)
|
|
120
125
|
self.main_token_counter = TokenCountingHandler(tokenizer=main_tok) if main_tok else None
|
|
@@ -134,7 +139,7 @@ class Agent:
|
|
|
134
139
|
if self.agent_type == AgentType.REACT:
|
|
135
140
|
prompt = _get_prompt(REACT_PROMPT_TEMPLATE, topic, custom_instructions)
|
|
136
141
|
self.agent = ReActAgent.from_tools(
|
|
137
|
-
tools=tools,
|
|
142
|
+
tools=self.tools,
|
|
138
143
|
llm=self.llm,
|
|
139
144
|
memory=self.memory,
|
|
140
145
|
verbose=verbose,
|
|
@@ -145,7 +150,7 @@ class Agent:
|
|
|
145
150
|
elif self.agent_type == AgentType.OPENAI:
|
|
146
151
|
prompt = _get_prompt(GENERAL_PROMPT_TEMPLATE, topic, custom_instructions)
|
|
147
152
|
self.agent = OpenAIAgent.from_tools(
|
|
148
|
-
tools=tools,
|
|
153
|
+
tools=self.tools,
|
|
149
154
|
llm=self.llm,
|
|
150
155
|
memory=self.memory,
|
|
151
156
|
verbose=verbose,
|
|
@@ -154,23 +159,24 @@ class Agent:
|
|
|
154
159
|
system_prompt=prompt,
|
|
155
160
|
)
|
|
156
161
|
elif self.agent_type == AgentType.LLMCOMPILER:
|
|
157
|
-
|
|
158
|
-
tools=tools,
|
|
162
|
+
agent_worker = LLMCompilerAgentWorker.from_tools(
|
|
163
|
+
tools=self.tools,
|
|
159
164
|
llm=self.llm,
|
|
160
165
|
verbose=verbose,
|
|
161
166
|
callable_manager=callback_manager,
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
_get_llm_compiler_prompt(
|
|
167
|
+
)
|
|
168
|
+
agent_worker.system_prompt = _get_prompt(
|
|
169
|
+
_get_llm_compiler_prompt(agent_worker.system_prompt, topic, custom_instructions),
|
|
165
170
|
topic, custom_instructions
|
|
166
171
|
)
|
|
167
|
-
|
|
168
|
-
_get_llm_compiler_prompt(
|
|
172
|
+
agent_worker.system_prompt_replan = _get_prompt(
|
|
173
|
+
_get_llm_compiler_prompt(agent_worker.system_prompt_replan, topic, custom_instructions),
|
|
169
174
|
topic, custom_instructions
|
|
170
175
|
)
|
|
176
|
+
self.agent = agent_worker.as_agent()
|
|
171
177
|
elif self.agent_type == AgentType.LATS:
|
|
172
178
|
agent_worker = LATSAgentWorker.from_tools(
|
|
173
|
-
tools=tools,
|
|
179
|
+
tools=self.tools,
|
|
174
180
|
llm=self.llm,
|
|
175
181
|
num_expansions=3,
|
|
176
182
|
max_rollouts=-1,
|
|
@@ -255,6 +261,7 @@ class Agent:
|
|
|
255
261
|
verbose: bool = True,
|
|
256
262
|
update_func: Optional[Callable[[AgentStatusType, str], None]] = None,
|
|
257
263
|
agent_progress_callback: Optional[Callable[[AgentStatusType, str], None]] = None,
|
|
264
|
+
query_logging_callback: Optional[Callable[[str, str], None]] = None,
|
|
258
265
|
agent_config: AgentConfig = AgentConfig(),
|
|
259
266
|
) -> "Agent":
|
|
260
267
|
"""
|
|
@@ -268,6 +275,7 @@ class Agent:
|
|
|
268
275
|
verbose (bool, optional): Whether the agent should print its steps. Defaults to True.
|
|
269
276
|
agent_progress_callback (Callable): A callback function the code calls on any agent updates.
|
|
270
277
|
update_func (Callable): old name for agent_progress_callback. Will be deprecated in future.
|
|
278
|
+
query_logging_callback (Callable): A callback function the code calls upon completion of a query
|
|
271
279
|
agent_config (AgentConfig, optional): The configuration of the agent.
|
|
272
280
|
|
|
273
281
|
Returns:
|
|
@@ -276,6 +284,7 @@ class Agent:
|
|
|
276
284
|
return cls(
|
|
277
285
|
tools=tools, topic=topic, custom_instructions=custom_instructions,
|
|
278
286
|
verbose=verbose, agent_progress_callback=agent_progress_callback,
|
|
287
|
+
query_logging_callback=query_logging_callback,
|
|
279
288
|
update_func=update_func, agent_config=agent_config
|
|
280
289
|
)
|
|
281
290
|
|
|
@@ -289,6 +298,7 @@ class Agent:
|
|
|
289
298
|
vectara_corpus_id: str = str(os.environ.get("VECTARA_CORPUS_ID", "")),
|
|
290
299
|
vectara_api_key: str = str(os.environ.get("VECTARA_API_KEY", "")),
|
|
291
300
|
agent_progress_callback: Optional[Callable[[AgentStatusType, str], None]] = None,
|
|
301
|
+
query_logging_callback: Optional[Callable[[str, str], None]] = None,
|
|
292
302
|
verbose: bool = False,
|
|
293
303
|
vectara_filter_fields: list[dict] = [],
|
|
294
304
|
vectara_lambda_val: float = 0.005,
|
|
@@ -308,6 +318,7 @@ class Agent:
|
|
|
308
318
|
vectara_corpus_id (str): The Vectara corpus ID (or comma separated list of IDs).
|
|
309
319
|
vectara_api_key (str): The Vectara API key.
|
|
310
320
|
agent_progress_callback (Callable): A callback function the code calls on any agent updates.
|
|
321
|
+
query_logging_callback (Callable): A callback function the code calls upon completion of a query
|
|
311
322
|
data_description (str): The description of the data.
|
|
312
323
|
assistant_specialty (str): The specialty of the assistant.
|
|
313
324
|
verbose (bool, optional): Whether to print verbose output.
|
|
@@ -367,6 +378,7 @@ class Agent:
|
|
|
367
378
|
custom_instructions=assistant_instructions,
|
|
368
379
|
verbose=verbose,
|
|
369
380
|
agent_progress_callback=agent_progress_callback,
|
|
381
|
+
query_logging_callback=query_logging_callback,
|
|
370
382
|
)
|
|
371
383
|
|
|
372
384
|
def report(self) -> None:
|
|
@@ -400,12 +412,32 @@ class Agent:
|
|
|
400
412
|
"tool token count": self.tool_token_counter.total_llm_token_count if self.tool_token_counter else -1,
|
|
401
413
|
}
|
|
402
414
|
|
|
415
|
+
async def _aformat_for_lats(self, prompt, agent_response):
|
|
416
|
+
llm_prompt = f"""
|
|
417
|
+
Given the question '{prompt}', and agent response '{agent_response.response}',
|
|
418
|
+
Please provide a well formatted final response to the query.
|
|
419
|
+
final response:
|
|
420
|
+
"""
|
|
421
|
+
agent_response.response = str(self.llm.acomplete(llm_prompt))
|
|
422
|
+
|
|
423
|
+
def chat(self, prompt: str) -> AgentResponse: # type: ignore
|
|
424
|
+
"""
|
|
425
|
+
Interact with the agent using a chat prompt.
|
|
426
|
+
|
|
427
|
+
Args:
|
|
428
|
+
prompt (str): The chat prompt.
|
|
429
|
+
|
|
430
|
+
Returns:
|
|
431
|
+
AgentResponse: The response from the agent.
|
|
432
|
+
"""
|
|
433
|
+
return asyncio.run(self.achat(prompt))
|
|
434
|
+
|
|
403
435
|
@retry(
|
|
404
436
|
retry_on_exception=_retry_if_exception,
|
|
405
437
|
stop_max_attempt_number=3,
|
|
406
438
|
wait_fixed=2000,
|
|
407
439
|
)
|
|
408
|
-
def
|
|
440
|
+
async def achat(self, prompt: str) -> AgentResponse: # type: ignore
|
|
409
441
|
"""
|
|
410
442
|
Interact with the agent using a chat prompt.
|
|
411
443
|
|
|
@@ -413,32 +445,79 @@ class Agent:
|
|
|
413
445
|
prompt (str): The chat prompt.
|
|
414
446
|
|
|
415
447
|
Returns:
|
|
416
|
-
|
|
448
|
+
AgentResponse: The response from the agent.
|
|
417
449
|
"""
|
|
418
450
|
|
|
419
451
|
try:
|
|
420
452
|
st = time.time()
|
|
421
|
-
agent_response = self.agent.
|
|
453
|
+
agent_response = await self.agent.achat(prompt)
|
|
422
454
|
if self.agent_type == AgentType.LATS:
|
|
423
|
-
prompt
|
|
424
|
-
Given the question '{prompt}', and agent response '{agent_response.response}',
|
|
425
|
-
Please provide a well formatted final response to the query.
|
|
426
|
-
final response:
|
|
427
|
-
"""
|
|
428
|
-
final_response = str(self.llm.complete(prompt))
|
|
429
|
-
else:
|
|
430
|
-
final_response = agent_response.response
|
|
431
|
-
|
|
455
|
+
await self._aformat_for_lats(prompt, agent_response)
|
|
432
456
|
if self.verbose:
|
|
433
457
|
print(f"Time taken: {time.time() - st}")
|
|
434
458
|
if self.observability_enabled:
|
|
435
459
|
eval_fcs()
|
|
436
|
-
|
|
460
|
+
if self.query_logging_callback:
|
|
461
|
+
self.query_logging_callback(prompt, agent_response.response)
|
|
462
|
+
return agent_response
|
|
437
463
|
except Exception as e:
|
|
438
|
-
return
|
|
464
|
+
return AgentResponse(
|
|
465
|
+
response = (
|
|
466
|
+
f"Vectara Agentic: encountered an exception ({e}) at ({traceback.format_exc()})"
|
|
467
|
+
", and can't respond."
|
|
468
|
+
)
|
|
469
|
+
)
|
|
439
470
|
|
|
440
|
-
#
|
|
471
|
+
def stream_chat(self, prompt: str) -> AgentStreamingResponse: # type: ignore
|
|
472
|
+
"""
|
|
473
|
+
Interact with the agent using a chat prompt with streaming.
|
|
474
|
+
Args:
|
|
475
|
+
prompt (str): The chat prompt.
|
|
476
|
+
Returns:
|
|
477
|
+
AgentStreamingResponse: The streaming response from the agent.
|
|
478
|
+
"""
|
|
479
|
+
return asyncio.run(self.astream_chat(prompt))
|
|
480
|
+
|
|
481
|
+
@retry(
|
|
482
|
+
retry_on_exception=_retry_if_exception,
|
|
483
|
+
stop_max_attempt_number=3,
|
|
484
|
+
wait_fixed=2000,
|
|
485
|
+
)
|
|
486
|
+
async def astream_chat(self, prompt: str) -> AgentStreamingResponse: # type: ignore
|
|
487
|
+
"""
|
|
488
|
+
Interact with the agent using a chat prompt asynchronously with streaming.
|
|
489
|
+
Args:
|
|
490
|
+
prompt (str): The chat prompt.
|
|
491
|
+
Returns:
|
|
492
|
+
AgentStreamingResponse: The streaming response from the agent.
|
|
493
|
+
"""
|
|
494
|
+
try:
|
|
495
|
+
agent_response = await self.agent.astream_chat(prompt)
|
|
496
|
+
original_async_response_gen = agent_response.async_response_gen
|
|
497
|
+
|
|
498
|
+
# Wrap async_response_gen
|
|
499
|
+
async def _stream_response_wrapper():
|
|
500
|
+
async for token in original_async_response_gen():
|
|
501
|
+
yield token # Yield async token to keep streaming behavior
|
|
502
|
+
|
|
503
|
+
# After streaming completes, execute additional logic
|
|
504
|
+
if self.agent_type == AgentType.LATS:
|
|
505
|
+
await self._aformat_for_lats(prompt, agent_response)
|
|
506
|
+
if self.query_logging_callback:
|
|
507
|
+
self.query_logging_callback(prompt, agent_response.response)
|
|
508
|
+
if self.observability_enabled:
|
|
509
|
+
eval_fcs()
|
|
510
|
+
|
|
511
|
+
agent_response.async_response_gen = _stream_response_wrapper # Override method
|
|
512
|
+
return agent_response
|
|
513
|
+
except Exception as e:
|
|
514
|
+
raise ValueError(
|
|
515
|
+
f"Vectara Agentic: encountered an exception ({e}) at ({traceback.format_exc()}), and can't respond."
|
|
516
|
+
) from e
|
|
441
517
|
|
|
518
|
+
#
|
|
519
|
+
# Serialization methods
|
|
520
|
+
#
|
|
442
521
|
def dumps(self) -> str:
|
|
443
522
|
"""Serialize the Agent instance to a JSON string."""
|
|
444
523
|
return json.dumps(self.to_dict())
|
vectara_agentic/agent_config.py
CHANGED
|
@@ -31,7 +31,7 @@ class AgentConfig:
|
|
|
31
31
|
)
|
|
32
32
|
|
|
33
33
|
main_llm_model_name: str = field(
|
|
34
|
-
default_factory=lambda: os.getenv("
|
|
34
|
+
default_factory=lambda: os.getenv("VECTARA_AGENTIC_MAIN_MODEL_NAME", "")
|
|
35
35
|
)
|
|
36
36
|
|
|
37
37
|
# Tool LLM provider & model name
|
|
@@ -41,7 +41,7 @@ class AgentConfig:
|
|
|
41
41
|
)
|
|
42
42
|
)
|
|
43
43
|
tool_llm_model_name: str = field(
|
|
44
|
-
default_factory=lambda: os.getenv("
|
|
44
|
+
default_factory=lambda: os.getenv("VECTARA_AGENTIC_TOOL_MODEL_NAME", "")
|
|
45
45
|
)
|
|
46
46
|
|
|
47
47
|
# Observer
|
vectara_agentic/tools.py
CHANGED
|
@@ -126,6 +126,122 @@ class VectaraTool(FunctionTool):
|
|
|
126
126
|
break
|
|
127
127
|
return is_equal
|
|
128
128
|
|
|
129
|
+
def _build_filter_string(kwargs: Dict[str, Any], tool_args_type: Dict[str, str], fixed_filter: str) -> str:
|
|
130
|
+
"""
|
|
131
|
+
Build filter string for Vectara from kwargs
|
|
132
|
+
"""
|
|
133
|
+
filter_parts = []
|
|
134
|
+
comparison_operators = [">=", "<=", "!=", ">", "<", "="]
|
|
135
|
+
numeric_only_ops = {">", "<", ">=", "<="}
|
|
136
|
+
|
|
137
|
+
for key, value in kwargs.items():
|
|
138
|
+
if value is None or value == "":
|
|
139
|
+
continue
|
|
140
|
+
|
|
141
|
+
# Determine the prefix for the key. Valid values are "doc" or "part"
|
|
142
|
+
# default to 'doc' if not specified
|
|
143
|
+
prefix = tool_args_type.get(key, "doc")
|
|
144
|
+
|
|
145
|
+
if prefix not in ["doc", "part"]:
|
|
146
|
+
raise ValueError(
|
|
147
|
+
f'Unrecognized prefix {prefix}. Please make sure to use either "doc" or "part" for the prefix.'
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
if value is PydanticUndefined:
|
|
151
|
+
raise ValueError(
|
|
152
|
+
f"Value of argument {key} is undefined, and this is invalid. "
|
|
153
|
+
"Please form proper arguments and try again."
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
# value of the argument
|
|
157
|
+
val_str = str(value).strip()
|
|
158
|
+
|
|
159
|
+
# Special handling for range operator
|
|
160
|
+
if val_str.startswith(("[", "(")) and val_str.endswith(("]", ")")):
|
|
161
|
+
# Extract the boundary types
|
|
162
|
+
start_inclusive = val_str.startswith("[")
|
|
163
|
+
end_inclusive = val_str.endswith("]")
|
|
164
|
+
|
|
165
|
+
# Remove the boundaries and strip whitespace
|
|
166
|
+
val_str = val_str[1:-1].strip()
|
|
167
|
+
|
|
168
|
+
if "," in val_str:
|
|
169
|
+
val_str = val_str.split(",")
|
|
170
|
+
if len(val_str) != 2:
|
|
171
|
+
raise ValueError(
|
|
172
|
+
f"Range operator requires two values for {key}: {value}"
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
# Validate both bounds as numeric or empty (for unbounded ranges)
|
|
176
|
+
start_val, end_val = val_str[0].strip(), val_str[1].strip()
|
|
177
|
+
if start_val and not (start_val.isdigit() or is_float(start_val)):
|
|
178
|
+
raise ValueError(
|
|
179
|
+
f"Range operator requires numeric operands for {key}: {value}"
|
|
180
|
+
)
|
|
181
|
+
if end_val and not (end_val.isdigit() or is_float(end_val)):
|
|
182
|
+
raise ValueError(
|
|
183
|
+
f"Range operator requires numeric operands for {key}: {value}"
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
# Build the SQL condition
|
|
187
|
+
range_conditions = []
|
|
188
|
+
if start_val:
|
|
189
|
+
operator = ">=" if start_inclusive else ">"
|
|
190
|
+
range_conditions.append(f"{prefix}.{key} {operator} {start_val}")
|
|
191
|
+
if end_val:
|
|
192
|
+
operator = "<=" if end_inclusive else "<"
|
|
193
|
+
range_conditions.append(f"{prefix}.{key} {operator} {end_val}")
|
|
194
|
+
|
|
195
|
+
# Join the range conditions with AND
|
|
196
|
+
filter_parts.append('( ' + " AND ".join(range_conditions) + ' )')
|
|
197
|
+
continue
|
|
198
|
+
|
|
199
|
+
raise ValueError(
|
|
200
|
+
f"Range operator requires two values for {key}: {value}"
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
# Check if value contains a known comparison operator at the start
|
|
204
|
+
matched_operator = None
|
|
205
|
+
for op in comparison_operators:
|
|
206
|
+
if val_str.startswith(op):
|
|
207
|
+
matched_operator = op
|
|
208
|
+
break
|
|
209
|
+
|
|
210
|
+
# Break down operator from value
|
|
211
|
+
# e.g. val_str = ">2022" --> operator = ">", rhs = "2022"
|
|
212
|
+
if matched_operator:
|
|
213
|
+
rhs = val_str[len(matched_operator):].strip()
|
|
214
|
+
|
|
215
|
+
if matched_operator in numeric_only_ops:
|
|
216
|
+
# Must be numeric
|
|
217
|
+
if not (rhs.isdigit() or is_float(rhs)):
|
|
218
|
+
raise ValueError(
|
|
219
|
+
f"Operator {matched_operator} requires a numeric operand for {key}: {val_str}"
|
|
220
|
+
)
|
|
221
|
+
filter_parts.append(f"{prefix}.{key}{matched_operator}{rhs}")
|
|
222
|
+
else:
|
|
223
|
+
# = and != operators can be numeric or string
|
|
224
|
+
if rhs.isdigit() or is_float(rhs):
|
|
225
|
+
filter_parts.append(f"{prefix}.{key}{matched_operator}{rhs}")
|
|
226
|
+
elif rhs.lower() in ["true", "false"]:
|
|
227
|
+
filter_parts.append(f"{prefix}.{key}{matched_operator}{rhs.lower()}")
|
|
228
|
+
else:
|
|
229
|
+
# For string operands, wrap them in quotes
|
|
230
|
+
filter_parts.append(f"{prefix}.{key}{matched_operator}'{rhs}'")
|
|
231
|
+
else:
|
|
232
|
+
if val_str.isdigit() or is_float(val_str):
|
|
233
|
+
filter_parts.append(f"{prefix}.{key}={val_str}")
|
|
234
|
+
elif val_str.lower() in ["true", "false"]:
|
|
235
|
+
# This is to handle boolean values.
|
|
236
|
+
# This is not complete solution - the best solution would be to test if the field is boolean
|
|
237
|
+
# That can be done after we move to APIv2
|
|
238
|
+
filter_parts.append(f"{prefix}.{key}={val_str.lower()}")
|
|
239
|
+
else:
|
|
240
|
+
filter_parts.append(f"{prefix}.{key}='{val_str}'")
|
|
241
|
+
|
|
242
|
+
filter_str = " AND ".join(filter_parts)
|
|
243
|
+
return f"({fixed_filter}) AND ({filter_str})" if fixed_filter else filter_str
|
|
244
|
+
|
|
129
245
|
class VectaraToolFactory:
|
|
130
246
|
"""
|
|
131
247
|
A factory class for creating Vectara RAG tools.
|
|
@@ -149,13 +265,159 @@ class VectaraToolFactory:
|
|
|
149
265
|
self.vectara_api_key = vectara_api_key
|
|
150
266
|
self.num_corpora = len(vectara_corpus_id.split(","))
|
|
151
267
|
|
|
268
|
+
def create_search_tool(
|
|
269
|
+
self,
|
|
270
|
+
tool_name: str,
|
|
271
|
+
tool_description: str,
|
|
272
|
+
tool_args_schema: type[BaseModel],
|
|
273
|
+
tool_args_type: Dict[str, str] = {},
|
|
274
|
+
fixed_filter: str = "",
|
|
275
|
+
lambda_val: float = 0.005,
|
|
276
|
+
reranker: str = "mmr",
|
|
277
|
+
rerank_k: int = 50,
|
|
278
|
+
mmr_diversity_bias: float = 0.2,
|
|
279
|
+
udf_expression: str = None,
|
|
280
|
+
rerank_chain: List[Dict] = None,
|
|
281
|
+
verbose: bool = False,
|
|
282
|
+
) -> VectaraTool:
|
|
283
|
+
"""
|
|
284
|
+
Creates a Vectara search/retrieval tool
|
|
285
|
+
|
|
286
|
+
Args:
|
|
287
|
+
tool_name (str): The name of the tool.
|
|
288
|
+
tool_description (str): The description of the tool.
|
|
289
|
+
tool_args_schema (BaseModel): The schema for the tool arguments.
|
|
290
|
+
tool_args_type (Dict[str, str], optional): The type of each argument (doc or part).
|
|
291
|
+
fixed_filter (str, optional): A fixed Vectara filter condition to apply to all queries.
|
|
292
|
+
lambda_val (float, optional): Lambda value for the Vectara query.
|
|
293
|
+
reranker (str, optional): The reranker mode.
|
|
294
|
+
rerank_k (int, optional): Number of top-k documents for reranking.
|
|
295
|
+
mmr_diversity_bias (float, optional): MMR diversity bias.
|
|
296
|
+
udf_expression (str, optional): the user defined expression for reranking results.
|
|
297
|
+
rerank_chain (List[Dict], optional): A list of rerankers to be applied sequentially.
|
|
298
|
+
Each dictionary should specify the "type" of reranker (mmr, slingshot, udf)
|
|
299
|
+
and any other parameters (e.g. "limit" or "cutoff" for any type,
|
|
300
|
+
"diversity_bias" for mmr, and "user_function" for udf).
|
|
301
|
+
If using slingshot/multilingual_reranker_v1, it must be first in the list.
|
|
302
|
+
verbose (bool, optional): Whether to print verbose output.
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
VectaraTool: A VectaraTool object.
|
|
306
|
+
"""
|
|
307
|
+
|
|
308
|
+
vectara = VectaraIndex(
|
|
309
|
+
vectara_api_key=self.vectara_api_key,
|
|
310
|
+
vectara_customer_id=self.vectara_customer_id,
|
|
311
|
+
vectara_corpus_id=self.vectara_corpus_id,
|
|
312
|
+
x_source_str="vectara-agentic",
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
# Dynamically generate the search function
|
|
316
|
+
def search_function(*args, **kwargs) -> ToolOutput:
|
|
317
|
+
"""
|
|
318
|
+
Dynamically generated function for semantic search Vectara.
|
|
319
|
+
"""
|
|
320
|
+
# Convert args to kwargs using the function signature
|
|
321
|
+
sig = inspect.signature(search_function)
|
|
322
|
+
bound_args = sig.bind_partial(*args, **kwargs)
|
|
323
|
+
bound_args.apply_defaults()
|
|
324
|
+
kwargs = bound_args.arguments
|
|
325
|
+
|
|
326
|
+
query = kwargs.pop("query")
|
|
327
|
+
top_k = kwargs.pop("top_k", 10)
|
|
328
|
+
try:
|
|
329
|
+
filter_string = _build_filter_string(kwargs, tool_args_type, fixed_filter)
|
|
330
|
+
except ValueError as e:
|
|
331
|
+
return ToolOutput(
|
|
332
|
+
tool_name=search_function.__name__,
|
|
333
|
+
content=str(e),
|
|
334
|
+
raw_input={"args": args, "kwargs": kwargs},
|
|
335
|
+
raw_output={"response": str(e)},
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
vectara_retriever = vectara.as_retriever(
|
|
339
|
+
summary_enabled=False,
|
|
340
|
+
similarity_top_k=top_k,
|
|
341
|
+
reranker=reranker,
|
|
342
|
+
rerank_k=rerank_k if rerank_k * self.num_corpora <= 100 else int(100 / self.num_corpora),
|
|
343
|
+
mmr_diversity_bias=mmr_diversity_bias,
|
|
344
|
+
udf_expression=udf_expression,
|
|
345
|
+
rerank_chain=rerank_chain,
|
|
346
|
+
lambda_val=lambda_val,
|
|
347
|
+
filter=filter_string,
|
|
348
|
+
x_source_str="vectara-agentic",
|
|
349
|
+
verbose=verbose,
|
|
350
|
+
)
|
|
351
|
+
response = vectara_retriever.retrieve(query)
|
|
352
|
+
|
|
353
|
+
if len(response) == 0:
|
|
354
|
+
msg = "Vectara Tool failed to retreive any results for the query."
|
|
355
|
+
return ToolOutput(
|
|
356
|
+
tool_name=search_function.__name__,
|
|
357
|
+
content=msg,
|
|
358
|
+
raw_input={"args": args, "kwargs": kwargs},
|
|
359
|
+
raw_output={"response": msg},
|
|
360
|
+
)
|
|
361
|
+
tool_output = "Matching documents:\n"
|
|
362
|
+
unique_ids = set()
|
|
363
|
+
for doc in response:
|
|
364
|
+
if doc.id_ in unique_ids:
|
|
365
|
+
continue
|
|
366
|
+
unique_ids.add(doc.id_)
|
|
367
|
+
tool_output += f"document '{doc.id_}' metadata: {doc.metadata}\n"
|
|
368
|
+
out = ToolOutput(
|
|
369
|
+
tool_name=search_function.__name__,
|
|
370
|
+
content=tool_output,
|
|
371
|
+
raw_input={"args": args, "kwargs": kwargs},
|
|
372
|
+
raw_output=response,
|
|
373
|
+
)
|
|
374
|
+
return out
|
|
375
|
+
|
|
376
|
+
fields = tool_args_schema.model_fields
|
|
377
|
+
params = [
|
|
378
|
+
inspect.Parameter(
|
|
379
|
+
name=field_name,
|
|
380
|
+
kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
381
|
+
default=field_info.default,
|
|
382
|
+
annotation=field_info,
|
|
383
|
+
)
|
|
384
|
+
for field_name, field_info in fields.items()
|
|
385
|
+
]
|
|
386
|
+
|
|
387
|
+
# Create a new signature using the extracted parameters
|
|
388
|
+
sig = inspect.Signature(params)
|
|
389
|
+
search_function.__signature__ = sig
|
|
390
|
+
search_function.__annotations__["return"] = dict[str, Any]
|
|
391
|
+
search_function.__name__ = "_" + re.sub(r"[^A-Za-z0-9_]", "_", tool_name)
|
|
392
|
+
|
|
393
|
+
# Create the tool function signature string
|
|
394
|
+
fields = []
|
|
395
|
+
for name, field in tool_args_schema.__fields__.items():
|
|
396
|
+
annotation = field.annotation
|
|
397
|
+
type_name = annotation.__name__ if hasattr(annotation, '__name__') else str(annotation)
|
|
398
|
+
fields.append(f"{name}: {type_name}")
|
|
399
|
+
args_str = ", ".join(fields)
|
|
400
|
+
function_str = f"{tool_name}({args_str}) -> str"
|
|
401
|
+
|
|
402
|
+
# Create the tool
|
|
403
|
+
tool = VectaraTool.from_defaults(
|
|
404
|
+
fn=search_function,
|
|
405
|
+
name=tool_name,
|
|
406
|
+
description=function_str + ". " + tool_description,
|
|
407
|
+
fn_schema=tool_args_schema,
|
|
408
|
+
tool_type=ToolType.QUERY,
|
|
409
|
+
)
|
|
410
|
+
return tool
|
|
411
|
+
|
|
152
412
|
def create_rag_tool(
|
|
153
413
|
self,
|
|
154
414
|
tool_name: str,
|
|
155
415
|
tool_description: str,
|
|
156
416
|
tool_args_schema: type[BaseModel],
|
|
157
417
|
tool_args_type: Dict[str, str] = {},
|
|
418
|
+
fixed_filter: str = "",
|
|
158
419
|
vectara_summarizer: str = "vectara-summary-ext-24-05-sml",
|
|
420
|
+
vectara_prompt_text: str = None,
|
|
159
421
|
summary_num_results: int = 5,
|
|
160
422
|
summary_response_lang: str = "eng",
|
|
161
423
|
n_sentences_before: int = 2,
|
|
@@ -178,7 +440,9 @@ class VectaraToolFactory:
|
|
|
178
440
|
tool_description (str): The description of the tool.
|
|
179
441
|
tool_args_schema (BaseModel): The schema for the tool arguments.
|
|
180
442
|
tool_args_type (Dict[str, str], optional): The type of each argument (doc or part).
|
|
443
|
+
fixed_filter (str, optional): A fixed Vectara filter condition to apply to all queries.
|
|
181
444
|
vectara_summarizer (str, optional): The Vectara summarizer to use.
|
|
445
|
+
vectara_prompt_text (str, optional): The prompt text for the Vectara summarizer.
|
|
182
446
|
summary_num_results (int, optional): The number of summary results.
|
|
183
447
|
summary_response_lang (str, optional): The response language for the summary.
|
|
184
448
|
n_sentences_before (int, optional): Number of sentences before the summary.
|
|
@@ -210,118 +474,6 @@ class VectaraToolFactory:
|
|
|
210
474
|
x_source_str="vectara-agentic",
|
|
211
475
|
)
|
|
212
476
|
|
|
213
|
-
def _build_filter_string(kwargs: Dict[str, Any], tool_args_type: Dict[str, str]) -> str:
|
|
214
|
-
filter_parts = []
|
|
215
|
-
comparison_operators = [">=", "<=", "!=", ">", "<", "="]
|
|
216
|
-
numeric_only_ops = {">", "<", ">=", "<="}
|
|
217
|
-
|
|
218
|
-
for key, value in kwargs.items():
|
|
219
|
-
if value is None or value == "":
|
|
220
|
-
continue
|
|
221
|
-
|
|
222
|
-
# Determine the prefix for the key. Valid values are "doc" or "part"
|
|
223
|
-
# default to 'doc' if not specified
|
|
224
|
-
prefix = tool_args_type.get(key, "doc")
|
|
225
|
-
|
|
226
|
-
if prefix not in ["doc", "part"]:
|
|
227
|
-
raise ValueError(
|
|
228
|
-
f'Unrecognized prefix {prefix}. Please make sure to use either "doc" or "part" for the prefix.'
|
|
229
|
-
)
|
|
230
|
-
|
|
231
|
-
if value is PydanticUndefined:
|
|
232
|
-
raise ValueError(
|
|
233
|
-
f"Value of argument {key} is undefined, and this is invalid. "
|
|
234
|
-
"Please form proper arguments and try again."
|
|
235
|
-
)
|
|
236
|
-
|
|
237
|
-
# value of the arrgument
|
|
238
|
-
val_str = str(value).strip()
|
|
239
|
-
|
|
240
|
-
# Special handling for range operator
|
|
241
|
-
if val_str.startswith(("[", "(")) and val_str.endswith(("]", ")")):
|
|
242
|
-
# Extract the boundary types
|
|
243
|
-
start_inclusive = val_str.startswith("[")
|
|
244
|
-
end_inclusive = val_str.endswith("]")
|
|
245
|
-
|
|
246
|
-
# Remove the boundaries and strip whitespace
|
|
247
|
-
val_str = val_str[1:-1].strip()
|
|
248
|
-
|
|
249
|
-
if "," in val_str:
|
|
250
|
-
val_str = val_str.split(",")
|
|
251
|
-
if len(val_str) != 2:
|
|
252
|
-
raise ValueError(
|
|
253
|
-
f"Range operator requires two values for {key}: {value}"
|
|
254
|
-
)
|
|
255
|
-
|
|
256
|
-
# Validate both bounds as numeric or empty (for unbounded ranges)
|
|
257
|
-
start_val, end_val = val_str[0].strip(), val_str[1].strip()
|
|
258
|
-
if start_val and not (start_val.isdigit() or is_float(start_val)):
|
|
259
|
-
raise ValueError(
|
|
260
|
-
f"Range operator requires numeric operands for {key}: {value}"
|
|
261
|
-
)
|
|
262
|
-
if end_val and not (end_val.isdigit() or is_float(end_val)):
|
|
263
|
-
raise ValueError(
|
|
264
|
-
f"Range operator requires numeric operands for {key}: {value}"
|
|
265
|
-
)
|
|
266
|
-
|
|
267
|
-
# Build the SQL condition
|
|
268
|
-
range_conditions = []
|
|
269
|
-
if start_val:
|
|
270
|
-
operator = ">=" if start_inclusive else ">"
|
|
271
|
-
range_conditions.append(f"{prefix}.{key} {operator} {start_val}")
|
|
272
|
-
if end_val:
|
|
273
|
-
operator = "<=" if end_inclusive else "<"
|
|
274
|
-
range_conditions.append(f"{prefix}.{key} {operator} {end_val}")
|
|
275
|
-
|
|
276
|
-
# Join the range conditions with AND
|
|
277
|
-
filter_parts.append('( ' + " AND ".join(range_conditions) + ' )')
|
|
278
|
-
continue
|
|
279
|
-
|
|
280
|
-
raise ValueError(
|
|
281
|
-
f"Range operator requires two values for {key}: {value}"
|
|
282
|
-
)
|
|
283
|
-
|
|
284
|
-
# Check if value contains a known comparison operator at the start
|
|
285
|
-
matched_operator = None
|
|
286
|
-
for op in comparison_operators:
|
|
287
|
-
if val_str.startswith(op):
|
|
288
|
-
matched_operator = op
|
|
289
|
-
break
|
|
290
|
-
|
|
291
|
-
# Break down operator from value
|
|
292
|
-
# e.g. val_str = ">2022" --> operator = ">", rhs = "2022"
|
|
293
|
-
if matched_operator:
|
|
294
|
-
rhs = val_str[len(matched_operator):].strip()
|
|
295
|
-
|
|
296
|
-
if matched_operator in numeric_only_ops:
|
|
297
|
-
# Must be numeric
|
|
298
|
-
if not (rhs.isdigit() or is_float(rhs)):
|
|
299
|
-
raise ValueError(
|
|
300
|
-
f"Operator {matched_operator} requires a numeric operand for {key}: {val_str}"
|
|
301
|
-
)
|
|
302
|
-
filter_parts.append(f"{prefix}.{key}{matched_operator}{rhs}")
|
|
303
|
-
else:
|
|
304
|
-
# = and != operators can be numeric or string
|
|
305
|
-
if rhs.isdigit() or is_float(rhs):
|
|
306
|
-
filter_parts.append(f"{prefix}.{key}{matched_operator}{rhs}")
|
|
307
|
-
elif rhs.lower() in ["true", "false"]:
|
|
308
|
-
filter_parts.append(f"{prefix}.{key}{matched_operator}{rhs.lower()}")
|
|
309
|
-
else:
|
|
310
|
-
# For string operands, wrap them in quotes
|
|
311
|
-
filter_parts.append(f"{prefix}.{key}{matched_operator}'{rhs}'")
|
|
312
|
-
else:
|
|
313
|
-
if val_str.isdigit() or is_float(val_str):
|
|
314
|
-
filter_parts.append(f"{prefix}.{key}={val_str}")
|
|
315
|
-
elif val_str.lower() in ["true", "false"]:
|
|
316
|
-
# This is to handle boolean values.
|
|
317
|
-
# This is not complete solution - the best solution would be to test if the field is boolean
|
|
318
|
-
# That can be done after we move to APIv2
|
|
319
|
-
filter_parts.append(f"{prefix}.{key}={val_str.lower()}")
|
|
320
|
-
else:
|
|
321
|
-
filter_parts.append(f"{prefix}.{key}='{val_str}'")
|
|
322
|
-
|
|
323
|
-
return " AND ".join(filter_parts)
|
|
324
|
-
|
|
325
477
|
# Dynamically generate the RAG function
|
|
326
478
|
def rag_function(*args, **kwargs) -> ToolOutput:
|
|
327
479
|
"""
|
|
@@ -335,7 +487,7 @@ class VectaraToolFactory:
|
|
|
335
487
|
|
|
336
488
|
query = kwargs.pop("query")
|
|
337
489
|
try:
|
|
338
|
-
filter_string = _build_filter_string(kwargs, tool_args_type)
|
|
490
|
+
filter_string = _build_filter_string(kwargs, tool_args_type, fixed_filter)
|
|
339
491
|
except ValueError as e:
|
|
340
492
|
return ToolOutput(
|
|
341
493
|
tool_name=rag_function.__name__,
|
|
@@ -349,6 +501,7 @@ class VectaraToolFactory:
|
|
|
349
501
|
summary_num_results=summary_num_results,
|
|
350
502
|
summary_response_lang=summary_response_lang,
|
|
351
503
|
summary_prompt_name=vectara_summarizer,
|
|
504
|
+
prompt_text=vectara_prompt_text,
|
|
352
505
|
reranker=reranker,
|
|
353
506
|
rerank_k=rerank_k if rerank_k * self.num_corpora <= 100 else int(100 / self.num_corpora),
|
|
354
507
|
mmr_diversity_bias=mmr_diversity_bias,
|
vectara_agentic/tools_catalog.py
CHANGED
|
@@ -3,9 +3,11 @@ This module contains the tools catalog for the Vectara Agentic.
|
|
|
3
3
|
"""
|
|
4
4
|
from typing import List
|
|
5
5
|
from functools import lru_cache
|
|
6
|
-
from
|
|
6
|
+
from datetime import date
|
|
7
7
|
import requests
|
|
8
8
|
|
|
9
|
+
from pydantic import Field
|
|
10
|
+
|
|
9
11
|
from .types import LLMRole
|
|
10
12
|
from .utils import get_llm
|
|
11
13
|
|
|
@@ -19,6 +21,11 @@ get_headers = {
|
|
|
19
21
|
"Connection": "keep-alive",
|
|
20
22
|
}
|
|
21
23
|
|
|
24
|
+
def get_current_date() -> str:
|
|
25
|
+
"""
|
|
26
|
+
Returns: the current date.
|
|
27
|
+
"""
|
|
28
|
+
return date.today().strftime("%A, %B %d, %Y")
|
|
22
29
|
|
|
23
30
|
#
|
|
24
31
|
# Standard Tools
|
vectara_agentic/types.py
CHANGED
|
@@ -3,6 +3,9 @@ This module contains the types used in the Vectara Agentic.
|
|
|
3
3
|
"""
|
|
4
4
|
from enum import Enum
|
|
5
5
|
|
|
6
|
+
from llama_index.core.tools.types import ToolOutput as LI_ToolOutput
|
|
7
|
+
from llama_index.core.chat_engine.types import AgentChatResponse as LI_AgentChatResponse
|
|
8
|
+
from llama_index.core.chat_engine.types import StreamingAgentChatResponse as LI_StreamingAgentChatResponse
|
|
6
9
|
|
|
7
10
|
class AgentType(Enum):
|
|
8
11
|
"""Enumeration for different types of agents."""
|
|
@@ -29,6 +32,7 @@ class ModelProvider(Enum):
|
|
|
29
32
|
FIREWORKS = "FIREWORKS"
|
|
30
33
|
COHERE = "COHERE"
|
|
31
34
|
GEMINI = "GEMINI"
|
|
35
|
+
BEDROCK = "BEDROCK"
|
|
32
36
|
|
|
33
37
|
|
|
34
38
|
class AgentStatusType(Enum):
|
|
@@ -51,3 +55,9 @@ class ToolType(Enum):
|
|
|
51
55
|
"""Enumeration for different types of tools."""
|
|
52
56
|
QUERY = "query"
|
|
53
57
|
ACTION = "action"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# classes for Agent responses
|
|
61
|
+
ToolOutput = LI_ToolOutput
|
|
62
|
+
AgentResponse = LI_AgentChatResponse
|
|
63
|
+
AgentStreamingResponse = LI_StreamingAgentChatResponse
|
vectara_agentic/utils.py
CHANGED
|
@@ -20,6 +20,7 @@ provider_to_default_model_name = {
|
|
|
20
20
|
ModelProvider.TOGETHER: "meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
|
21
21
|
ModelProvider.GROQ: "llama-3.3-70b-versatile",
|
|
22
22
|
ModelProvider.FIREWORKS: "accounts/fireworks/models/firefunction-v2",
|
|
23
|
+
ModelProvider.BEDROCK: "anthropic.claude-3-5-sonnet-20241022-v2:0",
|
|
23
24
|
ModelProvider.COHERE: "command-r-plus",
|
|
24
25
|
ModelProvider.GEMINI: "models/gemini-1.5-flash",
|
|
25
26
|
}
|
|
@@ -105,6 +106,9 @@ def get_llm(
|
|
|
105
106
|
elif model_provider == ModelProvider.FIREWORKS:
|
|
106
107
|
from llama_index.llms.fireworks import Fireworks
|
|
107
108
|
llm = Fireworks(model=model_name, temperature=0)
|
|
109
|
+
elif model_provider == ModelProvider.BEDROCK:
|
|
110
|
+
from llama_index.llms.bedrock import Bedrock
|
|
111
|
+
llm = Bedrock(model=model_name, temperature=0)
|
|
108
112
|
elif model_provider == ModelProvider.COHERE:
|
|
109
113
|
from llama_index.llms.cohere import Cohere
|
|
110
114
|
llm = Cohere(model=model_name, temperature=0)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: vectara_agentic
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.25
|
|
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,39 +16,39 @@ 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.
|
|
19
|
+
Requires-Dist: llama-index==0.12.11
|
|
20
20
|
Requires-Dist: llama-index-indices-managed-vectara==0.3.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.
|
|
24
|
-
Requires-Dist: llama-index-llms-openai==0.3.
|
|
25
|
-
Requires-Dist: llama-index-llms-anthropic==0.6.
|
|
23
|
+
Requires-Dist: llama-index-agent-openai==0.4.3
|
|
24
|
+
Requires-Dist: llama-index-llms-openai==0.3.16
|
|
25
|
+
Requires-Dist: llama-index-llms-anthropic==0.6.4
|
|
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.
|
|
28
|
+
Requires-Dist: llama-index-llms-fireworks==0.3.1
|
|
29
29
|
Requires-Dist: llama-index-llms-cohere==0.4.0
|
|
30
|
-
Requires-Dist: llama-index-llms-gemini==0.4.
|
|
30
|
+
Requires-Dist: llama-index-llms-gemini==0.4.4
|
|
31
|
+
Requires-Dist: llama-index-llms-bedrock==0.3.3
|
|
31
32
|
Requires-Dist: llama-index-tools-yahoo-finance==0.3.0
|
|
32
33
|
Requires-Dist: llama-index-tools-arxiv==0.3.0
|
|
33
34
|
Requires-Dist: llama-index-tools-database==0.3.0
|
|
34
35
|
Requires-Dist: llama-index-tools-google==0.3.0
|
|
35
36
|
Requires-Dist: llama-index-tools-tavily_research==0.3.0
|
|
36
37
|
Requires-Dist: llama-index-tools-neo4j==0.3.0
|
|
37
|
-
Requires-Dist: llama-index-graph-stores-kuzu==0.
|
|
38
|
+
Requires-Dist: llama-index-graph-stores-kuzu==0.6.0
|
|
38
39
|
Requires-Dist: llama-index-tools-slack==0.3.0
|
|
39
40
|
Requires-Dist: llama-index-tools-exa==0.3.0
|
|
40
41
|
Requires-Dist: tavily-python==0.5.0
|
|
41
|
-
Requires-Dist: exa-py==1.
|
|
42
|
+
Requires-Dist: exa-py==1.8.5
|
|
42
43
|
Requires-Dist: yahoo-finance==1.4.0
|
|
43
|
-
Requires-Dist: openinference-instrumentation-llama-index==3.
|
|
44
|
+
Requires-Dist: openinference-instrumentation-llama-index==3.1.4
|
|
44
45
|
Requires-Dist: opentelemetry-proto==1.26.0
|
|
45
|
-
Requires-Dist: arize-phoenix==
|
|
46
|
+
Requires-Dist: arize-phoenix==7.11.0
|
|
46
47
|
Requires-Dist: arize-phoenix-otel==0.6.1
|
|
47
48
|
Requires-Dist: protobuf==4.25.5
|
|
48
49
|
Requires-Dist: tokenizers>=0.20
|
|
49
|
-
Requires-Dist: pydantic==2.
|
|
50
|
+
Requires-Dist: pydantic==2.10.3
|
|
50
51
|
Requires-Dist: retrying==1.3.4
|
|
51
|
-
Requires-Dist: pymongo==4.10.1
|
|
52
52
|
Requires-Dist: python-dotenv==1.0.1
|
|
53
53
|
Requires-Dist: tiktoken==0.8.0
|
|
54
54
|
Requires-Dist: dill>=0.3.7
|
|
@@ -87,7 +87,7 @@ Dynamic: summary
|
|
|
87
87
|
|
|
88
88
|
## ✨ Overview
|
|
89
89
|
|
|
90
|
-
`vectara-agentic` is a Python library for developing powerful AI assistants and agents using Vectara and Agentic-RAG. It leverages the LlamaIndex Agent framework
|
|
90
|
+
`vectara-agentic` is a Python library for developing powerful AI assistants and agents using Vectara and Agentic-RAG. It leverages the LlamaIndex Agent framework and provides helper functions to quickly create tools that connect to Vectara corpora.
|
|
91
91
|
|
|
92
92
|
<p align="center">
|
|
93
93
|
<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;">
|
|
@@ -96,10 +96,10 @@ Dynamic: summary
|
|
|
96
96
|
### Features
|
|
97
97
|
|
|
98
98
|
- Enables easy creation of custom AI assistants and agents.
|
|
99
|
-
- Create a Vectara RAG tool with a single line of code.
|
|
100
|
-
- Supports `ReAct`, `OpenAIAgent`, `LATS
|
|
99
|
+
- Create a Vectara RAG tool or search tool with a single line of code.
|
|
100
|
+
- Supports `ReAct`, `OpenAIAgent`, `LATS` and `LLMCompiler` agent types.
|
|
101
101
|
- Includes pre-built tools for various domains (e.g., finance, legal).
|
|
102
|
-
- Integrates with various LLM inference services like OpenAI, Anthropic, Gemini, GROQ, Together.AI, Cohere and Fireworks
|
|
102
|
+
- Integrates with various LLM inference services like OpenAI, Anthropic, Gemini, GROQ, Together.AI, Cohere, Bedrock and Fireworks
|
|
103
103
|
- Built-in support for observability with Arize Phoenix
|
|
104
104
|
|
|
105
105
|
### 📚 Example AI Assistants
|
|
@@ -109,14 +109,14 @@ Check out our example AI assistants:
|
|
|
109
109
|
- [Financial Assistant](https://huggingface.co/spaces/vectara/finance-chat)
|
|
110
110
|
- [Justice Harvard Teaching Assistant](https://huggingface.co/spaces/vectara/Justice-Harvard)
|
|
111
111
|
- [Legal Assistant](https://huggingface.co/spaces/vectara/legal-agent)
|
|
112
|
-
|
|
112
|
+
- [EV Assistant](https://huggingface.co/spaces/vectara/ev-assistant)
|
|
113
113
|
|
|
114
114
|
### Prerequisites
|
|
115
115
|
|
|
116
116
|
- [Vectara account](https://console.vectara.com/signup/?utm_source=github&utm_medium=code&utm_term=DevRel&utm_content=vectara-agentic&utm_campaign=github-code-DevRel-vectara-agentic)
|
|
117
117
|
- A Vectara corpus with an [API key](https://docs.vectara.com/docs/api-keys)
|
|
118
118
|
- [Python 3.10 or higher](https://www.python.org/downloads/)
|
|
119
|
-
- OpenAI API key (or API keys for Anthropic, TOGETHER.AI, Fireworks AI, Cohere, GEMINI or GROQ, if you choose to use them)
|
|
119
|
+
- OpenAI API key (or API keys for Anthropic, TOGETHER.AI, Fireworks AI, Bedrock, Cohere, GEMINI or GROQ, if you choose to use them)
|
|
120
120
|
|
|
121
121
|
### Installation
|
|
122
122
|
|
|
@@ -126,18 +126,25 @@ pip install vectara-agentic
|
|
|
126
126
|
|
|
127
127
|
## 🚀 Quick Start
|
|
128
128
|
|
|
129
|
-
### 1.
|
|
129
|
+
### 1. Initialize the Vectara tool factory
|
|
130
130
|
|
|
131
131
|
```python
|
|
132
132
|
import os
|
|
133
133
|
from vectara_agentic.tools import VectaraToolFactory
|
|
134
|
-
from pydantic import BaseModel, Field
|
|
135
134
|
|
|
136
135
|
vec_factory = VectaraToolFactory(
|
|
137
136
|
vectara_api_key=os.environ['VECTARA_API_KEY'],
|
|
138
137
|
vectara_customer_id=os.environ['VECTARA_CUSTOMER_ID'],
|
|
139
138
|
vectara_corpus_id=os.environ['VECTARA_CORPUS_ID']
|
|
140
139
|
)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 2. Create a Vectara RAG Tool
|
|
143
|
+
|
|
144
|
+
A RAG tool calls the full Vectara RAG pipeline to provide summarized responses to queries grounded in data.
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from pydantic import BaseModel, Field
|
|
141
148
|
|
|
142
149
|
years = list(range(2020, 2024))
|
|
143
150
|
tickers = {
|
|
@@ -156,17 +163,22 @@ query_financial_reports_tool = vec_factory.create_rag_tool(
|
|
|
156
163
|
tool_name="query_financial_reports",
|
|
157
164
|
tool_description="Query financial reports for a company and year",
|
|
158
165
|
tool_args_schema=QueryFinancialReportsArgs,
|
|
166
|
+
lambda_val=0.005,
|
|
167
|
+
summary_num_results=7,
|
|
168
|
+
# Additional arguments
|
|
159
169
|
)
|
|
160
170
|
```
|
|
161
171
|
|
|
162
|
-
|
|
172
|
+
See the [docs](https://vectara.github.io/vectara-agentic-docs/) for additional arguments to customize your Vectara RAG tool.
|
|
173
|
+
|
|
174
|
+
### 3. Create other tools (optional)
|
|
163
175
|
|
|
164
176
|
In addition to RAG tools, you can generate a lot of other types of tools the agent can use. These could be mathematical tools, tools
|
|
165
177
|
that call other APIs to get more information, or any other type of tool.
|
|
166
178
|
|
|
167
179
|
See [Agent Tools](#agent-tools) for more information.
|
|
168
180
|
|
|
169
|
-
###
|
|
181
|
+
### 4. Create your agent
|
|
170
182
|
|
|
171
183
|
```python
|
|
172
184
|
from vectara_agentic import Agent
|
|
@@ -186,14 +198,72 @@ agent = Agent(
|
|
|
186
198
|
)
|
|
187
199
|
```
|
|
188
200
|
|
|
189
|
-
|
|
201
|
+
See the [docs](https://vectara.github.io/vectara-agentic-docs/) for additional arguments, including `agent_progress_callback` and `query_logging_callback`.
|
|
202
|
+
|
|
203
|
+
### 5. Run your agent
|
|
190
204
|
|
|
191
205
|
```python
|
|
192
|
-
|
|
193
|
-
print(response)
|
|
206
|
+
res = agent.chat("What was the revenue for Apple in 2021?")
|
|
207
|
+
print(res.response)
|
|
194
208
|
```
|
|
195
209
|
|
|
196
|
-
|
|
210
|
+
Note that:
|
|
211
|
+
1. `vectara-agentic` also supports `achat()` and two streaming variants `stream_chat()` and `astream_chat()`.
|
|
212
|
+
2. The response types from `chat()` and `achat()` are of type `AgentResponse`. If you just need the actual string
|
|
213
|
+
response it's available as the `response` variable, or just use `str()`. For advanced use-cases you can look
|
|
214
|
+
at other `AgentResponse` variables [such as `sources`](https://github.com/run-llama/llama_index/blob/659f9faaafbecebb6e6c65f42143c0bf19274a37/llama-index-core/llama_index/core/chat_engine/types.py#L53).
|
|
215
|
+
|
|
216
|
+
## 🧰 Vectara tools
|
|
217
|
+
|
|
218
|
+
`vectara-agentic` provides two helper functions to connect with Vectara RAG
|
|
219
|
+
* `create_rag_tool()` to create an agent tool that connects with a Vectara corpus for querying.
|
|
220
|
+
* `create_search_tool()` to create a tool to search a Vectara corpus and return a list of matching documents.
|
|
221
|
+
|
|
222
|
+
See the documentation for the full list of arguments for `create_rag_tool()` and `create_search_tool()`,
|
|
223
|
+
to understand how to configure Vectara query performed by those tools.
|
|
224
|
+
|
|
225
|
+
### Creating a Vectara RAG tool
|
|
226
|
+
|
|
227
|
+
A Vectara RAG tool is often the main workhorse for any Agentic RAG application, and enables the agent to query
|
|
228
|
+
one or more Vectara RAG corpora.
|
|
229
|
+
|
|
230
|
+
The tool generated always includes the `query` argument, followed by 1 or more optional arguments used for
|
|
231
|
+
metadata filtering, defined by `tool_args_schema`.
|
|
232
|
+
|
|
233
|
+
For example, in the quickstart example the schema is:
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
class QueryFinancialReportsArgs(BaseModel):
|
|
237
|
+
query: str = Field(..., description="The user query.")
|
|
238
|
+
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').")
|
|
239
|
+
ticker: str = Field(..., description=f"The company ticker. Must be a valid ticket symbol from the list {tickers.keys()}.")
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
The `query` is required and is always the query string.
|
|
243
|
+
The other arguments are optional and will be interpreted as Vectara metadata filters.
|
|
244
|
+
|
|
245
|
+
For example, in the example above, the agent may call the `query_financial_reports_tool` tool with
|
|
246
|
+
query='what is the revenue?', year=2022 and ticker='AAPL'. Subsequently the RAG tool will issue
|
|
247
|
+
a Vectara RAG query with the same query, but with metadata filtering (doc.year=2022 and doc.ticker='AAPL').
|
|
248
|
+
|
|
249
|
+
There are also additional cool features supported here:
|
|
250
|
+
* An argument can be a condition, for example year='>2022' translates to the correct metadata
|
|
251
|
+
filtering condition doc.year>2022
|
|
252
|
+
* if `fixed_filter` is defined in the RAG tool, it provides a constant metadata filtering that is always applied.
|
|
253
|
+
For example, if fixed_filter=`doc.filing_type='10K'` then a query with query='what is the reveue', year=2022
|
|
254
|
+
and ticker='AAPL' would translate into query='what is the revenue' with metadata filtering condition of
|
|
255
|
+
"doc.year=2022 AND doc.ticker='AAPL' and doc.filing_type='10K'"
|
|
256
|
+
|
|
257
|
+
Note that `tool_args_type` is an optional dictionary that indicates the level at which metadata filtering
|
|
258
|
+
is applied for each argument (`doc` or `part`)
|
|
259
|
+
|
|
260
|
+
### Creating a Vectara search tool
|
|
261
|
+
|
|
262
|
+
The Vectara search tool allows the agent to list documents that match a query.
|
|
263
|
+
This can be helpful to the agent to answer queries like "how many documents discuss the iPhone?" or other
|
|
264
|
+
similar queries that require a response in terms of a list of matching documents.
|
|
265
|
+
|
|
266
|
+
## 🛠️ Agent Tools at a Glance
|
|
197
267
|
|
|
198
268
|
`vectara-agentic` provides a few tools out of the box:
|
|
199
269
|
1. **Standard tools**:
|
|
@@ -217,10 +287,9 @@ print(response)
|
|
|
217
287
|
- `load_unique_values`: returns the top unique values for a given column
|
|
218
288
|
|
|
219
289
|
In addition, we include various other tools from LlamaIndex ToolSpecs:
|
|
220
|
-
* Tavily search
|
|
221
|
-
* EXA.AI
|
|
290
|
+
* Tavily search and EXA.AI
|
|
222
291
|
* arxiv
|
|
223
|
-
* neo4j & Kuzu for Graph integration
|
|
292
|
+
* neo4j & Kuzu for Graph DB integration
|
|
224
293
|
* Google tools (including gmail, calendar, and search)
|
|
225
294
|
* Slack
|
|
226
295
|
|
|
@@ -240,7 +309,7 @@ mult_tool = ToolsFactory().create_tool(mult_func)
|
|
|
240
309
|
The main way to control the behavior of `vectara-agentic` is by passing an `AgentConfig` object to your `Agent` when creating it.
|
|
241
310
|
This object will include the following items:
|
|
242
311
|
- `VECTARA_AGENTIC_AGENT_TYPE`: valid values are `REACT`, `LLMCOMPILER`, `LATS` or `OPENAI` (default: `OPENAI`)
|
|
243
|
-
- `VECTARA_AGENTIC_MAIN_LLM_PROVIDER`: valid values are `OPENAI`, `ANTHROPIC`, `TOGETHER`, `GROQ`, `COHERE`, `GEMINI` or `FIREWORKS` (default: `OPENAI`)
|
|
312
|
+
- `VECTARA_AGENTIC_MAIN_LLM_PROVIDER`: valid values are `OPENAI`, `ANTHROPIC`, `TOGETHER`, `GROQ`, `COHERE`, `BEDROCK`, `GEMINI` or `FIREWORKS` (default: `OPENAI`)
|
|
244
313
|
- `VECTARA_AGENTIC_MAIN_MODEL_NAME`: agent model name (default depends on provider)
|
|
245
314
|
- `VECTARA_AGENTIC_TOOL_LLM_PROVIDER`: tool LLM provider (default: `OPENAI`)
|
|
246
315
|
- `VECTARA_AGENTIC_TOOL_MODEL_NAME`: tool model name (default depends on provider)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
tests/test_agent.py,sha256=8LQlny0rIuVa13LGtebG0vatES6Ln7gmenbSwX-ctrY,4260
|
|
3
|
+
tests/test_tools.py,sha256=2ofZYz3Q-YMSxjpiEg1VNUlA9gMjvNAcJAO2Ucd0eVE,2969
|
|
4
|
+
vectara_agentic/__init__.py,sha256=ADH4fPKLbpGNYYYszv3c3QDOjPToPE_qh3LpkH_seCU,430
|
|
5
|
+
vectara_agentic/_callback.py,sha256=OBiHk_OJZTS3iKz_LigfEjnl_p5V90XYsQC0vEYVSPo,8782
|
|
6
|
+
vectara_agentic/_observability.py,sha256=HeQYJIkqPLW3EWHiXHatkaJzo08IQGESKujdeWTuRgk,3805
|
|
7
|
+
vectara_agentic/_prompts.py,sha256=mgGx3zUJPtpS1epBLtl0BnoLeE7wb6AX1SX6dFNaTTQ,6368
|
|
8
|
+
vectara_agentic/_version.py,sha256=90Cr_yLyeFeoJ2YK_LHwWc15gk11Emy9cx1xS0hlwtc,66
|
|
9
|
+
vectara_agentic/agent.py,sha256=1-dno6FrC5sMuJ2nei9o2r3E53sg0dM6p-zn25hxRN0,25979
|
|
10
|
+
vectara_agentic/agent_config.py,sha256=9P9lyFAAXLX1ft2dBQ6tYN7dKzp7SC7B-h-DnhUHsSg,2941
|
|
11
|
+
vectara_agentic/agent_endpoint.py,sha256=QIMejCLlpW2qzXxeDAxv3anF46XMDdVMdKGWhJh3azY,1996
|
|
12
|
+
vectara_agentic/db_tools.py,sha256=kCEENzmnorm8i-k4Kpd4KLJt1QWh_ZlAyX1aG-tzET0,3619
|
|
13
|
+
vectara_agentic/tools.py,sha256=8FNnlTj57VTCYCaUfNWCongg38_lwnEoWdc2idCX6Jw,34087
|
|
14
|
+
vectara_agentic/tools_catalog.py,sha256=DDHoPuA88jiixZjNSuGIuZCB7NSsQXdbbhrbVrtR2Ec,4141
|
|
15
|
+
vectara_agentic/types.py,sha256=00wm3YsJRyddvIBzeVjF3qklA38NuTkCvy_B-e68v6c,1589
|
|
16
|
+
vectara_agentic/utils.py,sha256=eDEOUpCkb0r216LxSLkamll2NmJhu76Z1TgQFbAVq7A,4690
|
|
17
|
+
vectara_agentic-0.1.25.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
18
|
+
vectara_agentic-0.1.25.dist-info/METADATA,sha256=TtClmE0CpgC9qcJlSWxFnTywur0fFK3UkIKnmyZIkGs,19469
|
|
19
|
+
vectara_agentic-0.1.25.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
20
|
+
vectara_agentic-0.1.25.dist-info/top_level.txt,sha256=Y7TQTFdOYGYodQRltUGRieZKIYuzeZj2kHqAUpfCUfg,22
|
|
21
|
+
vectara_agentic-0.1.25.dist-info/RECORD,,
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
tests/test_agent.py,sha256=8LQlny0rIuVa13LGtebG0vatES6Ln7gmenbSwX-ctrY,4260
|
|
3
|
-
tests/test_tools.py,sha256=2ofZYz3Q-YMSxjpiEg1VNUlA9gMjvNAcJAO2Ucd0eVE,2969
|
|
4
|
-
vectara_agentic/__init__.py,sha256=FUWwh37ia9AduK4YDo_TCD52A09ocbYo49oYyBJtyqY,219
|
|
5
|
-
vectara_agentic/_callback.py,sha256=OBiHk_OJZTS3iKz_LigfEjnl_p5V90XYsQC0vEYVSPo,8782
|
|
6
|
-
vectara_agentic/_observability.py,sha256=HeQYJIkqPLW3EWHiXHatkaJzo08IQGESKujdeWTuRgk,3805
|
|
7
|
-
vectara_agentic/_prompts.py,sha256=ITHWQQ4oSmRhqBwRcheYC_nMdZZielUOjfVIbDYi9rw,6257
|
|
8
|
-
vectara_agentic/_version.py,sha256=3P-p27Ccx3RQ_PJQDAu-lIwPrPQ8S780FnRmeItjqNg,66
|
|
9
|
-
vectara_agentic/agent.py,sha256=35dc7RBYevvX9XGz1WoPRQL6N8NnWxL_Eac56e1JpFo,22427
|
|
10
|
-
vectara_agentic/agent_config.py,sha256=8q_eRPURAZYHUXu_rxD2eO1XHC9jNGe_d9ytPgXbS7g,2949
|
|
11
|
-
vectara_agentic/agent_endpoint.py,sha256=QIMejCLlpW2qzXxeDAxv3anF46XMDdVMdKGWhJh3azY,1996
|
|
12
|
-
vectara_agentic/db_tools.py,sha256=kCEENzmnorm8i-k4Kpd4KLJt1QWh_ZlAyX1aG-tzET0,3619
|
|
13
|
-
vectara_agentic/tools.py,sha256=Qhql8IA_CGvsZ3ErOFQH2y-sxxHXvL3GUDH6shgxmzQ,28262
|
|
14
|
-
vectara_agentic/tools_catalog.py,sha256=5NlJypdu0IKa7mODxVOwo05lw3PqQJtSl_ZOsUDH_TA,3986
|
|
15
|
-
vectara_agentic/types.py,sha256=siRh9VmFt3jhTu4uJzYpvNlLi60lyIH5_xqYHKpB24Q,1149
|
|
16
|
-
vectara_agentic/utils.py,sha256=-hnILxUAAtcFRlupeNEVBwHpm-EMF98iLV1Z_hjVrNA,4460
|
|
17
|
-
vectara_agentic-0.1.24.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
18
|
-
vectara_agentic-0.1.24.dist-info/METADATA,sha256=VtSVDzA0zHVWq5C8fNqjATQCOpF_zXIAsWiPYd2_Y5E,15379
|
|
19
|
-
vectara_agentic-0.1.24.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
20
|
-
vectara_agentic-0.1.24.dist-info/top_level.txt,sha256=Y7TQTFdOYGYodQRltUGRieZKIYuzeZj2kHqAUpfCUfg,22
|
|
21
|
-
vectara_agentic-0.1.24.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|