vectara-agentic 0.1.24__py3-none-any.whl → 0.1.26__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 +109 -30
- vectara_agentic/agent_config.py +2 -2
- vectara_agentic/tools.py +277 -117
- vectara_agentic/tools_catalog.py +113 -87
- vectara_agentic/types.py +10 -0
- vectara_agentic/utils.py +4 -0
- {vectara_agentic-0.1.24.dist-info → vectara_agentic-0.1.26.dist-info}/METADATA +146 -41
- vectara_agentic-0.1.26.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.26.dist-info}/LICENSE +0 -0
- {vectara_agentic-0.1.24.dist-info → vectara_agentic-0.1.26.dist-info}/WHEEL +0 -0
- {vectara_agentic-0.1.24.dist-info → vectara_agentic-0.1.26.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:
|
|
@@ -385,8 +397,8 @@ class Agent:
|
|
|
385
397
|
print(f"- {tool.metadata.name}")
|
|
386
398
|
else:
|
|
387
399
|
print("- tool without metadata")
|
|
388
|
-
print(f"Agent LLM = {get_llm(LLMRole.MAIN).metadata.model_name}")
|
|
389
|
-
print(f"Tool LLM = {get_llm(LLMRole.TOOL).metadata.model_name}")
|
|
400
|
+
print(f"Agent LLM = {get_llm(LLMRole.MAIN, config=self.agent_config).metadata.model_name}")
|
|
401
|
+
print(f"Tool LLM = {get_llm(LLMRole.TOOL, config=self.agent_config).metadata.model_name}")
|
|
390
402
|
|
|
391
403
|
def token_counts(self) -> dict:
|
|
392
404
|
"""
|
|
@@ -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
|