vectara-agentic 0.2.4__tar.gz → 0.2.6__tar.gz
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-0.2.4 → vectara_agentic-0.2.6}/PKG-INFO +101 -23
- vectara_agentic-0.2.4/vectara_agentic.egg-info/PKG-INFO → vectara_agentic-0.2.6/README.md +88 -78
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/requirements.txt +10 -10
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/tests/test_agent.py +18 -0
- vectara_agentic-0.2.6/tests/test_agent_planning.py +46 -0
- vectara_agentic-0.2.6/tests/test_agent_type.py +83 -0
- vectara_agentic-0.2.6/tests/test_fallback.py +83 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/tests/test_private_llm.py +10 -9
- vectara_agentic-0.2.6/tests/test_workflow.py +67 -0
- vectara_agentic-0.2.6/vectara_agentic/__init__.py +26 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic/_callback.py +12 -4
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic/_observability.py +1 -1
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic/_prompts.py +48 -7
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic/_version.py +1 -1
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic/agent.py +331 -134
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic/db_tools.py +2 -2
- vectara_agentic-0.2.6/vectara_agentic/sub_query_workflow.py +292 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic/tools.py +34 -21
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic/types.py +5 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic/utils.py +5 -3
- vectara_agentic-0.2.4/README.md → vectara_agentic-0.2.6/vectara_agentic.egg-info/PKG-INFO +156 -11
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic.egg-info/SOURCES.txt +5 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic.egg-info/requires.txt +10 -10
- vectara_agentic-0.2.4/vectara_agentic/__init__.py +0 -16
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/LICENSE +0 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/MANIFEST.in +0 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/setup.cfg +0 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/setup.py +0 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/tests/__init__.py +0 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/tests/endpoint.py +0 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/tests/test_tools.py +0 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic/agent_config.py +0 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic/agent_endpoint.py +0 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic/tools_catalog.py +0 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic.egg-info/dependency_links.txt +0 -0
- {vectara_agentic-0.2.4 → vectara_agentic-0.2.6}/vectara_agentic.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: vectara_agentic
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
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,13 +16,13 @@ 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.
|
|
20
|
-
Requires-Dist: llama-index-indices-managed-vectara==0.4.
|
|
19
|
+
Requires-Dist: llama-index==0.12.25
|
|
20
|
+
Requires-Dist: llama-index-indices-managed-vectara==0.4.2
|
|
21
21
|
Requires-Dist: llama-index-agent-llm-compiler==0.3.0
|
|
22
22
|
Requires-Dist: llama-index-agent-lats==0.3.0
|
|
23
23
|
Requires-Dist: llama-index-agent-openai==0.4.6
|
|
24
24
|
Requires-Dist: llama-index-llms-openai==0.3.25
|
|
25
|
-
Requires-Dist: llama-index-llms-anthropic==0.6.
|
|
25
|
+
Requires-Dist: llama-index-llms-anthropic==0.6.10
|
|
26
26
|
Requires-Dist: llama-index-llms-together==0.3.1
|
|
27
27
|
Requires-Dist: llama-index-llms-groq==0.3.1
|
|
28
28
|
Requires-Dist: llama-index-llms-fireworks==0.3.2
|
|
@@ -41,18 +41,18 @@ Requires-Dist: llama-index-tools-exa==0.3.0
|
|
|
41
41
|
Requires-Dist: tavily-python==0.5.1
|
|
42
42
|
Requires-Dist: exa-py==1.8.9
|
|
43
43
|
Requires-Dist: yahoo-finance==1.4.0
|
|
44
|
-
Requires-Dist: openinference-instrumentation-llama-index==3.
|
|
45
|
-
Requires-Dist: opentelemetry-proto==1.
|
|
46
|
-
Requires-Dist: arize-phoenix==
|
|
47
|
-
Requires-Dist: arize-phoenix-otel==0.
|
|
48
|
-
Requires-Dist: protobuf==
|
|
44
|
+
Requires-Dist: openinference-instrumentation-llama-index==3.3.3
|
|
45
|
+
Requires-Dist: opentelemetry-proto==1.31.0
|
|
46
|
+
Requires-Dist: arize-phoenix==8.14.1
|
|
47
|
+
Requires-Dist: arize-phoenix-otel==0.8.0
|
|
48
|
+
Requires-Dist: protobuf==5.29.3
|
|
49
49
|
Requires-Dist: tokenizers>=0.20
|
|
50
|
-
Requires-Dist: pydantic==2.10.
|
|
50
|
+
Requires-Dist: pydantic==2.10.6
|
|
51
51
|
Requires-Dist: retrying==1.3.4
|
|
52
52
|
Requires-Dist: python-dotenv==1.0.1
|
|
53
53
|
Requires-Dist: tiktoken==0.9.0
|
|
54
54
|
Requires-Dist: cloudpickle>=3.1.1
|
|
55
|
-
Requires-Dist: httpx==0.
|
|
55
|
+
Requires-Dist: httpx==0.28.1
|
|
56
56
|
Dynamic: author
|
|
57
57
|
Dynamic: author-email
|
|
58
58
|
Dynamic: classifier
|
|
@@ -60,6 +60,7 @@ Dynamic: description
|
|
|
60
60
|
Dynamic: description-content-type
|
|
61
61
|
Dynamic: home-page
|
|
62
62
|
Dynamic: keywords
|
|
63
|
+
Dynamic: license-file
|
|
63
64
|
Dynamic: project-url
|
|
64
65
|
Dynamic: requires-dist
|
|
65
66
|
Dynamic: requires-python
|
|
@@ -93,14 +94,20 @@ Dynamic: summary
|
|
|
93
94
|
<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;">
|
|
94
95
|
</p>
|
|
95
96
|
|
|
96
|
-
###
|
|
97
|
-
|
|
98
|
-
-
|
|
99
|
-
|
|
100
|
-
-
|
|
101
|
-
|
|
102
|
-
-
|
|
103
|
-
|
|
97
|
+
### Key Features
|
|
98
|
+
|
|
99
|
+
- **Rapid Tool Creation:**
|
|
100
|
+
Build Vectara RAG tools or search tools with a single line of code.
|
|
101
|
+
- **Agent Flexibility:**
|
|
102
|
+
Supports multiple agent types including `ReAct`, `OpenAIAgent`, `LATS`, and `LLMCompiler`.
|
|
103
|
+
- **Pre-Built Domain Tools:**
|
|
104
|
+
Tools tailored for finance, legal, and other verticals.
|
|
105
|
+
- **Multi-LLM Integration:**
|
|
106
|
+
Seamless integration with OpenAI, Anthropic, Gemini, GROQ, Together.AI, Cohere, Bedrock, and Fireworks.
|
|
107
|
+
- **Observability:**
|
|
108
|
+
Built-in support with Arize Phoenix for monitoring and feedback.
|
|
109
|
+
- **Workflow Support:**
|
|
110
|
+
Extend your agent’s capabilities by defining custom workflows using the `run()` method.
|
|
104
111
|
|
|
105
112
|
### 📚 Example AI Assistants
|
|
106
113
|
|
|
@@ -200,7 +207,7 @@ agent = Agent(
|
|
|
200
207
|
|
|
201
208
|
See the [docs](https://vectara.github.io/vectara-agentic-docs/) for additional arguments, including `agent_progress_callback` and `query_logging_callback`.
|
|
202
209
|
|
|
203
|
-
### 5. Run
|
|
210
|
+
### 5. Run a chat interaction
|
|
204
211
|
|
|
205
212
|
```python
|
|
206
213
|
res = agent.chat("What was the revenue for Apple in 2021?")
|
|
@@ -213,6 +220,77 @@ Note that:
|
|
|
213
220
|
response it's available as the `response` variable, or just use `str()`. For advanced use-cases you can look
|
|
214
221
|
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
222
|
|
|
223
|
+
## Advanced Usage: Workflows
|
|
224
|
+
|
|
225
|
+
In addition to standard chat interactions, `vectara-agentic` supports custom workflows via the `run()` method.
|
|
226
|
+
Workflows allow you to structure multi-step interactions where inputs and outputs are validated using Pydantic models.
|
|
227
|
+
To learn more about workflows read [the documentation](https://docs.llamaindex.ai/en/stable/understanding/workflows/basic_flow/)
|
|
228
|
+
|
|
229
|
+
### Defining a Custom Workflow
|
|
230
|
+
|
|
231
|
+
Create a workflow by subclassing `llama_index.core.workflow.Workflow` and defining the input/output models:
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
from pydantic import BaseModel
|
|
235
|
+
from llama_index.core.workflow import (
|
|
236
|
+
StartEvent,StopEvent, Workflow, step,
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
class MyWorkflow(Workflow):
|
|
240
|
+
class InputsModel(BaseModel):
|
|
241
|
+
query: str
|
|
242
|
+
|
|
243
|
+
class OutputsModel(BaseModel):
|
|
244
|
+
answer: str
|
|
245
|
+
|
|
246
|
+
@step
|
|
247
|
+
async def my_step(self, ev: StartEvent) -> StopEvent:
|
|
248
|
+
# do something here
|
|
249
|
+
return StopEvent(result="Hello, world!")
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
When the `run()` method in vectara-agentic is invoked, it calls the workflow with the following variables in the StartEvent:
|
|
253
|
+
* `agent`: the agent object used to call `run()` (self)
|
|
254
|
+
* `tools`: the tools provided to the agent. Those can be used as needed in the flow.
|
|
255
|
+
* `llm`: a pointer to a LlamaIndex llm, so it can be used in the workflow. For example, one of the steps may call `llm.acomplete(prompt)`
|
|
256
|
+
* `verbose`: controls whether extra debug information is displayed
|
|
257
|
+
* `inputs`: this is the actual inputs to the workflow provided by the call to `run()` and must be of type `InputsModel`
|
|
258
|
+
|
|
259
|
+
### Using the Workflow with Your Agent
|
|
260
|
+
|
|
261
|
+
When initializing your agent, pass the workflow class using the `workflow_cls` parameter:
|
|
262
|
+
|
|
263
|
+
```python
|
|
264
|
+
agent = Agent(
|
|
265
|
+
tools=[query_financial_reports_tool],
|
|
266
|
+
topic="10-K financial reports",
|
|
267
|
+
custom_instructions="You are a helpful financial assistant.",
|
|
268
|
+
workflow_cls=MyWorkflow, # Provide your custom workflow here
|
|
269
|
+
workflow_timeout=120 # Optional: Set a timeout (default is 120 seconds)
|
|
270
|
+
)
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Running the Workflow
|
|
274
|
+
|
|
275
|
+
Prepare the inputs using your workflow’s `InputsModel` and execute the workflow using `run()`:
|
|
276
|
+
|
|
277
|
+
```python
|
|
278
|
+
# Create an instance of the workflow's input model
|
|
279
|
+
inputs = MyWorkflow.InputsModel(query="What is Vectara?", extra_param=42)
|
|
280
|
+
|
|
281
|
+
# Run the workflow (ensure you're in an async context or use asyncio.run)
|
|
282
|
+
workflow_result = asyncio.run(agent.run(inputs))
|
|
283
|
+
|
|
284
|
+
# Access the output from the workflow's OutputsModel
|
|
285
|
+
print(workflow_result.answer)
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Using SubQuestionQueryWorkflow
|
|
289
|
+
|
|
290
|
+
vectara-agentic already includes one useful workflow you can use right away (it is also useful as an advanced example)
|
|
291
|
+
This workflow is called `SubQuestionQueryWorkflow` and it works by breaking a complex query into sub-queries and then
|
|
292
|
+
executing each sub-query with the agent until it reaches a good response.
|
|
293
|
+
|
|
216
294
|
## 🧰 Vectara tools
|
|
217
295
|
|
|
218
296
|
`vectara-agentic` provides two helper functions to connect with Vectara RAG
|
|
@@ -353,9 +431,9 @@ The `AgentConfig` object may include the following items:
|
|
|
353
431
|
|
|
354
432
|
If any of these are not provided, `AgentConfig` first tries to read the values from the OS environment.
|
|
355
433
|
|
|
356
|
-
## Configuring Vectara
|
|
434
|
+
## Configuring Vectara tools: rag_tool, or search_tool
|
|
357
435
|
|
|
358
|
-
When creating a `VectaraToolFactory`, you can pass in a `vectara_api_key`,
|
|
436
|
+
When creating a `VectaraToolFactory`, you can pass in a `vectara_api_key`, and `vectara_corpus_key` to the factory.
|
|
359
437
|
|
|
360
438
|
If not passed in, it will be taken from the environment variables (`VECTARA_API_KEY` and `VECTARA_CORPUS_KEY`). Note that `VECTARA_CORPUS_KEY` can be a single KEY or a comma-separated list of KEYs (if you want to query multiple corpora).
|
|
361
439
|
|
|
@@ -1,70 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.2
|
|
2
|
-
Name: vectara_agentic
|
|
3
|
-
Version: 0.2.4
|
|
4
|
-
Summary: A Python package for creating AI Assistants and AI Agents with Vectara
|
|
5
|
-
Home-page: https://github.com/vectara/py-vectara-agentic
|
|
6
|
-
Author: Ofer Mendelevitch
|
|
7
|
-
Author-email: ofer@vectara.com
|
|
8
|
-
Project-URL: Documentation, https://vectara.github.io/py-vectara-agentic/
|
|
9
|
-
Keywords: LLM,NLP,RAG,Agentic-RAG,AI assistant,AI Agent,Vectara
|
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
|
-
Classifier: Operating System :: OS Independent
|
|
13
|
-
Classifier: Development Status :: 4 - Beta
|
|
14
|
-
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
15
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
-
Requires-Python: >=3.10
|
|
17
|
-
Description-Content-Type: text/markdown
|
|
18
|
-
License-File: LICENSE
|
|
19
|
-
Requires-Dist: llama-index==0.12.22
|
|
20
|
-
Requires-Dist: llama-index-indices-managed-vectara==0.4.1
|
|
21
|
-
Requires-Dist: llama-index-agent-llm-compiler==0.3.0
|
|
22
|
-
Requires-Dist: llama-index-agent-lats==0.3.0
|
|
23
|
-
Requires-Dist: llama-index-agent-openai==0.4.6
|
|
24
|
-
Requires-Dist: llama-index-llms-openai==0.3.25
|
|
25
|
-
Requires-Dist: llama-index-llms-anthropic==0.6.7
|
|
26
|
-
Requires-Dist: llama-index-llms-together==0.3.1
|
|
27
|
-
Requires-Dist: llama-index-llms-groq==0.3.1
|
|
28
|
-
Requires-Dist: llama-index-llms-fireworks==0.3.2
|
|
29
|
-
Requires-Dist: llama-index-llms-cohere==0.4.0
|
|
30
|
-
Requires-Dist: llama-index-llms-gemini==0.4.11
|
|
31
|
-
Requires-Dist: llama-index-llms-bedrock==0.3.4
|
|
32
|
-
Requires-Dist: llama-index-tools-yahoo-finance==0.3.0
|
|
33
|
-
Requires-Dist: llama-index-tools-arxiv==0.3.0
|
|
34
|
-
Requires-Dist: llama-index-tools-database==0.3.0
|
|
35
|
-
Requires-Dist: llama-index-tools-google==0.3.0
|
|
36
|
-
Requires-Dist: llama-index-tools-tavily_research==0.3.0
|
|
37
|
-
Requires-Dist: llama-index-tools-neo4j==0.3.0
|
|
38
|
-
Requires-Dist: llama-index-graph-stores-kuzu==0.6.0
|
|
39
|
-
Requires-Dist: llama-index-tools-slack==0.3.0
|
|
40
|
-
Requires-Dist: llama-index-tools-exa==0.3.0
|
|
41
|
-
Requires-Dist: tavily-python==0.5.1
|
|
42
|
-
Requires-Dist: exa-py==1.8.9
|
|
43
|
-
Requires-Dist: yahoo-finance==1.4.0
|
|
44
|
-
Requires-Dist: openinference-instrumentation-llama-index==3.1.4
|
|
45
|
-
Requires-Dist: opentelemetry-proto==1.26.0
|
|
46
|
-
Requires-Dist: arize-phoenix==7.11.0
|
|
47
|
-
Requires-Dist: arize-phoenix-otel==0.6.1
|
|
48
|
-
Requires-Dist: protobuf==4.25.5
|
|
49
|
-
Requires-Dist: tokenizers>=0.20
|
|
50
|
-
Requires-Dist: pydantic==2.10.3
|
|
51
|
-
Requires-Dist: retrying==1.3.4
|
|
52
|
-
Requires-Dist: python-dotenv==1.0.1
|
|
53
|
-
Requires-Dist: tiktoken==0.9.0
|
|
54
|
-
Requires-Dist: cloudpickle>=3.1.1
|
|
55
|
-
Requires-Dist: httpx==0.27.2
|
|
56
|
-
Dynamic: author
|
|
57
|
-
Dynamic: author-email
|
|
58
|
-
Dynamic: classifier
|
|
59
|
-
Dynamic: description
|
|
60
|
-
Dynamic: description-content-type
|
|
61
|
-
Dynamic: home-page
|
|
62
|
-
Dynamic: keywords
|
|
63
|
-
Dynamic: project-url
|
|
64
|
-
Dynamic: requires-dist
|
|
65
|
-
Dynamic: requires-python
|
|
66
|
-
Dynamic: summary
|
|
67
|
-
|
|
68
1
|
# <img src="https://raw.githubusercontent.com/vectara/py-vectara-agentic/main/.github/assets/Vectara-logo.png" alt="Vectara Logo" width="30" height="30" style="vertical-align: middle;"> vectara-agentic
|
|
69
2
|
|
|
70
3
|
<p align="center">
|
|
@@ -93,14 +26,20 @@ Dynamic: summary
|
|
|
93
26
|
<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;">
|
|
94
27
|
</p>
|
|
95
28
|
|
|
96
|
-
###
|
|
97
|
-
|
|
98
|
-
-
|
|
99
|
-
|
|
100
|
-
-
|
|
101
|
-
|
|
102
|
-
-
|
|
103
|
-
|
|
29
|
+
### Key Features
|
|
30
|
+
|
|
31
|
+
- **Rapid Tool Creation:**
|
|
32
|
+
Build Vectara RAG tools or search tools with a single line of code.
|
|
33
|
+
- **Agent Flexibility:**
|
|
34
|
+
Supports multiple agent types including `ReAct`, `OpenAIAgent`, `LATS`, and `LLMCompiler`.
|
|
35
|
+
- **Pre-Built Domain Tools:**
|
|
36
|
+
Tools tailored for finance, legal, and other verticals.
|
|
37
|
+
- **Multi-LLM Integration:**
|
|
38
|
+
Seamless integration with OpenAI, Anthropic, Gemini, GROQ, Together.AI, Cohere, Bedrock, and Fireworks.
|
|
39
|
+
- **Observability:**
|
|
40
|
+
Built-in support with Arize Phoenix for monitoring and feedback.
|
|
41
|
+
- **Workflow Support:**
|
|
42
|
+
Extend your agent’s capabilities by defining custom workflows using the `run()` method.
|
|
104
43
|
|
|
105
44
|
### 📚 Example AI Assistants
|
|
106
45
|
|
|
@@ -200,7 +139,7 @@ agent = Agent(
|
|
|
200
139
|
|
|
201
140
|
See the [docs](https://vectara.github.io/vectara-agentic-docs/) for additional arguments, including `agent_progress_callback` and `query_logging_callback`.
|
|
202
141
|
|
|
203
|
-
### 5. Run
|
|
142
|
+
### 5. Run a chat interaction
|
|
204
143
|
|
|
205
144
|
```python
|
|
206
145
|
res = agent.chat("What was the revenue for Apple in 2021?")
|
|
@@ -213,6 +152,77 @@ Note that:
|
|
|
213
152
|
response it's available as the `response` variable, or just use `str()`. For advanced use-cases you can look
|
|
214
153
|
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
154
|
|
|
155
|
+
## Advanced Usage: Workflows
|
|
156
|
+
|
|
157
|
+
In addition to standard chat interactions, `vectara-agentic` supports custom workflows via the `run()` method.
|
|
158
|
+
Workflows allow you to structure multi-step interactions where inputs and outputs are validated using Pydantic models.
|
|
159
|
+
To learn more about workflows read [the documentation](https://docs.llamaindex.ai/en/stable/understanding/workflows/basic_flow/)
|
|
160
|
+
|
|
161
|
+
### Defining a Custom Workflow
|
|
162
|
+
|
|
163
|
+
Create a workflow by subclassing `llama_index.core.workflow.Workflow` and defining the input/output models:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from pydantic import BaseModel
|
|
167
|
+
from llama_index.core.workflow import (
|
|
168
|
+
StartEvent,StopEvent, Workflow, step,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
class MyWorkflow(Workflow):
|
|
172
|
+
class InputsModel(BaseModel):
|
|
173
|
+
query: str
|
|
174
|
+
|
|
175
|
+
class OutputsModel(BaseModel):
|
|
176
|
+
answer: str
|
|
177
|
+
|
|
178
|
+
@step
|
|
179
|
+
async def my_step(self, ev: StartEvent) -> StopEvent:
|
|
180
|
+
# do something here
|
|
181
|
+
return StopEvent(result="Hello, world!")
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
When the `run()` method in vectara-agentic is invoked, it calls the workflow with the following variables in the StartEvent:
|
|
185
|
+
* `agent`: the agent object used to call `run()` (self)
|
|
186
|
+
* `tools`: the tools provided to the agent. Those can be used as needed in the flow.
|
|
187
|
+
* `llm`: a pointer to a LlamaIndex llm, so it can be used in the workflow. For example, one of the steps may call `llm.acomplete(prompt)`
|
|
188
|
+
* `verbose`: controls whether extra debug information is displayed
|
|
189
|
+
* `inputs`: this is the actual inputs to the workflow provided by the call to `run()` and must be of type `InputsModel`
|
|
190
|
+
|
|
191
|
+
### Using the Workflow with Your Agent
|
|
192
|
+
|
|
193
|
+
When initializing your agent, pass the workflow class using the `workflow_cls` parameter:
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
agent = Agent(
|
|
197
|
+
tools=[query_financial_reports_tool],
|
|
198
|
+
topic="10-K financial reports",
|
|
199
|
+
custom_instructions="You are a helpful financial assistant.",
|
|
200
|
+
workflow_cls=MyWorkflow, # Provide your custom workflow here
|
|
201
|
+
workflow_timeout=120 # Optional: Set a timeout (default is 120 seconds)
|
|
202
|
+
)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Running the Workflow
|
|
206
|
+
|
|
207
|
+
Prepare the inputs using your workflow’s `InputsModel` and execute the workflow using `run()`:
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
# Create an instance of the workflow's input model
|
|
211
|
+
inputs = MyWorkflow.InputsModel(query="What is Vectara?", extra_param=42)
|
|
212
|
+
|
|
213
|
+
# Run the workflow (ensure you're in an async context or use asyncio.run)
|
|
214
|
+
workflow_result = asyncio.run(agent.run(inputs))
|
|
215
|
+
|
|
216
|
+
# Access the output from the workflow's OutputsModel
|
|
217
|
+
print(workflow_result.answer)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Using SubQuestionQueryWorkflow
|
|
221
|
+
|
|
222
|
+
vectara-agentic already includes one useful workflow you can use right away (it is also useful as an advanced example)
|
|
223
|
+
This workflow is called `SubQuestionQueryWorkflow` and it works by breaking a complex query into sub-queries and then
|
|
224
|
+
executing each sub-query with the agent until it reaches a good response.
|
|
225
|
+
|
|
216
226
|
## 🧰 Vectara tools
|
|
217
227
|
|
|
218
228
|
`vectara-agentic` provides two helper functions to connect with Vectara RAG
|
|
@@ -353,9 +363,9 @@ The `AgentConfig` object may include the following items:
|
|
|
353
363
|
|
|
354
364
|
If any of these are not provided, `AgentConfig` first tries to read the values from the OS environment.
|
|
355
365
|
|
|
356
|
-
## Configuring Vectara
|
|
366
|
+
## Configuring Vectara tools: rag_tool, or search_tool
|
|
357
367
|
|
|
358
|
-
When creating a `VectaraToolFactory`, you can pass in a `vectara_api_key`,
|
|
368
|
+
When creating a `VectaraToolFactory`, you can pass in a `vectara_api_key`, and `vectara_corpus_key` to the factory.
|
|
359
369
|
|
|
360
370
|
If not passed in, it will be taken from the environment variables (`VECTARA_API_KEY` and `VECTARA_CORPUS_KEY`). Note that `VECTARA_CORPUS_KEY` can be a single KEY or a comma-separated list of KEYs (if you want to query multiple corpora).
|
|
361
371
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
llama-index==0.12.
|
|
2
|
-
llama-index-indices-managed-vectara==0.4.
|
|
1
|
+
llama-index==0.12.25
|
|
2
|
+
llama-index-indices-managed-vectara==0.4.2
|
|
3
3
|
llama-index-agent-llm-compiler==0.3.0
|
|
4
4
|
llama-index-agent-lats==0.3.0
|
|
5
5
|
llama-index-agent-openai==0.4.6
|
|
6
6
|
llama-index-llms-openai==0.3.25
|
|
7
|
-
llama-index-llms-anthropic==0.6.
|
|
7
|
+
llama-index-llms-anthropic==0.6.10
|
|
8
8
|
llama-index-llms-together==0.3.1
|
|
9
9
|
llama-index-llms-groq==0.3.1
|
|
10
10
|
llama-index-llms-fireworks==0.3.2
|
|
@@ -23,15 +23,15 @@ llama-index-tools-exa==0.3.0
|
|
|
23
23
|
tavily-python==0.5.1
|
|
24
24
|
exa-py==1.8.9
|
|
25
25
|
yahoo-finance==1.4.0
|
|
26
|
-
openinference-instrumentation-llama-index==3.
|
|
27
|
-
opentelemetry-proto==1.
|
|
28
|
-
arize-phoenix==
|
|
29
|
-
arize-phoenix-otel==0.
|
|
30
|
-
protobuf==
|
|
26
|
+
openinference-instrumentation-llama-index==3.3.3
|
|
27
|
+
opentelemetry-proto==1.31.0
|
|
28
|
+
arize-phoenix==8.14.1
|
|
29
|
+
arize-phoenix-otel==0.8.0
|
|
30
|
+
protobuf==5.29.3
|
|
31
31
|
tokenizers>=0.20
|
|
32
|
-
pydantic==2.10.
|
|
32
|
+
pydantic==2.10.6
|
|
33
33
|
retrying==1.3.4
|
|
34
34
|
python-dotenv==1.0.1
|
|
35
35
|
tiktoken==0.9.0
|
|
36
36
|
cloudpickle>=3.1.1
|
|
37
|
-
httpx==0.
|
|
37
|
+
httpx==0.28.1
|
|
@@ -102,8 +102,18 @@ class TestAgentPackage(unittest.TestCase):
|
|
|
102
102
|
self.assertEqual(agent._topic, "question answering")
|
|
103
103
|
|
|
104
104
|
def test_serialization(self):
|
|
105
|
+
config = AgentConfig(
|
|
106
|
+
agent_type=AgentType.REACT,
|
|
107
|
+
main_llm_provider=ModelProvider.ANTHROPIC,
|
|
108
|
+
main_llm_model_name="claude-3-5-sonnet-20241022",
|
|
109
|
+
tool_llm_provider=ModelProvider.TOGETHER,
|
|
110
|
+
tool_llm_model_name="meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
|
111
|
+
observer=ObserverType.ARIZE_PHOENIX
|
|
112
|
+
)
|
|
113
|
+
|
|
105
114
|
agent = Agent.from_corpus(
|
|
106
115
|
tool_name="RAG Tool",
|
|
116
|
+
agent_config=config,
|
|
107
117
|
vectara_corpus_key="corpus_key",
|
|
108
118
|
vectara_api_key="api_key",
|
|
109
119
|
data_description="information",
|
|
@@ -117,10 +127,18 @@ class TestAgentPackage(unittest.TestCase):
|
|
|
117
127
|
self.assertEqual(agent, agent_reloaded)
|
|
118
128
|
self.assertEqual(agent.agent_type, agent_reloaded.agent_type)
|
|
119
129
|
|
|
130
|
+
self.assertEqual(agent.agent_config.observer, agent_reloaded.agent_config.observer)
|
|
131
|
+
self.assertEqual(agent.agent_config.main_llm_provider, agent_reloaded.agent_config.main_llm_provider)
|
|
132
|
+
self.assertEqual(agent.agent_config.tool_llm_provider, agent_reloaded.agent_config.tool_llm_provider)
|
|
133
|
+
|
|
120
134
|
self.assertIsInstance(agent_reloaded, Agent)
|
|
121
135
|
self.assertEqual(agent, agent_reloaded_again)
|
|
122
136
|
self.assertEqual(agent.agent_type, agent_reloaded_again.agent_type)
|
|
123
137
|
|
|
138
|
+
self.assertEqual(agent.agent_config.observer, agent_reloaded_again.agent_config.observer)
|
|
139
|
+
self.assertEqual(agent.agent_config.main_llm_provider, agent_reloaded_again.agent_config.main_llm_provider)
|
|
140
|
+
self.assertEqual(agent.agent_config.tool_llm_provider, agent_reloaded_again.agent_config.tool_llm_provider)
|
|
141
|
+
|
|
124
142
|
def test_chat_history(self):
|
|
125
143
|
tools = [ToolsFactory().create_tool(mult)]
|
|
126
144
|
topic = "AI topic"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
|
|
3
|
+
from vectara_agentic.agent import Agent
|
|
4
|
+
from vectara_agentic.agent_config import AgentConfig
|
|
5
|
+
from vectara_agentic.tools import ToolsFactory
|
|
6
|
+
|
|
7
|
+
def mult(x, y):
|
|
8
|
+
return x * y
|
|
9
|
+
|
|
10
|
+
def addition(x, y):
|
|
11
|
+
return x + y
|
|
12
|
+
|
|
13
|
+
class TestAgentPlanningPackage(unittest.TestCase):
|
|
14
|
+
|
|
15
|
+
def test_no_planning(self):
|
|
16
|
+
tools = [ToolsFactory().create_tool(mult)]
|
|
17
|
+
topic = "AI topic"
|
|
18
|
+
instructions = "Always do as your father tells you, if your mother agrees!"
|
|
19
|
+
agent = Agent(
|
|
20
|
+
tools=tools,
|
|
21
|
+
topic=topic,
|
|
22
|
+
custom_instructions=instructions,
|
|
23
|
+
agent_config = AgentConfig()
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
res = agent.chat("If you multiply 5 times 7, then 3 times 2, and add the results - what do you get?")
|
|
27
|
+
self.assertIn("41", res.response)
|
|
28
|
+
|
|
29
|
+
def test_structured_planning(self):
|
|
30
|
+
tools = [ToolsFactory().create_tool(mult), ToolsFactory().create_tool(addition)]
|
|
31
|
+
topic = "AI topic"
|
|
32
|
+
instructions = "Always do as your father tells you, if your mother agrees!"
|
|
33
|
+
agent = Agent(
|
|
34
|
+
tools=tools,
|
|
35
|
+
topic=topic,
|
|
36
|
+
custom_instructions=instructions,
|
|
37
|
+
agent_config = AgentConfig(),
|
|
38
|
+
use_structured_planning = True,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
res = agent.chat("If you multiply 5 times 7, then 3 times 2, and add the results - what do you get?")
|
|
42
|
+
self.assertIn("41", res.response)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
if __name__ == "__main__":
|
|
46
|
+
unittest.main()
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
|
|
3
|
+
from vectara_agentic.agent import Agent, AgentType
|
|
4
|
+
from vectara_agentic.agent_config import AgentConfig
|
|
5
|
+
from vectara_agentic.tools import ToolsFactory
|
|
6
|
+
from vectara_agentic.types import ModelProvider
|
|
7
|
+
|
|
8
|
+
import nest_asyncio
|
|
9
|
+
nest_asyncio.apply()
|
|
10
|
+
def mult(x, y):
|
|
11
|
+
return x * y
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
react_config_1 = AgentConfig(
|
|
15
|
+
agent_type=AgentType.REACT,
|
|
16
|
+
main_llm_provider=ModelProvider.ANTHROPIC,
|
|
17
|
+
main_llm_model_name="claude-3-7-sonnet-20250219",
|
|
18
|
+
tool_llm_provider=ModelProvider.TOGETHER,
|
|
19
|
+
tool_llm_model_name="meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
react_config_2 = AgentConfig(
|
|
23
|
+
agent_type=AgentType.REACT,
|
|
24
|
+
main_llm_provider=ModelProvider.GEMINI,
|
|
25
|
+
tool_llm_provider=ModelProvider.GEMINI,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
openai_config = AgentConfig(
|
|
29
|
+
agent_type=AgentType.OPENAI,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
class TestAgentType(unittest.TestCase):
|
|
33
|
+
|
|
34
|
+
def test_openai(self):
|
|
35
|
+
tools = [ToolsFactory().create_tool(mult)]
|
|
36
|
+
topic = "AI topic"
|
|
37
|
+
instructions = "Always do as your father tells you, if your mother agrees!"
|
|
38
|
+
agent = Agent(
|
|
39
|
+
agent_config=openai_config,
|
|
40
|
+
tools=tools,
|
|
41
|
+
topic=topic,
|
|
42
|
+
custom_instructions=instructions,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
agent.chat("What is 5 times 10. Only give the answer, nothing else")
|
|
46
|
+
agent.chat("what is 3 times 7. Only give the answer, nothing else")
|
|
47
|
+
res = agent.chat("multiply the results of the last two multiplications. Only give the answer, nothing else.")
|
|
48
|
+
self.assertIn("1050", res.response)
|
|
49
|
+
|
|
50
|
+
def test_react_anthropic(self):
|
|
51
|
+
tools = [ToolsFactory().create_tool(mult)]
|
|
52
|
+
topic = "AI topic"
|
|
53
|
+
instructions = "Always do as your father tells you, if your mother agrees!"
|
|
54
|
+
agent = Agent(
|
|
55
|
+
agent_config=react_config_1,
|
|
56
|
+
tools=tools,
|
|
57
|
+
topic=topic,
|
|
58
|
+
custom_instructions=instructions,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
agent.chat("What is 5 times 10. Only give the answer, nothing else")
|
|
62
|
+
agent.chat("what is 3 times 7. Only give the answer, nothing else")
|
|
63
|
+
res = agent.chat("multiply the results of the last two multiplications. Only give the answer, nothing else.")
|
|
64
|
+
self.assertIn("1050", res.response)
|
|
65
|
+
|
|
66
|
+
def test_react_gemini(self):
|
|
67
|
+
tools = [ToolsFactory().create_tool(mult)]
|
|
68
|
+
topic = "AI topic"
|
|
69
|
+
instructions = "Always do as your father tells you, if your mother agrees!"
|
|
70
|
+
agent = Agent(
|
|
71
|
+
agent_config=react_config_2,
|
|
72
|
+
tools=tools,
|
|
73
|
+
topic=topic,
|
|
74
|
+
custom_instructions=instructions,
|
|
75
|
+
)
|
|
76
|
+
agent.chat("What is 5 times 10. Only give the answer, nothing else")
|
|
77
|
+
agent.chat("what is 3 times 7. Only give the answer, nothing else")
|
|
78
|
+
res = agent.chat("multiply the results of the last two multiplications. Only give the answer, nothing else.")
|
|
79
|
+
self.assertIn("1050", res.response)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
if __name__ == "__main__":
|
|
83
|
+
unittest.main()
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import unittest
|
|
3
|
+
import subprocess
|
|
4
|
+
import time
|
|
5
|
+
import requests
|
|
6
|
+
import signal
|
|
7
|
+
|
|
8
|
+
from vectara_agentic.agent import Agent, AgentType
|
|
9
|
+
from vectara_agentic.agent_config import AgentConfig
|
|
10
|
+
from vectara_agentic.types import ModelProvider, AgentConfigType
|
|
11
|
+
from vectara_agentic.tools import ToolsFactory
|
|
12
|
+
|
|
13
|
+
FLASK_PORT = 5002
|
|
14
|
+
|
|
15
|
+
class TestFallback(unittest.TestCase):
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def setUp(cls):
|
|
19
|
+
# Start the Flask server as a subprocess
|
|
20
|
+
cls.flask_process = subprocess.Popen(
|
|
21
|
+
['flask', 'run', f'--port={FLASK_PORT}'],
|
|
22
|
+
env={**os.environ, 'FLASK_APP': 'tests.endpoint:app', 'FLASK_ENV': 'development'},
|
|
23
|
+
stdout=None, stderr=None,
|
|
24
|
+
)
|
|
25
|
+
# Wait for the server to start
|
|
26
|
+
timeout = 10
|
|
27
|
+
url = f'http://127.0.0.1:{FLASK_PORT}/'
|
|
28
|
+
for _ in range(timeout):
|
|
29
|
+
try:
|
|
30
|
+
requests.get(url)
|
|
31
|
+
print("Flask server started for fallback unit test")
|
|
32
|
+
return
|
|
33
|
+
except requests.ConnectionError:
|
|
34
|
+
time.sleep(1)
|
|
35
|
+
raise RuntimeError(f"Failed to start Flask server at {url}")
|
|
36
|
+
|
|
37
|
+
@classmethod
|
|
38
|
+
def tearDown(cls):
|
|
39
|
+
# Terminate the Flask server
|
|
40
|
+
cls.flask_process.send_signal(signal.SIGINT)
|
|
41
|
+
cls.flask_process.wait()
|
|
42
|
+
|
|
43
|
+
def test_fallback(self):
|
|
44
|
+
def mult(x, y):
|
|
45
|
+
return x * y
|
|
46
|
+
|
|
47
|
+
tools = [ToolsFactory().create_tool(mult)]
|
|
48
|
+
topic = "calculator"
|
|
49
|
+
custom_instructions = "you are an agent specializing in math, assisting a user."
|
|
50
|
+
config = AgentConfig(
|
|
51
|
+
agent_type=AgentType.REACT,
|
|
52
|
+
main_llm_provider=ModelProvider.PRIVATE,
|
|
53
|
+
main_llm_model_name="gpt-4o",
|
|
54
|
+
private_llm_api_base=f"http://127.0.0.1:{FLASK_PORT}/v1",
|
|
55
|
+
private_llm_api_key="TEST_API_KEY",
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# Set fallback agent config to OpenAI agent
|
|
59
|
+
fallback_config = AgentConfig()
|
|
60
|
+
|
|
61
|
+
agent = Agent(agent_config=config, tools=tools, topic=topic,
|
|
62
|
+
custom_instructions=custom_instructions,
|
|
63
|
+
fallback_agent_config=fallback_config)
|
|
64
|
+
|
|
65
|
+
# To run this test, you must have OPENAI_API_KEY in your environment
|
|
66
|
+
res = agent.chat(
|
|
67
|
+
"What is 5 times 10. Only give the answer, nothing else"
|
|
68
|
+
).response
|
|
69
|
+
self.assertEqual(res, "50")
|
|
70
|
+
|
|
71
|
+
TestFallback.flask_process.send_signal(signal.SIGINT)
|
|
72
|
+
TestFallback.flask_process.wait()
|
|
73
|
+
|
|
74
|
+
res = agent.chat(
|
|
75
|
+
"What is 5 times 10. Only give the answer, nothing else"
|
|
76
|
+
).response
|
|
77
|
+
self.assertEqual(res, "50")
|
|
78
|
+
self.assertEqual(agent.agent_config_type, AgentConfigType.FALLBACK)
|
|
79
|
+
self.assertEqual(agent.fallback_agent_config, fallback_config)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
if __name__ == "__main__":
|
|
83
|
+
unittest.main()
|