vectara-agentic 0.1.9__tar.gz → 0.1.11__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.

Files changed (23) hide show
  1. {vectara_agentic-0.1.9/vectara_agentic.egg-info → vectara_agentic-0.1.11}/PKG-INFO +32 -15
  2. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/README.md +21 -8
  3. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/requirements.txt +10 -6
  4. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/setup.py +1 -1
  5. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/tests/test_agent.py +14 -0
  6. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/tests/test_tools.py +20 -0
  7. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/vectara_agentic/__init__.py +1 -1
  8. vectara_agentic-0.1.11/vectara_agentic/_observability.py +83 -0
  9. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/vectara_agentic/agent.py +178 -24
  10. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/vectara_agentic/tools.py +26 -6
  11. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/vectara_agentic/types.py +1 -0
  12. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/vectara_agentic/utils.py +10 -6
  13. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11/vectara_agentic.egg-info}/PKG-INFO +32 -15
  14. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/vectara_agentic.egg-info/SOURCES.txt +1 -0
  15. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/vectara_agentic.egg-info/requires.txt +10 -6
  16. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/LICENSE +0 -0
  17. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/MANIFEST.in +0 -0
  18. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/setup.cfg +0 -0
  19. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/vectara_agentic/_callback.py +0 -0
  20. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/vectara_agentic/_prompts.py +0 -0
  21. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/vectara_agentic/tools_catalog.py +0 -0
  22. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/vectara_agentic.egg-info/dependency_links.txt +0 -0
  23. {vectara_agentic-0.1.9 → vectara_agentic-0.1.11}/vectara_agentic.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vectara_agentic
3
- Version: 0.1.9
3
+ Version: 0.1.11
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,27 +16,31 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
16
  Requires-Python: >=3.10
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: llama-index==0.11.10
19
+ Requires-Dist: llama-index==0.11.13
20
20
  Requires-Dist: llama-index-indices-managed-vectara==0.2.2
21
21
  Requires-Dist: llama-index-agent-llm-compiler==0.2.0
22
- Requires-Dist: llama-index-agent-openai==0.3.1
23
- Requires-Dist: llama-index-llms-openai==0.2.7
22
+ Requires-Dist: llama-index-agent-openai==0.3.4
23
+ Requires-Dist: llama-index-llms-openai==0.2.9
24
24
  Requires-Dist: llama-index-llms-anthropic==0.3.1
25
25
  Requires-Dist: llama-index-llms-together==0.2.0
26
26
  Requires-Dist: llama-index-llms-groq==0.2.0
27
27
  Requires-Dist: llama-index-llms-fireworks==0.2.0
28
28
  Requires-Dist: llama-index-llms-cohere==0.3.0
29
+ Requires-Dist: llama-index-llms-gemini==0.3.5
29
30
  Requires-Dist: llama-index-tools-yahoo-finance==0.2.0
30
31
  Requires-Dist: llama-index-tools-arxiv==0.2.0
31
32
  Requires-Dist: llama-index-tools-database==0.2.0
32
33
  Requires-Dist: llama-index-tools-google==0.2.0
33
34
  Requires-Dist: llama-index-tools-tavily_research==0.2.0
34
- Requires-Dist: llama-index-callbacks-arize-phoenix==0.2.1
35
- Requires-Dist: pydantic==2.8.2
35
+ Requires-Dist: openinference-instrumentation-llama-index==3.0.2
36
+ Requires-Dist: opentelemetry-proto==1.16.0
37
+ Requires-Dist: arize-phoenix-otel==0.5.1
38
+ Requires-Dist: pydantic==2.9.2
36
39
  Requires-Dist: retrying==1.3.4
37
- Requires-Dist: pymongo==4.6.1
40
+ Requires-Dist: pymongo==4.6.3
38
41
  Requires-Dist: python-dotenv==1.0.1
39
42
  Requires-Dist: tiktoken==0.7.0
43
+ Requires-Dist: dill==0.3.8
40
44
 
41
45
  # vectara-agentic
42
46
 
@@ -64,7 +68,7 @@ Requires-Dist: tiktoken==0.7.0
64
68
  - [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)
65
69
  - A Vectara corpus with an [API key](https://docs.vectara.com/docs/api-keys)
66
70
  - [Python 3.10 or higher](https://www.python.org/downloads/)
67
- - OpenAI API key (or API keys for Anthropic, TOGETHER.AI, Fireworks AI, Cohere or GROQ)
71
+ - OpenAI API key (or API keys for Anthropic, TOGETHER.AI, Fireworks AI, Cohere, GEMINI or GROQ)
68
72
 
69
73
  ## Installation
70
74
 
@@ -98,6 +102,8 @@ query_financial_reports = vec_factory.create_rag_tool(
98
102
  )
99
103
  ```
100
104
 
105
+ Note that `VECTARA_CORPUS_ID` can be a single ID or a comma-separated list of IDs.
106
+
101
107
  2. **Create other tools (optional)**
102
108
 
103
109
  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
@@ -139,7 +145,7 @@ financial_bot_instructions = """
139
145
  Configure `vectara-agentic` using environment variables:
140
146
 
141
147
  - `VECTARA_AGENTIC_AGENT_TYPE`: valid values are `REACT`, `LLMCOMPILER` or `OPENAI` (default: `OPENAI`)
142
- - `VECTARA_AGENTIC_MAIN_LLM_PROVIDER`: valid values are `OPENAI`, `ANTHROPIC`, `TOGETHER`, `GROQ`, `COHERE` or `FIREWORKS` (default: `OPENAI`)
148
+ - `VECTARA_AGENTIC_MAIN_LLM_PROVIDER`: valid values are `OPENAI`, `ANTHROPIC`, `TOGETHER`, `GROQ`, `COHERE`, `GEMINI` or `FIREWORKS` (default: `OPENAI`)
143
149
  - `VECTARA_AGENTIC_MAIN_MODEL_NAME`: agent model name (default depends on provider)
144
150
  - `VECTARA_AGENTIC_TOOL_LLM_PROVIDER`: tool LLM provider (default: `OPENAI`)
145
151
  - `VECTARA_AGENTIC_TOOL_MODEL_NAME`: tool model name (default depends on provider)
@@ -182,16 +188,27 @@ The `Agent` class defines a few helpful methods to help you understand the inter
182
188
  * The `report()` method prints out the agent object’s type, the tools, and the LLMs used for the main agent and tool calling.
183
189
  * The `token_counts()` method tells you how many tokens you have used in the current session for both the main agent and tool calling LLMs. This can be helpful if you want to track spend by token.
184
190
 
191
+ ## Serialization
192
+
193
+ The `Agent` class supports serialization. Use the `dumps()` to serialize and `loads()` to read back from a serialized stream.
194
+
185
195
  ## Observability
186
196
 
187
197
  vectara-agentic supports observability via the existing integration of LlamaIndex and Arize Phoenix.
188
- To enable tracing of your vectara-agentic assistant, follow these steps (adapted from [here](https://docs.llamaindex.ai/en/stable/module_guides/observability/)):
189
- 1. Go to `https://llamatrace.com/login` an create an account, then create an API key and put it in the `PHOENIX_API_KEY` variable
190
- 2. `os["VECTARA_AGENTIC_OBSERVER_TYPE"] = "ARIZE_PHOENIX"`: to enable Arize Phoenix observability
191
- 3. `os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"api_key={PHOENIX_API_KEY}"`
198
+ First, set `os["VECTARA_AGENTIC_OBSERVER_TYPE"] = "ARIZE_PHOENIX"`.
199
+ Then you can use Arize Phoenix in three ways:
200
+ 1. **Locally**.
201
+ 1. If you have a local phoenix server that you've run using e.g. `python -m phoenix.server.main serve`, vectara-agentic will send all traces to it.
202
+ 2. If not, vectara-agentic will run a local instance during the agent's lifecycle, and will close it when finished.
203
+ 3. In both cases, traces will be sent to the local instance, and you can see the dashboard at `http://localhost:6006`
204
+ 2. **Hosted Instance**. In this case the traces are sent to the Phoenix instances hosted on Arize.
205
+ 1. Go to `https://app.phoenix.arize.com`, setup an account if you don't have one.
206
+ 2. create an API key and put it in the `PHOENIX_API_KEY` variable. This variable indicates you want to use the hosted version.
207
+ 3. To view the traces go to `https://app.phoenix.arize.com`.
208
+
209
+ Now when you run your agent, all call traces are sent to Phoenix and recorded.
210
+ In addition, vectara-agentic also records `FCS` values into Arize for every Vectara RAG call. You can see those results in the `Feedback` column of the arize UI.
192
211
 
193
- Now when you run your agent, all metrics are sent to LlamaTrace and recorded. You can view them at `https://llamatrace.com`.
194
- If you do not include the `OTEL_EXPORTER_OTLP_HEADERS` a local instance of Arize Phoenix will be setup instead and you can view it at `http://localhost:6006`
195
212
 
196
213
  ## About Custom Instructions
197
214
 
@@ -24,7 +24,7 @@
24
24
  - [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)
25
25
  - A Vectara corpus with an [API key](https://docs.vectara.com/docs/api-keys)
26
26
  - [Python 3.10 or higher](https://www.python.org/downloads/)
27
- - OpenAI API key (or API keys for Anthropic, TOGETHER.AI, Fireworks AI, Cohere or GROQ)
27
+ - OpenAI API key (or API keys for Anthropic, TOGETHER.AI, Fireworks AI, Cohere, GEMINI or GROQ)
28
28
 
29
29
  ## Installation
30
30
 
@@ -58,6 +58,8 @@ query_financial_reports = vec_factory.create_rag_tool(
58
58
  )
59
59
  ```
60
60
 
61
+ Note that `VECTARA_CORPUS_ID` can be a single ID or a comma-separated list of IDs.
62
+
61
63
  2. **Create other tools (optional)**
62
64
 
63
65
  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
@@ -99,7 +101,7 @@ financial_bot_instructions = """
99
101
  Configure `vectara-agentic` using environment variables:
100
102
 
101
103
  - `VECTARA_AGENTIC_AGENT_TYPE`: valid values are `REACT`, `LLMCOMPILER` or `OPENAI` (default: `OPENAI`)
102
- - `VECTARA_AGENTIC_MAIN_LLM_PROVIDER`: valid values are `OPENAI`, `ANTHROPIC`, `TOGETHER`, `GROQ`, `COHERE` or `FIREWORKS` (default: `OPENAI`)
104
+ - `VECTARA_AGENTIC_MAIN_LLM_PROVIDER`: valid values are `OPENAI`, `ANTHROPIC`, `TOGETHER`, `GROQ`, `COHERE`, `GEMINI` or `FIREWORKS` (default: `OPENAI`)
103
105
  - `VECTARA_AGENTIC_MAIN_MODEL_NAME`: agent model name (default depends on provider)
104
106
  - `VECTARA_AGENTIC_TOOL_LLM_PROVIDER`: tool LLM provider (default: `OPENAI`)
105
107
  - `VECTARA_AGENTIC_TOOL_MODEL_NAME`: tool model name (default depends on provider)
@@ -142,16 +144,27 @@ The `Agent` class defines a few helpful methods to help you understand the inter
142
144
  * The `report()` method prints out the agent object’s type, the tools, and the LLMs used for the main agent and tool calling.
143
145
  * The `token_counts()` method tells you how many tokens you have used in the current session for both the main agent and tool calling LLMs. This can be helpful if you want to track spend by token.
144
146
 
147
+ ## Serialization
148
+
149
+ The `Agent` class supports serialization. Use the `dumps()` to serialize and `loads()` to read back from a serialized stream.
150
+
145
151
  ## Observability
146
152
 
147
153
  vectara-agentic supports observability via the existing integration of LlamaIndex and Arize Phoenix.
148
- To enable tracing of your vectara-agentic assistant, follow these steps (adapted from [here](https://docs.llamaindex.ai/en/stable/module_guides/observability/)):
149
- 1. Go to `https://llamatrace.com/login` an create an account, then create an API key and put it in the `PHOENIX_API_KEY` variable
150
- 2. `os["VECTARA_AGENTIC_OBSERVER_TYPE"] = "ARIZE_PHOENIX"`: to enable Arize Phoenix observability
151
- 3. `os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"api_key={PHOENIX_API_KEY}"`
154
+ First, set `os["VECTARA_AGENTIC_OBSERVER_TYPE"] = "ARIZE_PHOENIX"`.
155
+ Then you can use Arize Phoenix in three ways:
156
+ 1. **Locally**.
157
+ 1. If you have a local phoenix server that you've run using e.g. `python -m phoenix.server.main serve`, vectara-agentic will send all traces to it.
158
+ 2. If not, vectara-agentic will run a local instance during the agent's lifecycle, and will close it when finished.
159
+ 3. In both cases, traces will be sent to the local instance, and you can see the dashboard at `http://localhost:6006`
160
+ 2. **Hosted Instance**. In this case the traces are sent to the Phoenix instances hosted on Arize.
161
+ 1. Go to `https://app.phoenix.arize.com`, setup an account if you don't have one.
162
+ 2. create an API key and put it in the `PHOENIX_API_KEY` variable. This variable indicates you want to use the hosted version.
163
+ 3. To view the traces go to `https://app.phoenix.arize.com`.
164
+
165
+ Now when you run your agent, all call traces are sent to Phoenix and recorded.
166
+ In addition, vectara-agentic also records `FCS` values into Arize for every Vectara RAG call. You can see those results in the `Feedback` column of the arize UI.
152
167
 
153
- Now when you run your agent, all metrics are sent to LlamaTrace and recorded. You can view them at `https://llamatrace.com`.
154
- If you do not include the `OTEL_EXPORTER_OTLP_HEADERS` a local instance of Arize Phoenix will be setup instead and you can view it at `http://localhost:6006`
155
168
 
156
169
  ## About Custom Instructions
157
170
 
@@ -1,21 +1,25 @@
1
- llama-index==0.11.10
1
+ llama-index==0.11.13
2
2
  llama-index-indices-managed-vectara==0.2.2
3
3
  llama-index-agent-llm-compiler==0.2.0
4
- llama-index-agent-openai==0.3.1
5
- llama-index-llms-openai==0.2.7
4
+ llama-index-agent-openai==0.3.4
5
+ llama-index-llms-openai==0.2.9
6
6
  llama-index-llms-anthropic==0.3.1
7
7
  llama-index-llms-together==0.2.0
8
8
  llama-index-llms-groq==0.2.0
9
9
  llama-index-llms-fireworks==0.2.0
10
10
  llama-index-llms-cohere==0.3.0
11
+ llama-index-llms-gemini==0.3.5
11
12
  llama-index-tools-yahoo-finance==0.2.0
12
13
  llama-index-tools-arxiv==0.2.0
13
14
  llama-index-tools-database==0.2.0
14
15
  llama-index-tools-google==0.2.0
15
16
  llama-index-tools-tavily_research==0.2.0
16
- llama-index-callbacks-arize-phoenix==0.2.1
17
- pydantic==2.8.2
17
+ openinference-instrumentation-llama-index==3.0.2
18
+ opentelemetry-proto==1.16.0
19
+ arize-phoenix-otel==0.5.1
20
+ pydantic==2.9.2
18
21
  retrying==1.3.4
19
- pymongo==4.6.1
22
+ pymongo==4.6.3
20
23
  python-dotenv==1.0.1
21
24
  tiktoken==0.7.0
25
+ dill==0.3.8
@@ -8,7 +8,7 @@ def read_requirements():
8
8
 
9
9
  setup(
10
10
  name="vectara_agentic",
11
- version="0.1.9",
11
+ version="0.1.11",
12
12
  author="Ofer Mendelevitch",
13
13
  author_email="ofer@vectara.com",
14
14
  description="A Python package for creating AI Assistants and AI Agents with Vectara",
@@ -56,6 +56,20 @@ class TestAgentPackage(unittest.TestCase):
56
56
  self.assertIsInstance(agent, Agent)
57
57
  self.assertEqual(agent._topic, "question answering")
58
58
 
59
+ def test_serialization(self):
60
+ agent = Agent.from_corpus(
61
+ tool_name="RAG Tool",
62
+ vectara_customer_id="4584783",
63
+ vectara_corpus_id="4",
64
+ vectara_api_key="api_key",
65
+ data_description="information",
66
+ assistant_specialty="question answering",
67
+ )
68
+
69
+ agent_reloaded = agent.loads(agent.dumps())
70
+ self.assertIsInstance(agent_reloaded, Agent)
71
+ self.assertEqual(agent, agent_reloaded)
72
+
59
73
 
60
74
  if __name__ == "__main__":
61
75
  unittest.main()
@@ -1,6 +1,7 @@
1
1
  import unittest
2
2
 
3
3
  from vectara_agentic.tools import VectaraTool, VectaraToolFactory, ToolsFactory, ToolType
4
+ from vectara_agentic.agent import Agent
4
5
  from pydantic import Field, BaseModel
5
6
  from llama_index.core.tools import FunctionTool
6
7
 
@@ -57,6 +58,25 @@ class TestToolsPackage(unittest.TestCase):
57
58
  self.assertIsInstance(arxiv_tool, FunctionTool)
58
59
  self.assertEqual(arxiv_tool.tool_type, ToolType.QUERY)
59
60
 
61
+ def test_public_repo(self):
62
+ vectara_customer_id = "1366999410"
63
+ vectara_corpus_id = "1"
64
+ vectara_api_key = "zqt_UXrBcnI2UXINZkrv4g1tQPhzj02vfdtqYJIDiA"
65
+
66
+ class QueryToolArgs(BaseModel):
67
+ query: str = Field(description="The user query")
68
+
69
+ agent = Agent.from_corpus(
70
+ vectara_customer_id=vectara_customer_id,
71
+ vectara_corpus_id=vectara_corpus_id,
72
+ vectara_api_key=vectara_api_key,
73
+ tool_name="ask_vectara",
74
+ data_description="data from Vectara website",
75
+ assistant_specialty="RAG as a service",
76
+ vectara_summarizer="mockingbird-1.0-2024-07-16"
77
+ )
78
+
79
+ self.assertContains(agent.chat("What is Vectara?"), "Vectara is an end-to-end platform")
60
80
 
61
81
  if __name__ == "__main__":
62
82
  unittest.main()
@@ -3,7 +3,7 @@ vectara_agentic package.
3
3
  """
4
4
 
5
5
  # Define the package version
6
- __version__ = "0.1.9"
6
+ __version__ = "0.1.11"
7
7
 
8
8
  # Import classes and functions from modules
9
9
  # from .module1 import Class1, function1
@@ -0,0 +1,83 @@
1
+ import os
2
+ import json
3
+ import pandas as pd
4
+
5
+ from phoenix.otel import register
6
+ import phoenix as px
7
+ from openinference.instrumentation.llama_index import LlamaIndexInstrumentor
8
+ from phoenix.trace.dsl import SpanQuery
9
+ from phoenix.trace import SpanEvaluations
10
+
11
+ from .types import ObserverType
12
+
13
+ def setup_observer():
14
+ observer = ObserverType(os.getenv("VECTARA_AGENTIC_OBSERVER_TYPE", "NO_OBSERVER"))
15
+ if observer == ObserverType.ARIZE_PHOENIX:
16
+ phoenix_endpoint = os.getenv("PHOENIX_ENDPOINT", None)
17
+ if not phoenix_endpoint:
18
+ px.launch_app()
19
+ tracer_provider = register(endpoint='http://localhost:6006', project_name="vectara-agentic")
20
+ elif 'app.phoenix.arize.com' in phoenix_endpoint: # hosted on Arizze
21
+ phoenix_api_key = os.getenv("PHOENIX_API_KEY", None)
22
+ if not phoenix_api_key:
23
+ raise Exception("Arize Phoenix API key not set. Please set PHOENIX_API_KEY environment variable.")
24
+ os.environ["PHOENIX_CLIENT_HEADERS"] = f"api_key={phoenix_api_key}"
25
+ os.environ["PHOENIX_COLLECTOR_ENDPOINT"] = "https://app.phoenix.arize.com"
26
+ tracer_provider = register(endpoint=phoenix_endpoint, project_name="vectara-agentic")
27
+ else: # Self hosted Phoenix
28
+ tracer_provider = register(endpoint=phoenix_endpoint, project_name="vectara-agentic")
29
+ LlamaIndexInstrumentor().instrument(tracer_provider=tracer_provider)
30
+ else:
31
+ print("No observer set.")
32
+
33
+
34
+ def _extract_fcs_value(output):
35
+ try:
36
+ output_json = json.loads(output)
37
+ if 'metadata' in output_json and 'fcs' in output_json['metadata']:
38
+ return output_json['metadata']['fcs']
39
+ except json.JSONDecodeError:
40
+ print(f"Failed to parse JSON: {output}")
41
+ except KeyError:
42
+ print(f"'fcs' not found in: {output_json}")
43
+ return None
44
+
45
+ def _find_top_level_parent_id(row, all_spans):
46
+ current_id = row['parent_id']
47
+ while current_id is not None:
48
+ parent_row = all_spans[all_spans.index == current_id]
49
+ if parent_row.empty:
50
+ break
51
+ new_parent_id = parent_row['parent_id'].iloc[0]
52
+ if new_parent_id == current_id:
53
+ break
54
+ if new_parent_id is None:
55
+ return current_id
56
+ current_id = new_parent_id
57
+ return current_id
58
+
59
+ def eval_fcs():
60
+ query = SpanQuery().select(
61
+ "output.value",
62
+ "parent_id",
63
+ "name"
64
+ )
65
+ client = px.Client()
66
+ all_spans = client.query_spans(query, project_name="vectara-agentic")
67
+
68
+ vectara_spans = all_spans[all_spans['name'] == 'VectaraQueryEngine._query']
69
+ vectara_spans['top_level_parent_id'] = vectara_spans.apply(lambda row: _find_top_level_parent_id(row, all_spans), axis=1)
70
+ vectara_spans['score'] = vectara_spans['output.value'].apply(lambda x: _extract_fcs_value(x))
71
+
72
+ vectara_spans.reset_index(inplace=True)
73
+ top_level_spans = vectara_spans.copy()
74
+ top_level_spans['context.span_id'] = top_level_spans['top_level_parent_id']
75
+ vectara_spans = pd.concat([vectara_spans, top_level_spans], ignore_index=True)
76
+ vectara_spans.set_index('context.span_id', inplace=True)
77
+
78
+ px.Client().log_evaluations(
79
+ SpanEvaluations(
80
+ dataframe=vectara_spans,
81
+ eval_name="Vectara FCS",
82
+ ),
83
+ )
@@ -1,10 +1,12 @@
1
1
  """
2
2
  This module contains the Agent class for handling different types of agents and their interactions.
3
3
  """
4
- from typing import List, Callable, Optional
4
+ from typing import List, Callable, Optional, Dict, Any
5
5
  import os
6
6
  from datetime import date
7
7
  import time
8
+ import json
9
+ import dill
8
10
 
9
11
  import logging
10
12
  logger = logging.getLogger('opentelemetry.exporter.otlp.proto.http.trace_exporter')
@@ -21,17 +23,16 @@ from llama_index.core.callbacks import CallbackManager, TokenCountingHandler
21
23
  from llama_index.core.callbacks.base_handler import BaseCallbackHandler
22
24
  from llama_index.agent.openai import OpenAIAgent
23
25
  from llama_index.core.memory import ChatMemoryBuffer
24
- from llama_index.core import set_global_handler
25
-
26
- import phoenix as px
27
26
 
28
27
  from dotenv import load_dotenv
29
28
 
30
- from .types import AgentType, AgentStatusType, LLMRole, ObserverType
29
+ from .types import AgentType, AgentStatusType, LLMRole, ToolType
31
30
  from .utils import get_llm, get_tokenizer_for_model
32
31
  from ._prompts import REACT_PROMPT_TEMPLATE, GENERAL_PROMPT_TEMPLATE
33
32
  from ._callback import AgentCallbackHandler
34
- from .tools import VectaraToolFactory
33
+ from ._observability import setup_observer, eval_fcs
34
+ from .tools import VectaraToolFactory, VectaraTool
35
+
35
36
 
36
37
  load_dotenv(override=True)
37
38
 
@@ -67,7 +68,6 @@ class Agent:
67
68
  """
68
69
  Agent class for handling different types of agents and their interactions.
69
70
  """
70
-
71
71
  def __init__(
72
72
  self,
73
73
  tools: list[FunctionTool],
@@ -75,6 +75,7 @@ class Agent:
75
75
  custom_instructions: str = "",
76
76
  verbose: bool = True,
77
77
  update_func: Optional[Callable[[AgentStatusType, str], None]] = None,
78
+ agent_type: AgentType = None,
78
79
  ) -> None:
79
80
  """
80
81
  Initialize the agent with the specified type, tools, topic, and system message.
@@ -87,7 +88,7 @@ class Agent:
87
88
  verbose (bool, optional): Whether the agent should print its steps. Defaults to True.
88
89
  update_func (Callable): A callback function the code calls on any agent updates.
89
90
  """
90
- self.agent_type = AgentType(os.getenv("VECTARA_AGENTIC_AGENT_TYPE", "OPENAI"))
91
+ self.agent_type = agent_type or AgentType(os.getenv("VECTARA_AGENTIC_AGENT_TYPE", "OPENAI"))
91
92
  self.tools = tools
92
93
  self.llm = get_llm(LLMRole.MAIN)
93
94
  self._custom_instructions = custom_instructions
@@ -140,17 +141,49 @@ class Agent:
140
141
  else:
141
142
  raise ValueError(f"Unknown agent type: {self.agent_type}")
142
143
 
143
- observer = ObserverType(os.getenv("VECTARA_AGENTIC_OBSERVER_TYPE", "NO_OBSERVER"))
144
- if observer == ObserverType.ARIZE_PHOENIX:
145
- if os.environ.get("OTEL_EXPORTER_OTLP_HEADERS", None):
146
- set_global_handler("arize_phoenix", endpoint="https://llamatrace.com/v1/traces")
147
- print("Arize Phoenix observer set. https://llamatrace.com")
148
- else:
149
- px.launch_app()
150
- set_global_handler("arize_phoenix", endpoint="http://localhost:6006/v1/traces")
151
- print("Arize Phoenix observer set. http://localhost:6006/.")
152
- else:
153
- print("No observer set.")
144
+ try:
145
+ setup_observer()
146
+ except Exception as e:
147
+ print(f"Failed to set up observer ({e}), ignoring")
148
+
149
+ def __eq__(self, other):
150
+ if not isinstance(other, Agent):
151
+ print(f"Comparison failed: other is not an instance of Agent. (self: {type(self)}, other: {type(other)})")
152
+ return False
153
+
154
+ # Compare agent_type
155
+ if self.agent_type != other.agent_type:
156
+ print(f"Comparison failed: agent_type differs. (self.agent_type: {self.agent_type}, other.agent_type: {other.agent_type})")
157
+ return False
158
+
159
+ # Compare tools
160
+ if self.tools != other.tools:
161
+ print(f"Comparison failed: tools differ. (self.tools: {self.tools}, other.tools: {other.tools})")
162
+ return False
163
+
164
+ # Compare topic
165
+ if self._topic != other._topic:
166
+ print(f"Comparison failed: topic differs. (self.topic: {self._topic}, other.topic: {other._topic})")
167
+ return False
168
+
169
+ # Compare custom_instructions
170
+ if self._custom_instructions != other._custom_instructions:
171
+ print(f"Comparison failed: custom_instructions differ. (self.custom_instructions: {self._custom_instructions}, other.custom_instructions: {other._custom_instructions})")
172
+ return False
173
+
174
+ # Compare verbose
175
+ if self.verbose != other.verbose:
176
+ print(f"Comparison failed: verbose differs. (self.verbose: {self.verbose}, other.verbose: {other.verbose})")
177
+ return False
178
+
179
+ # Compare agent
180
+ if self.agent.memory.chat_store != other.agent.memory.chat_store:
181
+ print(f"Comparison failed: agent memory differs. (self.agent: {repr(self.agent.memory.chat_store)}, other.agent: {repr(other.agent.memory.chat_store)})")
182
+ return False
183
+
184
+ # If all comparisons pass
185
+ print("All comparisons passed. Objects are equal.")
186
+ return True
154
187
 
155
188
  @classmethod
156
189
  def from_tools(
@@ -160,6 +193,7 @@ class Agent:
160
193
  custom_instructions: str = "",
161
194
  verbose: bool = True,
162
195
  update_func: Optional[Callable[[AgentStatusType, str], None]] = None,
196
+ agent_type: AgentType = None,
163
197
  ) -> "Agent":
164
198
  """
165
199
  Create an agent from tools, agent type, and language model.
@@ -176,7 +210,7 @@ class Agent:
176
210
  Returns:
177
211
  Agent: An instance of the Agent class.
178
212
  """
179
- return cls(tools, topic, custom_instructions, verbose, update_func)
213
+ return cls(tools, topic, custom_instructions, verbose, update_func, agent_type)
180
214
 
181
215
  @classmethod
182
216
  def from_corpus(
@@ -203,12 +237,12 @@ class Agent:
203
237
  Args:
204
238
  tool_name (str): The name of Vectara tool used by the agent
205
239
  vectara_customer_id (str): The Vectara customer ID.
206
- vectara_corpus_id (str): The Vectara corpus ID.
240
+ vectara_corpus_id (str): The Vectara corpus ID (or comma separated list of IDs).
207
241
  vectara_api_key (str): The Vectara API key.
208
242
  data_description (str): The description of the data.
209
243
  assistant_specialty (str): The specialty of the assistant.
210
244
  verbose (bool, optional): Whether to print verbose output.
211
- vectara_filter_fields (List[dict], optional): The filterable attributes (each dict includes name, type, and description).
245
+ vectara_filter_fields (List[dict], optional): The filterable attributes (each dict maps field name to Tuple[type, description]).
212
246
  vectara_lambda_val (float, optional): The lambda value for Vectara hybrid search.
213
247
  vectara_reranker (str, optional): The Vectara reranker name (default "mmr")
214
248
  vectara_rerank_k (int, optional): The number of results to use with reranking.
@@ -224,9 +258,10 @@ class Agent:
224
258
  vectara_customer_id=vectara_customer_id,
225
259
  vectara_corpus_id=vectara_corpus_id)
226
260
  field_definitions = {}
227
- field_definitions['query'] = (str, Field(description="The user query"))
261
+ field_definitions['query'] = (str, Field(description="The user query")) # type: ignore
228
262
  for field in vectara_filter_fields:
229
- field_definitions[field['name']] = (eval(field['type']), Field(description=field['description'], default=None)) # type: ignore
263
+ field_definitions[field['name']] = (eval(field['type']),
264
+ Field(description=field['description'])) # type: ignore
230
265
  QueryArgs = create_model( # type: ignore
231
266
  "QueryArgs",
232
267
  **field_definitions
@@ -311,7 +346,126 @@ class Agent:
311
346
  agent_response = self.agent.chat(prompt)
312
347
  if self.verbose:
313
348
  print(f"Time taken: {time.time() - st}")
349
+ eval_fcs()
314
350
  return agent_response.response
315
351
  except Exception as e:
316
352
  import traceback
317
353
  return f"Vectara Agentic: encountered an exception ({e}) at ({traceback.format_exc()}), and can't respond."
354
+
355
+ # Serialization methods
356
+
357
+ def to_dict(self) -> Dict[str, Any]:
358
+ """Serialize the Agent instance to a dictionary."""
359
+ tool_info = []
360
+
361
+ for tool in self.tools:
362
+ tool_dict = {
363
+ "tool_type": tool.tool_type.value,
364
+ "name": tool._metadata.name,
365
+ "description": tool._metadata.description,
366
+ "fn": dill.dumps(tool.fn).decode('latin-1') if tool.fn else None, # Serialize fn
367
+ "async_fn": dill.dumps(tool.async_fn).decode('latin-1') if tool.async_fn else None, # Serialize async_fn
368
+ }
369
+ tool_info.append(tool_dict)
370
+
371
+ return {
372
+ "agent_type": self.agent_type.value,
373
+ "tools": tool_info,
374
+ "topic": self._topic,
375
+ "custom_instructions": self._custom_instructions,
376
+ "verbose": self.verbose,
377
+ }
378
+
379
+
380
+ def dumps(self) -> str:
381
+ """Serialize the Agent instance to a JSON string."""
382
+ return json.dumps(self.to_dict())
383
+
384
+ @classmethod
385
+ def loads(cls, data: str) -> "Agent":
386
+ """Create an Agent instance from a JSON string."""
387
+ return cls.from_dict(json.loads(data))
388
+
389
+
390
+ def to_dict(self) -> Dict[str, Any]:
391
+ """Serialize the Agent instance to a dictionary."""
392
+ tool_info = []
393
+
394
+ for tool in self.tools:
395
+ # Serialize each tool's metadata, function, and dynamic model schema (QueryArgs)
396
+ tool_dict = {
397
+ "tool_type": tool.tool_type.value,
398
+ "name": tool._metadata.name,
399
+ "description": tool._metadata.description,
400
+ "fn": dill.dumps(tool.fn).decode('latin-1') if tool.fn else None, # Serialize fn
401
+ "async_fn": dill.dumps(tool.async_fn).decode('latin-1') if tool.async_fn else None, # Serialize async_fn
402
+ "fn_schema": tool._metadata.fn_schema.model_json_schema() if hasattr(tool._metadata, 'fn_schema') else None, # Serialize schema if available
403
+ }
404
+ tool_info.append(tool_dict)
405
+
406
+ return {
407
+ "agent_type": self.agent_type.value,
408
+ "memory": dill.dumps(self.agent.memory).decode('latin-1'),
409
+ "tools": tool_info,
410
+ "topic": self._topic,
411
+ "custom_instructions": self._custom_instructions,
412
+ "verbose": self.verbose,
413
+ }
414
+
415
+ @classmethod
416
+ def from_dict(cls, data: Dict[str, Any]) -> "Agent":
417
+ """Create an Agent instance from a dictionary."""
418
+ agent_type = AgentType(data["agent_type"])
419
+ tools = []
420
+
421
+ JSON_TYPE_TO_PYTHON = {
422
+ "string": "str",
423
+ "integer": "int",
424
+ "boolean": "bool",
425
+ "array": "list",
426
+ "object": "dict",
427
+ "number": "float",
428
+ }
429
+
430
+ for tool_data in data["tools"]:
431
+ # Recreate the dynamic model using the schema info
432
+ if tool_data.get("fn_schema"):
433
+ field_definitions = {}
434
+ for field,values in tool_data["fn_schema"]["properties"].items():
435
+ if 'default' in values:
436
+ field_definitions[field] = (eval(JSON_TYPE_TO_PYTHON.get(values['type'], values['type'])),
437
+ Field(description=values['description'], default=values['default'])) # type: ignore
438
+ else:
439
+ field_definitions[field] = (eval(JSON_TYPE_TO_PYTHON.get(values['type'], values['type'])),
440
+ Field(description=values['description'])) # type: ignore
441
+ query_args_model = create_model( # type: ignore
442
+ "QueryArgs",
443
+ **field_definitions
444
+ )
445
+ else:
446
+ query_args_model = create_model("QueryArgs")
447
+
448
+ fn = dill.loads(tool_data["fn"].encode('latin-1')) if tool_data["fn"] else None
449
+ async_fn = dill.loads(tool_data["async_fn"].encode('latin-1')) if tool_data["async_fn"] else None
450
+
451
+ tool = VectaraTool.from_defaults(
452
+ tool_type=ToolType(tool_data["tool_type"]),
453
+ name=tool_data["name"],
454
+ description=tool_data["description"],
455
+ fn=fn,
456
+ async_fn=async_fn,
457
+ fn_schema=query_args_model # Re-assign the recreated dynamic model
458
+ )
459
+ tools.append(tool)
460
+
461
+ agent = cls(
462
+ tools=tools,
463
+ agent_type=agent_type,
464
+ topic=data["topic"],
465
+ custom_instructions=data["custom_instructions"],
466
+ verbose=data["verbose"],
467
+ )
468
+ memory = dill.loads(data["memory"].encode('latin-1')) if data.get("memory") else None
469
+ if memory:
470
+ agent.agent.memory = memory
471
+ return agent
@@ -81,12 +81,31 @@ class VectaraTool(FunctionTool):
81
81
  tool = FunctionTool.from_defaults(fn, name, description, return_direct, fn_schema, async_fn, tool_metadata)
82
82
  vectara_tool = cls(
83
83
  tool_type=tool_type,
84
- fn=tool.fn,
85
- metadata=tool.metadata,
86
- async_fn=tool.async_fn
84
+ fn=tool._fn,
85
+ metadata=tool._metadata,
86
+ async_fn=tool._async_fn
87
87
  )
88
88
  return vectara_tool
89
89
 
90
+ def __eq__(self, other):
91
+ if self.tool_type != other.tool_type:
92
+ return False
93
+
94
+ # Check if fn_schema is an instance of a BaseModel or a class itself (metaclass)
95
+ self_schema_dict = self.metadata.fn_schema.model_fields
96
+ other_schema_dict = other.metadata.fn_schema.model_fields
97
+ is_equal = True
98
+ for key in self_schema_dict.keys():
99
+ if key not in other_schema_dict:
100
+ is_equal = False
101
+ break
102
+ if (self_schema_dict[key].annotation != other_schema_dict[key].annotation or
103
+ self_schema_dict[key].description != other_schema_dict[key].description or
104
+ self_schema_dict[key].is_required() != other_schema_dict[key].is_required()):
105
+ is_equal = False
106
+ break
107
+ return is_equal
108
+
90
109
 
91
110
  class VectaraToolFactory:
92
111
  """
@@ -103,12 +122,13 @@ class VectaraToolFactory:
103
122
  Initialize the VectaraToolFactory
104
123
  Args:
105
124
  vectara_customer_id (str): The Vectara customer ID.
106
- vectara_corpus_id (str): The Vectara corpus ID.
125
+ vectara_corpus_id (str): The Vectara corpus ID (or comma separated list of IDs).
107
126
  vectara_api_key (str): The Vectara API key.
108
127
  """
109
128
  self.vectara_customer_id = vectara_customer_id
110
129
  self.vectara_corpus_id = vectara_corpus_id
111
130
  self.vectara_api_key = vectara_api_key
131
+ self.num_corpora = len(vectara_corpus_id.split(","))
112
132
 
113
133
  def create_rag_tool(
114
134
  self,
@@ -188,7 +208,7 @@ class VectaraToolFactory:
188
208
  summary_response_lang=summary_response_lang,
189
209
  summary_prompt_name=vectara_summarizer,
190
210
  reranker=reranker,
191
- rerank_k=rerank_k,
211
+ rerank_k=rerank_k if rerank_k*self.num_corpora<=100 else int(100/self.num_corpora),
192
212
  mmr_diversity_bias=mmr_diversity_bias,
193
213
  n_sentence_before=n_sentences_before,
194
214
  n_sentence_after=n_sentences_after,
@@ -255,7 +275,7 @@ class VectaraToolFactory:
255
275
  )
256
276
  return out
257
277
 
258
- fields = tool_args_schema.__fields__
278
+ fields = tool_args_schema.model_fields
259
279
  params = [
260
280
  inspect.Parameter(
261
281
  name=field_name,
@@ -28,6 +28,7 @@ class ModelProvider(Enum):
28
28
  GROQ = "GROQ"
29
29
  FIREWORKS = "FIREWORKS"
30
30
  COHERE = "COHERE"
31
+ GEMINI = "GEMINI"
31
32
 
32
33
 
33
34
  class AgentStatusType(Enum):
@@ -11,6 +11,7 @@ from llama_index.llms.together import TogetherLLM
11
11
  from llama_index.llms.groq import Groq
12
12
  from llama_index.llms.fireworks import Fireworks
13
13
  from llama_index.llms.cohere import Cohere
14
+ from llama_index.llms.gemini import Gemini
14
15
 
15
16
  import tiktoken
16
17
  from typing import Tuple, Callable, Optional
@@ -24,6 +25,7 @@ provider_to_default_model_name = {
24
25
  ModelProvider.GROQ: "llama-3.1-70b-versatile",
25
26
  ModelProvider.FIREWORKS: "accounts/fireworks/models/firefunction-v2",
26
27
  ModelProvider.COHERE: "command-r-plus",
28
+ ModelProvider.GEMINI: "models/gemini-pro",
27
29
  }
28
30
 
29
31
  DEFAULT_MODEL_PROVIDER = ModelProvider.OPENAI
@@ -77,17 +79,19 @@ def get_llm(role: LLMRole) -> LLM:
77
79
  model_provider, model_name = _get_llm_params_for_role(role)
78
80
 
79
81
  if model_provider == ModelProvider.OPENAI:
80
- llm = OpenAI(model=model_name, temperature=0)
82
+ llm = OpenAI(model=model_name, temperature=0, is_function_calling_model=True)
81
83
  elif model_provider == ModelProvider.ANTHROPIC:
82
- llm = Anthropic(model=model_name, temperature=0)
84
+ llm = Anthropic(model=model_name, temperature=0, is_function_calling_model=True)
85
+ elif model_provider == ModelProvider.GEMINI:
86
+ llm = Gemini(model=model_name, temperature=0, is_function_calling_model=True)
83
87
  elif model_provider == ModelProvider.TOGETHER:
84
- llm = TogetherLLM(model=model_name, temperature=0)
88
+ llm = TogetherLLM(model=model_name, temperature=0, is_function_calling_model=True)
85
89
  elif model_provider == ModelProvider.GROQ:
86
- llm = Groq(model=model_name, temperature=0)
90
+ llm = Groq(model=model_name, temperature=0, is_function_calling_model=True)
87
91
  elif model_provider == ModelProvider.FIREWORKS:
88
- llm = Fireworks(model=model_name, temperature=0)
92
+ llm = Fireworks(model=model_name, temperature=0, is_function_calling_model=True)
89
93
  elif model_provider == ModelProvider.COHERE:
90
- llm = Cohere(model=model_name, temperature=0)
94
+ llm = Cohere(model=model_name, temperature=0, is_function_calling_model=True)
91
95
  else:
92
96
  raise ValueError(f"Unknown LLM provider: {model_provider}")
93
97
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vectara_agentic
3
- Version: 0.1.9
3
+ Version: 0.1.11
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,27 +16,31 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
16
  Requires-Python: >=3.10
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: llama-index==0.11.10
19
+ Requires-Dist: llama-index==0.11.13
20
20
  Requires-Dist: llama-index-indices-managed-vectara==0.2.2
21
21
  Requires-Dist: llama-index-agent-llm-compiler==0.2.0
22
- Requires-Dist: llama-index-agent-openai==0.3.1
23
- Requires-Dist: llama-index-llms-openai==0.2.7
22
+ Requires-Dist: llama-index-agent-openai==0.3.4
23
+ Requires-Dist: llama-index-llms-openai==0.2.9
24
24
  Requires-Dist: llama-index-llms-anthropic==0.3.1
25
25
  Requires-Dist: llama-index-llms-together==0.2.0
26
26
  Requires-Dist: llama-index-llms-groq==0.2.0
27
27
  Requires-Dist: llama-index-llms-fireworks==0.2.0
28
28
  Requires-Dist: llama-index-llms-cohere==0.3.0
29
+ Requires-Dist: llama-index-llms-gemini==0.3.5
29
30
  Requires-Dist: llama-index-tools-yahoo-finance==0.2.0
30
31
  Requires-Dist: llama-index-tools-arxiv==0.2.0
31
32
  Requires-Dist: llama-index-tools-database==0.2.0
32
33
  Requires-Dist: llama-index-tools-google==0.2.0
33
34
  Requires-Dist: llama-index-tools-tavily_research==0.2.0
34
- Requires-Dist: llama-index-callbacks-arize-phoenix==0.2.1
35
- Requires-Dist: pydantic==2.8.2
35
+ Requires-Dist: openinference-instrumentation-llama-index==3.0.2
36
+ Requires-Dist: opentelemetry-proto==1.16.0
37
+ Requires-Dist: arize-phoenix-otel==0.5.1
38
+ Requires-Dist: pydantic==2.9.2
36
39
  Requires-Dist: retrying==1.3.4
37
- Requires-Dist: pymongo==4.6.1
40
+ Requires-Dist: pymongo==4.6.3
38
41
  Requires-Dist: python-dotenv==1.0.1
39
42
  Requires-Dist: tiktoken==0.7.0
43
+ Requires-Dist: dill==0.3.8
40
44
 
41
45
  # vectara-agentic
42
46
 
@@ -64,7 +68,7 @@ Requires-Dist: tiktoken==0.7.0
64
68
  - [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)
65
69
  - A Vectara corpus with an [API key](https://docs.vectara.com/docs/api-keys)
66
70
  - [Python 3.10 or higher](https://www.python.org/downloads/)
67
- - OpenAI API key (or API keys for Anthropic, TOGETHER.AI, Fireworks AI, Cohere or GROQ)
71
+ - OpenAI API key (or API keys for Anthropic, TOGETHER.AI, Fireworks AI, Cohere, GEMINI or GROQ)
68
72
 
69
73
  ## Installation
70
74
 
@@ -98,6 +102,8 @@ query_financial_reports = vec_factory.create_rag_tool(
98
102
  )
99
103
  ```
100
104
 
105
+ Note that `VECTARA_CORPUS_ID` can be a single ID or a comma-separated list of IDs.
106
+
101
107
  2. **Create other tools (optional)**
102
108
 
103
109
  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
@@ -139,7 +145,7 @@ financial_bot_instructions = """
139
145
  Configure `vectara-agentic` using environment variables:
140
146
 
141
147
  - `VECTARA_AGENTIC_AGENT_TYPE`: valid values are `REACT`, `LLMCOMPILER` or `OPENAI` (default: `OPENAI`)
142
- - `VECTARA_AGENTIC_MAIN_LLM_PROVIDER`: valid values are `OPENAI`, `ANTHROPIC`, `TOGETHER`, `GROQ`, `COHERE` or `FIREWORKS` (default: `OPENAI`)
148
+ - `VECTARA_AGENTIC_MAIN_LLM_PROVIDER`: valid values are `OPENAI`, `ANTHROPIC`, `TOGETHER`, `GROQ`, `COHERE`, `GEMINI` or `FIREWORKS` (default: `OPENAI`)
143
149
  - `VECTARA_AGENTIC_MAIN_MODEL_NAME`: agent model name (default depends on provider)
144
150
  - `VECTARA_AGENTIC_TOOL_LLM_PROVIDER`: tool LLM provider (default: `OPENAI`)
145
151
  - `VECTARA_AGENTIC_TOOL_MODEL_NAME`: tool model name (default depends on provider)
@@ -182,16 +188,27 @@ The `Agent` class defines a few helpful methods to help you understand the inter
182
188
  * The `report()` method prints out the agent object’s type, the tools, and the LLMs used for the main agent and tool calling.
183
189
  * The `token_counts()` method tells you how many tokens you have used in the current session for both the main agent and tool calling LLMs. This can be helpful if you want to track spend by token.
184
190
 
191
+ ## Serialization
192
+
193
+ The `Agent` class supports serialization. Use the `dumps()` to serialize and `loads()` to read back from a serialized stream.
194
+
185
195
  ## Observability
186
196
 
187
197
  vectara-agentic supports observability via the existing integration of LlamaIndex and Arize Phoenix.
188
- To enable tracing of your vectara-agentic assistant, follow these steps (adapted from [here](https://docs.llamaindex.ai/en/stable/module_guides/observability/)):
189
- 1. Go to `https://llamatrace.com/login` an create an account, then create an API key and put it in the `PHOENIX_API_KEY` variable
190
- 2. `os["VECTARA_AGENTIC_OBSERVER_TYPE"] = "ARIZE_PHOENIX"`: to enable Arize Phoenix observability
191
- 3. `os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"api_key={PHOENIX_API_KEY}"`
198
+ First, set `os["VECTARA_AGENTIC_OBSERVER_TYPE"] = "ARIZE_PHOENIX"`.
199
+ Then you can use Arize Phoenix in three ways:
200
+ 1. **Locally**.
201
+ 1. If you have a local phoenix server that you've run using e.g. `python -m phoenix.server.main serve`, vectara-agentic will send all traces to it.
202
+ 2. If not, vectara-agentic will run a local instance during the agent's lifecycle, and will close it when finished.
203
+ 3. In both cases, traces will be sent to the local instance, and you can see the dashboard at `http://localhost:6006`
204
+ 2. **Hosted Instance**. In this case the traces are sent to the Phoenix instances hosted on Arize.
205
+ 1. Go to `https://app.phoenix.arize.com`, setup an account if you don't have one.
206
+ 2. create an API key and put it in the `PHOENIX_API_KEY` variable. This variable indicates you want to use the hosted version.
207
+ 3. To view the traces go to `https://app.phoenix.arize.com`.
208
+
209
+ Now when you run your agent, all call traces are sent to Phoenix and recorded.
210
+ In addition, vectara-agentic also records `FCS` values into Arize for every Vectara RAG call. You can see those results in the `Feedback` column of the arize UI.
192
211
 
193
- Now when you run your agent, all metrics are sent to LlamaTrace and recorded. You can view them at `https://llamatrace.com`.
194
- If you do not include the `OTEL_EXPORTER_OTLP_HEADERS` a local instance of Arize Phoenix will be setup instead and you can view it at `http://localhost:6006`
195
212
 
196
213
  ## About Custom Instructions
197
214
 
@@ -7,6 +7,7 @@ tests/test_agent.py
7
7
  tests/test_tools.py
8
8
  vectara_agentic/__init__.py
9
9
  vectara_agentic/_callback.py
10
+ vectara_agentic/_observability.py
10
11
  vectara_agentic/_prompts.py
11
12
  vectara_agentic/agent.py
12
13
  vectara_agentic/tools.py
@@ -1,21 +1,25 @@
1
- llama-index==0.11.10
1
+ llama-index==0.11.13
2
2
  llama-index-indices-managed-vectara==0.2.2
3
3
  llama-index-agent-llm-compiler==0.2.0
4
- llama-index-agent-openai==0.3.1
5
- llama-index-llms-openai==0.2.7
4
+ llama-index-agent-openai==0.3.4
5
+ llama-index-llms-openai==0.2.9
6
6
  llama-index-llms-anthropic==0.3.1
7
7
  llama-index-llms-together==0.2.0
8
8
  llama-index-llms-groq==0.2.0
9
9
  llama-index-llms-fireworks==0.2.0
10
10
  llama-index-llms-cohere==0.3.0
11
+ llama-index-llms-gemini==0.3.5
11
12
  llama-index-tools-yahoo-finance==0.2.0
12
13
  llama-index-tools-arxiv==0.2.0
13
14
  llama-index-tools-database==0.2.0
14
15
  llama-index-tools-google==0.2.0
15
16
  llama-index-tools-tavily_research==0.2.0
16
- llama-index-callbacks-arize-phoenix==0.2.1
17
- pydantic==2.8.2
17
+ openinference-instrumentation-llama-index==3.0.2
18
+ opentelemetry-proto==1.16.0
19
+ arize-phoenix-otel==0.5.1
20
+ pydantic==2.9.2
18
21
  retrying==1.3.4
19
- pymongo==4.6.1
22
+ pymongo==4.6.3
20
23
  python-dotenv==1.0.1
21
24
  tiktoken==0.7.0
25
+ dill==0.3.8