vectara-agentic 0.3.3__py3-none-any.whl → 0.4.1__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.
- tests/__init__.py +7 -0
- tests/conftest.py +316 -0
- tests/endpoint.py +54 -17
- tests/run_tests.py +112 -0
- tests/test_agent.py +35 -33
- tests/test_agent_fallback_memory.py +270 -0
- tests/test_agent_memory_consistency.py +229 -0
- tests/test_agent_type.py +86 -143
- tests/test_api_endpoint.py +4 -0
- tests/test_bedrock.py +50 -31
- tests/test_fallback.py +4 -0
- tests/test_gemini.py +27 -59
- tests/test_groq.py +50 -31
- tests/test_private_llm.py +11 -2
- tests/test_return_direct.py +6 -2
- tests/test_serialization.py +7 -6
- tests/test_session_memory.py +252 -0
- tests/test_streaming.py +109 -0
- tests/test_together.py +62 -0
- tests/test_tools.py +10 -82
- tests/test_vectara_llms.py +4 -0
- tests/test_vhc.py +67 -0
- tests/test_workflow.py +13 -28
- vectara_agentic/__init__.py +27 -4
- vectara_agentic/_callback.py +65 -67
- vectara_agentic/_observability.py +30 -30
- vectara_agentic/_version.py +1 -1
- vectara_agentic/agent.py +565 -859
- vectara_agentic/agent_config.py +15 -14
- vectara_agentic/agent_core/__init__.py +22 -0
- vectara_agentic/agent_core/factory.py +383 -0
- vectara_agentic/{_prompts.py → agent_core/prompts.py} +21 -46
- vectara_agentic/agent_core/serialization.py +348 -0
- vectara_agentic/agent_core/streaming.py +483 -0
- vectara_agentic/agent_core/utils/__init__.py +29 -0
- vectara_agentic/agent_core/utils/hallucination.py +157 -0
- vectara_agentic/agent_core/utils/logging.py +52 -0
- vectara_agentic/agent_core/utils/schemas.py +87 -0
- vectara_agentic/agent_core/utils/tools.py +125 -0
- vectara_agentic/agent_endpoint.py +4 -6
- vectara_agentic/db_tools.py +37 -12
- vectara_agentic/llm_utils.py +42 -43
- vectara_agentic/sub_query_workflow.py +9 -14
- vectara_agentic/tool_utils.py +138 -83
- vectara_agentic/tools.py +36 -21
- vectara_agentic/tools_catalog.py +16 -16
- vectara_agentic/types.py +106 -8
- {vectara_agentic-0.3.3.dist-info → vectara_agentic-0.4.1.dist-info}/METADATA +111 -31
- vectara_agentic-0.4.1.dist-info/RECORD +53 -0
- tests/test_agent_planning.py +0 -64
- tests/test_hhem.py +0 -100
- vectara_agentic/hhem.py +0 -82
- vectara_agentic-0.3.3.dist-info/RECORD +0 -39
- {vectara_agentic-0.3.3.dist-info → vectara_agentic-0.4.1.dist-info}/WHEEL +0 -0
- {vectara_agentic-0.3.3.dist-info → vectara_agentic-0.4.1.dist-info}/licenses/LICENSE +0 -0
- {vectara_agentic-0.3.3.dist-info → vectara_agentic-0.4.1.dist-info}/top_level.txt +0 -0
vectara_agentic/tools_catalog.py
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"""
|
|
2
2
|
This module contains the tools catalog for the Vectara Agentic.
|
|
3
3
|
"""
|
|
4
|
+
|
|
4
5
|
from typing import List
|
|
5
6
|
from datetime import date
|
|
6
7
|
|
|
7
|
-
import requests
|
|
8
|
-
|
|
9
8
|
from pydantic import Field
|
|
10
9
|
|
|
11
10
|
from .types import LLMRole
|
|
@@ -13,16 +12,6 @@ from .agent_config import AgentConfig
|
|
|
13
12
|
from .llm_utils import get_llm
|
|
14
13
|
from .utils import remove_self_from_signature
|
|
15
14
|
|
|
16
|
-
req_session = requests.Session()
|
|
17
|
-
|
|
18
|
-
get_headers = {
|
|
19
|
-
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:98.0) Gecko/20100101 Firefox/98.0",
|
|
20
|
-
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
|
|
21
|
-
"Accept-Language": "en-US,en;q=0.5",
|
|
22
|
-
"Accept-Encoding": "gzip, deflate",
|
|
23
|
-
"Connection": "keep-alive",
|
|
24
|
-
}
|
|
25
|
-
|
|
26
15
|
def get_current_date() -> str:
|
|
27
16
|
"""
|
|
28
17
|
Returns the current date as a string.
|
|
@@ -35,6 +24,7 @@ class ToolsCatalog:
|
|
|
35
24
|
"""
|
|
36
25
|
A curated set of tools for vectara-agentic
|
|
37
26
|
"""
|
|
27
|
+
|
|
38
28
|
def __init__(self, agent_config: AgentConfig):
|
|
39
29
|
self.agent_config = agent_config
|
|
40
30
|
|
|
@@ -76,7 +66,9 @@ class ToolsCatalog:
|
|
|
76
66
|
def rephrase_text(
|
|
77
67
|
self,
|
|
78
68
|
text: str = Field(description="the original text."),
|
|
79
|
-
instructions: str = Field(
|
|
69
|
+
instructions: str = Field(
|
|
70
|
+
description="the specific instructions for how to rephrase the text."
|
|
71
|
+
),
|
|
80
72
|
) -> str:
|
|
81
73
|
"""
|
|
82
74
|
This is a helper tool.
|
|
@@ -103,8 +95,13 @@ class ToolsCatalog:
|
|
|
103
95
|
def critique_text(
|
|
104
96
|
self,
|
|
105
97
|
text: str = Field(description="the original text."),
|
|
106
|
-
role: str = Field(
|
|
107
|
-
|
|
98
|
+
role: str = Field(
|
|
99
|
+
default=None, description="the role of the person providing critique."
|
|
100
|
+
),
|
|
101
|
+
point_of_view: str = Field(
|
|
102
|
+
default=None,
|
|
103
|
+
description="the point of view with which to provide critique.",
|
|
104
|
+
),
|
|
108
105
|
) -> str:
|
|
109
106
|
"""
|
|
110
107
|
This is a helper tool.
|
|
@@ -121,13 +118,16 @@ class ToolsCatalog:
|
|
|
121
118
|
if role:
|
|
122
119
|
prompt = f"As a {role}, critique the provided text from the point of view of {point_of_view}."
|
|
123
120
|
else:
|
|
124
|
-
prompt =
|
|
121
|
+
prompt = (
|
|
122
|
+
f"Critique the provided text from the point of view of {point_of_view}."
|
|
123
|
+
)
|
|
125
124
|
prompt += "\nStructure the critique as bullet points.\n"
|
|
126
125
|
prompt += f"Original text: {text}\nCritique:"
|
|
127
126
|
llm = get_llm(LLMRole.TOOL, config=self.agent_config)
|
|
128
127
|
response = llm.complete(prompt)
|
|
129
128
|
return response.text
|
|
130
129
|
|
|
130
|
+
|
|
131
131
|
#
|
|
132
132
|
# Guardrails tool: returns list of topics to avoid
|
|
133
133
|
#
|
vectara_agentic/types.py
CHANGED
|
@@ -3,13 +3,13 @@ This module contains the types used in the Vectara Agentic.
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from enum import Enum
|
|
6
|
-
from typing import Protocol,
|
|
6
|
+
from typing import Any, Dict, Callable, AsyncIterator, Protocol, cast
|
|
7
|
+
from dataclasses import dataclass, field
|
|
7
8
|
|
|
8
9
|
from llama_index.core.schema import Document as LI_Document
|
|
9
10
|
from llama_index.core.tools.types import ToolOutput as LI_ToolOutput
|
|
10
|
-
from llama_index.core.chat_engine.types import AgentChatResponse as LI_AgentChatResponse
|
|
11
11
|
from llama_index.core.chat_engine.types import (
|
|
12
|
-
|
|
12
|
+
AgentChatResponse as LI_AgentChatResponse,
|
|
13
13
|
)
|
|
14
14
|
|
|
15
15
|
|
|
@@ -17,10 +17,7 @@ class AgentType(Enum):
|
|
|
17
17
|
"""Enumeration for different types of agents."""
|
|
18
18
|
|
|
19
19
|
REACT = "REACT"
|
|
20
|
-
OPENAI = "OPENAI"
|
|
21
20
|
FUNCTION_CALLING = "FUNCTION_CALLING"
|
|
22
|
-
LLMCOMPILER = "LLMCOMPILER"
|
|
23
|
-
LATS = "LATS"
|
|
24
21
|
|
|
25
22
|
|
|
26
23
|
class ObserverType(Enum):
|
|
@@ -37,7 +34,6 @@ class ModelProvider(Enum):
|
|
|
37
34
|
ANTHROPIC = "ANTHROPIC"
|
|
38
35
|
TOGETHER = "TOGETHER"
|
|
39
36
|
GROQ = "GROQ"
|
|
40
|
-
FIREWORKS = "FIREWORKS"
|
|
41
37
|
COHERE = "COHERE"
|
|
42
38
|
GEMINI = "GEMINI"
|
|
43
39
|
BEDROCK = "BEDROCK"
|
|
@@ -84,8 +80,110 @@ class HumanReadableOutput(Protocol):
|
|
|
84
80
|
"""Get the raw output data."""
|
|
85
81
|
|
|
86
82
|
|
|
83
|
+
class _StreamProto(Protocol):
|
|
84
|
+
"""What we actually use from the LI streaming response."""
|
|
85
|
+
|
|
86
|
+
response: str | None
|
|
87
|
+
response_id: str | None
|
|
88
|
+
|
|
89
|
+
def get_response(self) -> LI_AgentChatResponse:
|
|
90
|
+
"""Get the agent chat response."""
|
|
91
|
+
|
|
92
|
+
def to_response(self) -> LI_AgentChatResponse:
|
|
93
|
+
"""Convert to agent chat response."""
|
|
94
|
+
|
|
95
|
+
def get_final_response(self) -> LI_AgentChatResponse:
|
|
96
|
+
"""Get the final agent chat response."""
|
|
97
|
+
|
|
98
|
+
def __iter__(self):
|
|
99
|
+
"""Return an iterator over the stream."""
|
|
100
|
+
|
|
101
|
+
async def async_response_gen(self) -> AsyncIterator[str]:
|
|
102
|
+
"""Async generator that yields response strings."""
|
|
103
|
+
|
|
104
|
+
|
|
87
105
|
# classes for Agent responses
|
|
88
106
|
ToolOutput = LI_ToolOutput
|
|
89
107
|
AgentResponse = LI_AgentChatResponse
|
|
90
|
-
AgentStreamingResponse = LI_StreamingAgentChatResponse
|
|
91
108
|
Document = LI_Document
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@dataclass
|
|
112
|
+
class AgentStreamingResponse:
|
|
113
|
+
"""Our stream wrapper with writable metadata and a typed get_response()."""
|
|
114
|
+
|
|
115
|
+
base: _StreamProto
|
|
116
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
117
|
+
|
|
118
|
+
def __getattr__(self, name: str):
|
|
119
|
+
return getattr(self.base, name)
|
|
120
|
+
|
|
121
|
+
def get_response(self) -> AgentResponse:
|
|
122
|
+
"""Get the response from the base stream, merging metadata."""
|
|
123
|
+
# choose whichever method the base actually has
|
|
124
|
+
if hasattr(self.base, "get_response"):
|
|
125
|
+
resp = cast(AgentResponse, self.base.get_response())
|
|
126
|
+
elif hasattr(self.base, "to_response"):
|
|
127
|
+
resp = cast(AgentResponse, self.base.to_response())
|
|
128
|
+
else:
|
|
129
|
+
resp = cast(AgentResponse, self.base.get_final_response())
|
|
130
|
+
|
|
131
|
+
resp.metadata = (resp.metadata or {}) | self.metadata
|
|
132
|
+
return resp
|
|
133
|
+
|
|
134
|
+
async def aget_response(self) -> AgentResponse:
|
|
135
|
+
"""Get the response from the base stream, merging metadata (async version)."""
|
|
136
|
+
# prefer async version if available
|
|
137
|
+
if hasattr(self.base, "aget_response"):
|
|
138
|
+
resp = cast(AgentResponse, await self.base.aget_response())
|
|
139
|
+
elif hasattr(self.base, "get_response"):
|
|
140
|
+
resp = cast(AgentResponse, self.base.get_response())
|
|
141
|
+
elif hasattr(self.base, "to_response"):
|
|
142
|
+
resp = cast(AgentResponse, self.base.to_response())
|
|
143
|
+
elif hasattr(self.base, "get_final_response"):
|
|
144
|
+
resp = cast(AgentResponse, self.base.get_final_response())
|
|
145
|
+
else:
|
|
146
|
+
# Fallback for StreamingAgentChatResponse objects that don't have standard methods
|
|
147
|
+
# Try to get the response directly from the object's response attribute
|
|
148
|
+
if hasattr(self.base, "response"):
|
|
149
|
+
response_text = self.base.response if isinstance(self.base.response, str) else str(self.base.response)
|
|
150
|
+
resp = AgentResponse(response=response_text, metadata=getattr(self.base, "metadata", {}))
|
|
151
|
+
else:
|
|
152
|
+
resp = AgentResponse(response="", metadata={})
|
|
153
|
+
|
|
154
|
+
resp.metadata = (resp.metadata or {}) | self.metadata
|
|
155
|
+
return resp
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def async_response_gen(self) -> Callable[[], AsyncIterator[str]]:
|
|
159
|
+
"""Get the async response generator from the base stream."""
|
|
160
|
+
return self.base.async_response_gen
|
|
161
|
+
|
|
162
|
+
@async_response_gen.setter
|
|
163
|
+
def async_response_gen(self, fn: Callable[[], AsyncIterator[str]]):
|
|
164
|
+
"""Set the async response generator for the base stream."""
|
|
165
|
+
self.base.async_response_gen = fn
|
|
166
|
+
|
|
167
|
+
@classmethod
|
|
168
|
+
def from_error(cls, msg: str) -> "AgentStreamingResponse":
|
|
169
|
+
"""Create an AgentStreamingResponse from an error message."""
|
|
170
|
+
|
|
171
|
+
async def _empty_gen():
|
|
172
|
+
if False: # pylint: disable=using-constant-test
|
|
173
|
+
yield ""
|
|
174
|
+
|
|
175
|
+
class _ErrStream:
|
|
176
|
+
def __init__(self, msg: str):
|
|
177
|
+
self.response = msg
|
|
178
|
+
self.response_id = None
|
|
179
|
+
|
|
180
|
+
async def async_response_gen(self):
|
|
181
|
+
"""Async generator that yields an error message."""
|
|
182
|
+
if False: # pylint: disable=using-constant-test
|
|
183
|
+
yield ""
|
|
184
|
+
|
|
185
|
+
def get_response(self) -> AgentResponse:
|
|
186
|
+
"""Return an AgentResponse with the error message."""
|
|
187
|
+
return AgentResponse(response=self.response, metadata={})
|
|
188
|
+
|
|
189
|
+
return cls(base=_ErrStream(msg), metadata={})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vectara_agentic
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
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,26 +16,24 @@ 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-core==0.12.
|
|
21
|
-
Requires-Dist: llama-index-
|
|
19
|
+
Requires-Dist: llama-index==0.12.52
|
|
20
|
+
Requires-Dist: llama-index-core==0.12.52.post1
|
|
21
|
+
Requires-Dist: llama-index-workflow==1.0.1
|
|
22
|
+
Requires-Dist: llama-index-cli==0.4.4
|
|
22
23
|
Requires-Dist: llama-index-indices-managed-vectara==0.4.5
|
|
23
|
-
Requires-Dist: llama-index-agent-
|
|
24
|
-
Requires-Dist: llama-index-
|
|
25
|
-
Requires-Dist: llama-index-
|
|
26
|
-
Requires-Dist: llama-index-llms-
|
|
27
|
-
Requires-Dist: llama-index-llms-
|
|
28
|
-
Requires-Dist: llama-index-llms-
|
|
29
|
-
Requires-Dist: llama-index-llms-together==0.3.1
|
|
30
|
-
Requires-Dist: llama-index-llms-groq==0.3.1
|
|
31
|
-
Requires-Dist: llama-index-llms-fireworks==0.3.2
|
|
24
|
+
Requires-Dist: llama-index-agent-openai==0.4.12
|
|
25
|
+
Requires-Dist: llama-index-llms-openai==0.4.7
|
|
26
|
+
Requires-Dist: llama-index-llms-openai-like==0.4.0
|
|
27
|
+
Requires-Dist: llama-index-llms-anthropic==0.7.6
|
|
28
|
+
Requires-Dist: llama-index-llms-together==0.3.2
|
|
29
|
+
Requires-Dist: llama-index-llms-groq==0.3.2
|
|
32
30
|
Requires-Dist: llama-index-llms-cohere==0.5.0
|
|
33
|
-
Requires-Dist: llama-index-llms-google-genai==0.2.
|
|
34
|
-
Requires-Dist: llama-index-llms-bedrock-converse==0.7.
|
|
31
|
+
Requires-Dist: llama-index-llms-google-genai==0.2.5
|
|
32
|
+
Requires-Dist: llama-index-llms-bedrock-converse==0.7.6
|
|
35
33
|
Requires-Dist: llama-index-tools-yahoo-finance==0.3.0
|
|
36
34
|
Requires-Dist: llama-index-tools-arxiv==0.3.0
|
|
37
35
|
Requires-Dist: llama-index-tools-database==0.3.0
|
|
38
|
-
Requires-Dist: llama-index-tools-google==0.
|
|
36
|
+
Requires-Dist: llama-index-tools-google==0.5.0
|
|
39
37
|
Requires-Dist: llama-index-tools-tavily_research==0.3.0
|
|
40
38
|
Requires-Dist: llama_index.tools.brave_search==0.3.0
|
|
41
39
|
Requires-Dist: llama-index-tools-neo4j==0.3.0
|
|
@@ -44,21 +42,21 @@ Requires-Dist: llama-index-graph-stores-kuzu==0.7.0
|
|
|
44
42
|
Requires-Dist: llama-index-tools-salesforce==0.3.0
|
|
45
43
|
Requires-Dist: llama-index-tools-slack==0.3.0
|
|
46
44
|
Requires-Dist: llama-index-tools-exa==0.3.0
|
|
47
|
-
Requires-Dist: llama-index-tools-wikipedia==0.3.
|
|
45
|
+
Requires-Dist: llama-index-tools-wikipedia==0.3.1
|
|
48
46
|
Requires-Dist: llama-index-tools-bing-search==0.3.0
|
|
49
|
-
Requires-Dist: openai>=1.
|
|
50
|
-
Requires-Dist: tavily-python
|
|
51
|
-
Requires-Dist: exa-py
|
|
47
|
+
Requires-Dist: openai>=1.96.1
|
|
48
|
+
Requires-Dist: tavily-python>=0.7.9
|
|
49
|
+
Requires-Dist: exa-py>=1.14.8
|
|
52
50
|
Requires-Dist: openinference-instrumentation-llama-index==4.3.1
|
|
53
51
|
Requires-Dist: opentelemetry-proto>=1.31.0
|
|
54
52
|
Requires-Dist: arize-phoenix==10.9.1
|
|
55
53
|
Requires-Dist: arize-phoenix-otel==0.10.3
|
|
56
|
-
Requires-Dist: protobuf==5.29.
|
|
54
|
+
Requires-Dist: protobuf==5.29.5
|
|
57
55
|
Requires-Dist: tokenizers>=0.20
|
|
58
56
|
Requires-Dist: pydantic==2.11.5
|
|
57
|
+
Requires-Dist: pandas==2.2.3
|
|
59
58
|
Requires-Dist: retrying==1.3.4
|
|
60
59
|
Requires-Dist: python-dotenv==1.0.1
|
|
61
|
-
Requires-Dist: tiktoken==0.9.0
|
|
62
60
|
Requires-Dist: cloudpickle>=3.1.1
|
|
63
61
|
Requires-Dist: httpx==0.28.1
|
|
64
62
|
Requires-Dist: commonmark==0.9.1
|
|
@@ -108,6 +106,7 @@ Dynamic: summary
|
|
|
108
106
|
- [Using Tools](#using-tools)
|
|
109
107
|
- [Advanced Usage: Workflows](#advanced-usage-workflows)
|
|
110
108
|
- [Configuration](#️-configuration)
|
|
109
|
+
- [Migrating from v0.3.x](#-migrating-from-v03x)
|
|
111
110
|
- [Contributing](#-contributing)
|
|
112
111
|
- [License](#-license)
|
|
113
112
|
|
|
@@ -124,11 +123,11 @@ Dynamic: summary
|
|
|
124
123
|
- **Rapid Tool Creation:**
|
|
125
124
|
Build Vectara RAG tools or search tools with a single line of code.
|
|
126
125
|
- **Agent Flexibility:**
|
|
127
|
-
Supports multiple agent types including `ReAct
|
|
126
|
+
Supports multiple agent types including `ReAct` and `Function Calling`.
|
|
128
127
|
- **Pre-Built Domain Tools:**
|
|
129
128
|
Tools tailored for finance, legal, and other verticals.
|
|
130
129
|
- **Multi-LLM Integration:**
|
|
131
|
-
Seamless integration with OpenAI, Anthropic, Gemini, GROQ, Together.AI, Cohere,
|
|
130
|
+
Seamless integration with OpenAI, Anthropic, Gemini, GROQ, Together.AI, Cohere, and Bedrock.
|
|
132
131
|
- **Observability:**
|
|
133
132
|
Built-in support with Arize Phoenix for monitoring and feedback.
|
|
134
133
|
- **Workflow Support:**
|
|
@@ -148,7 +147,7 @@ Check out our example AI assistants:
|
|
|
148
147
|
- [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)
|
|
149
148
|
- A Vectara corpus with an [API key](https://docs.vectara.com/docs/api-keys)
|
|
150
149
|
- [Python 3.10 or higher](https://www.python.org/downloads/)
|
|
151
|
-
- OpenAI API key (or API keys for Anthropic, TOGETHER.AI,
|
|
150
|
+
- OpenAI API key (or API keys for Anthropic, TOGETHER.AI, Cohere, GEMINI or GROQ, if you choose to use them).
|
|
152
151
|
To use AWS Bedrock, make sure that
|
|
153
152
|
* The Bedrock models you need are enabled on your account
|
|
154
153
|
* Your environment includes `AWS_PROFILE` with your AWS profile name.
|
|
@@ -200,7 +199,8 @@ ask_finance = vec_factory.create_rag_tool(
|
|
|
200
199
|
tool_description="Query financial reports for a company and year",
|
|
201
200
|
tool_args_schema=QueryFinancialReportsArgs,
|
|
202
201
|
lambda_val=0.005,
|
|
203
|
-
summary_num_results=7,
|
|
202
|
+
summary_num_results=7,
|
|
203
|
+
vhc_eligible=True, # RAG tools participate in VHC by default
|
|
204
204
|
# Additional Vectara query arguments...
|
|
205
205
|
)
|
|
206
206
|
```
|
|
@@ -480,6 +480,30 @@ def mult_func(x, y):
|
|
|
480
480
|
mult_tool = ToolsFactory().create_tool(mult_func)
|
|
481
481
|
```
|
|
482
482
|
|
|
483
|
+
#### VHC Eligibility
|
|
484
|
+
|
|
485
|
+
When creating tools, you can control whether they participate in Vectara Hallucination Correction, by using the `vhc_eligible` parameter:
|
|
486
|
+
|
|
487
|
+
```python
|
|
488
|
+
# Tool that provides factual data - should participate in VHC
|
|
489
|
+
data_tool = ToolsFactory().create_tool(get_company_data, vhc_eligible=True)
|
|
490
|
+
|
|
491
|
+
# Utility tool that doesn't provide context - should not participate in VHC
|
|
492
|
+
summary_tool = ToolsFactory().create_tool(summarize_text, vhc_eligible=False)
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**VHC-eligible tools** (default: `True`) are those that provide factual context for responses, such as:
|
|
496
|
+
- Data retrieval tools
|
|
497
|
+
- Search tools
|
|
498
|
+
- API calls that return factual information
|
|
499
|
+
|
|
500
|
+
**Non-VHC-eligible tools** (`vhc_eligible=False`) are utility tools that don't contribute factual context:
|
|
501
|
+
- Text summarization tools
|
|
502
|
+
- Text rephrasing tools
|
|
503
|
+
- Formatting or processing tools
|
|
504
|
+
|
|
505
|
+
Built-in utility tools like `summarize_text`, `rephrase_text`, and `get_bad_topics` are automatically marked as non-VHC-eligible.
|
|
506
|
+
|
|
483
507
|
#### Human-Readable Tool Output
|
|
484
508
|
|
|
485
509
|
Tools can provide both raw data and human-readable formatted output using the `create_human_readable_output` utility:
|
|
@@ -504,7 +528,50 @@ Built-in formatters include `format_as_table`, `format_as_json`, and `format_as_
|
|
|
504
528
|
> and not as nested functions. Nested functions are not supported if you use serialization
|
|
505
529
|
> (dumps/loads or from_dict/to_dict).
|
|
506
530
|
|
|
507
|
-
The human-readable format, if available, is used when
|
|
531
|
+
The human-readable format, if available, is used when using Vectara Hallucination Correction.
|
|
532
|
+
|
|
533
|
+
## 🔍 Vectara Hallucination Correction (VHC)
|
|
534
|
+
|
|
535
|
+
`vectara-agentic` provides built-in support for Vectara Hallucination Correction (VHC), which analyzes agent responses and corrects any detected hallucinations based on the factual content retrieved by VHC-eligible tools.
|
|
536
|
+
|
|
537
|
+
### Computing VHC
|
|
538
|
+
|
|
539
|
+
After a chat interaction, you can compute VHC to analyze and correct the agent's response:
|
|
540
|
+
|
|
541
|
+
```python
|
|
542
|
+
# Chat with the agent
|
|
543
|
+
response = agent.chat("What was Apple's revenue in 2022?")
|
|
544
|
+
print(response.response)
|
|
545
|
+
|
|
546
|
+
# Compute VHC analysis
|
|
547
|
+
vhc_result = agent.compute_vhc()
|
|
548
|
+
|
|
549
|
+
# Access corrected text and corrections
|
|
550
|
+
if vhc_result["corrected_text"]:
|
|
551
|
+
print("Original:", response.response)
|
|
552
|
+
print("Corrected:", vhc_result["corrected_text"])
|
|
553
|
+
print("Corrections:", vhc_result["corrections"])
|
|
554
|
+
else:
|
|
555
|
+
print("No corrections needed or VHC not available")
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
### Async VHC Computation
|
|
559
|
+
|
|
560
|
+
For async applications, use `acompute_vhc()`:
|
|
561
|
+
|
|
562
|
+
```python
|
|
563
|
+
# Async chat
|
|
564
|
+
response = await agent.achat("What was Apple's revenue in 2022?")
|
|
565
|
+
|
|
566
|
+
# Async VHC computation
|
|
567
|
+
vhc_result = await agent.acompute_vhc()
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### VHC Requirements
|
|
571
|
+
|
|
572
|
+
- VHC requires a valid `VECTARA_API_KEY` environment variable
|
|
573
|
+
- Only VHC-eligible tools (those marked with `vhc_eligible=True`) contribute to the analysis
|
|
574
|
+
- VHC results are cached for each query/response pair to avoid redundant computation
|
|
508
575
|
|
|
509
576
|
### Tool Validation
|
|
510
577
|
|
|
@@ -719,12 +786,13 @@ agent = Agent(
|
|
|
719
786
|
```
|
|
720
787
|
|
|
721
788
|
The `AgentConfig` object may include the following items:
|
|
722
|
-
- `agent_type`: the agent type. Valid values are `REACT
|
|
723
|
-
- `main_llm_provider` and `tool_llm_provider`: the LLM provider for main agent and for the tools. Valid values are `OPENAI`, `ANTHROPIC`, `TOGETHER`, `GROQ`, `COHERE`, `BEDROCK`, `GEMINI`
|
|
724
|
-
|
|
789
|
+
- `agent_type`: the agent type. Valid values are `REACT` or `FUNCTION_CALLING` (default: `FUNCTION_CALLING`).
|
|
790
|
+
- `main_llm_provider` and `tool_llm_provider`: the LLM provider for main agent and for the tools. Valid values are `OPENAI`, `ANTHROPIC`, `TOGETHER`, `GROQ`, `COHERE`, `BEDROCK`, `GEMINI` (default: `OPENAI`).
|
|
791
|
+
|
|
792
|
+
> **Note:** Fireworks AI support has been removed. If you were using Fireworks, please migrate to one of the supported providers listed above.
|
|
793
|
+
- `main_llm_model_name` and `tool_llm_model_name`: agent model name for agent and tools (default depends on provider: OpenAI uses gpt-4.1, Gemini uses gemini-2.5-flash).
|
|
725
794
|
- `observer`: the observer type; should be `ARIZE_PHOENIX` or if undefined no observation framework will be used.
|
|
726
795
|
- `endpoint_api_key`: a secret key if using the API endpoint option (defaults to `dev-api-key`)
|
|
727
|
-
- `max_reasoning_steps`: the maximum number of reasoning steps (iterations for React and function calls for OpenAI agent, respectively). Defaults to 50.
|
|
728
796
|
|
|
729
797
|
If any of these are not provided, `AgentConfig` first tries to read the values from the OS environment.
|
|
730
798
|
|
|
@@ -759,3 +827,15 @@ agent = Agent(
|
|
|
759
827
|
)
|
|
760
828
|
```
|
|
761
829
|
|
|
830
|
+
## 🚀 Migrating from v0.3.x
|
|
831
|
+
|
|
832
|
+
If you're upgrading from v0.3.x, please note the following breaking changes in v0.4.0:
|
|
833
|
+
|
|
834
|
+
- **Fireworks LLM removed**: Migrate to OpenAI, Anthropic, Together.AI, GROQ, Cohere, Bedrock, or Gemini
|
|
835
|
+
- **OPENAI AgentType removed**: Use the FUNCTION_CALLING AgentType instead, when using OpenAI for main_llm_provider
|
|
836
|
+
- **StructuredPlanning deprecated**: Use standard Agent workflows or create custom workflows
|
|
837
|
+
- **Token counting and compact_docstring removed**: Remove these from your configuration
|
|
838
|
+
- **update_func removed**: This functionality is no longer available
|
|
839
|
+
|
|
840
|
+
For detailed migration instructions, see [CHANGELOG.md](CHANGELOG.md).
|
|
841
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
tests/__init__.py,sha256=vXhQJCyD1Uhx2NP8b8vIUG3RUhkXyvn7oOir2bmctQU,175
|
|
2
|
+
tests/conftest.py,sha256=PlHevWpkOP1F9pG9GJSf8ewYW_1FsFYcx3CQyjxAziY,9286
|
|
3
|
+
tests/endpoint.py,sha256=0URgtz8uydhP_rtpGn_59P1LiWkd3idNlI85LzXnlUE,2744
|
|
4
|
+
tests/run_tests.py,sha256=2dKDJ2uhz6SKlr72Zkh7PTVb2F52_FpirM_wKiIFuiw,3232
|
|
5
|
+
tests/test_agent.py,sha256=dwCHul-GnpURAmSMJlNo9_k_Aizr4KhkJKccKwDvZ38,5778
|
|
6
|
+
tests/test_agent_fallback_memory.py,sha256=1LoRHxUM767bGmCeusPlGubX_pIeP5KxIABRwdWLJGo,10862
|
|
7
|
+
tests/test_agent_memory_consistency.py,sha256=D8ivCGp5reJyOK7Q6wDiZlv3bKX4-SEchnqocyib1Po,8966
|
|
8
|
+
tests/test_agent_type.py,sha256=d5Zs0iM12DxregfwkJ6UxERWcR5eLgy2ona1znwvK3I,5153
|
|
9
|
+
tests/test_api_endpoint.py,sha256=I2UDamPMSLLkgw0pZ5QMM0o_8vVga9-F6ql-S3zlMBs,5136
|
|
10
|
+
tests/test_bedrock.py,sha256=74M4k4MWFfZV-mD75R_27HQGTfWcPQ40ijLanT54y-E,1979
|
|
11
|
+
tests/test_fallback.py,sha256=6wkyiyAvsibIdr33aXdsuU9nzDeJt0XSz5yiyuisUEQ,2963
|
|
12
|
+
tests/test_gemini.py,sha256=pvCcfTf79-R49H_WVZou1xx-vVmZEY-19zRtxZeUdD4,2581
|
|
13
|
+
tests/test_groq.py,sha256=OmO-VBrKfZYUc11QfZH25jT3FySQrSpv_FS488IqSik,1970
|
|
14
|
+
tests/test_private_llm.py,sha256=P6sldeAWcHg29u_Nu4FdHVUyNaRe5ULE-hjNJz6WKHc,2620
|
|
15
|
+
tests/test_return_direct.py,sha256=QsCw-ZGp06cutLkyrLh1U1rggoH7iBiFz4SQ9MIx-Xk,1521
|
|
16
|
+
tests/test_serialization.py,sha256=wdVRoy6hoPqCF7SGpYbC2TM7iR2o_IKIRKOBZFAChp0,4824
|
|
17
|
+
tests/test_session_memory.py,sha256=hnADl59agjpXySY-CBjw6sDPn3s6JketIK6XbLZsLzU,9691
|
|
18
|
+
tests/test_streaming.py,sha256=EBihBb_ZQiGCCvv7Us7YqHN4CxDIQy-XsUSDVO1n5wU,3302
|
|
19
|
+
tests/test_together.py,sha256=s0ywOxL-XT_iq970ucamVAPR_CIS9OT72vJB7degNdc,1983
|
|
20
|
+
tests/test_tools.py,sha256=869Fl54kmLc44ijykO2QpfcXyAWLDqJ9Niq3XNzhzv8,13621
|
|
21
|
+
tests/test_vectara_llms.py,sha256=H1M9OaDvD8_GCFRBm6IdvWejYKn-zm3-Rzt_noCBbiQ,2496
|
|
22
|
+
tests/test_vhc.py,sha256=MXyFxckQzfdXcULqwoao4taoQ93qLDvkcf-h2LwUQnE,1974
|
|
23
|
+
tests/test_workflow.py,sha256=dwQnHSxvRMVqUtFV8O2KvuyaSKJXFDkVhcffn8mSuJs,3555
|
|
24
|
+
vectara_agentic/__init__.py,sha256=CfS3QR4drKygcTcyH5zUUDuXXQ3WZtTCytz8W4-loeE,1077
|
|
25
|
+
vectara_agentic/_callback.py,sha256=ueckIfLNa9ykmmEyLqrrZwfDNWrEfyZzJeWktpnkwJQ,12970
|
|
26
|
+
vectara_agentic/_observability.py,sha256=c_1WuP8rS9sPuMH6twzcz6CGLqfTT5y4fyOHvDVdxsg,4423
|
|
27
|
+
vectara_agentic/_version.py,sha256=dWTo8m6tq_yNZLAER4W8gWnDQib4KBI28u8pwf8jiRM,65
|
|
28
|
+
vectara_agentic/agent.py,sha256=2laHGTp1D2ve96zdxdN3wtq0MMIe5B8RxTxDXrJDTOE,46779
|
|
29
|
+
vectara_agentic/agent_config.py,sha256=njqEX2qHJjAp2KpNuJglgZhyWXPK74wjIjBPACD6w7w,4074
|
|
30
|
+
vectara_agentic/agent_endpoint.py,sha256=E_AF-YwxaKqd1-p43X62e1e4ugwOWKIyNq4RWOfsO7A,7402
|
|
31
|
+
vectara_agentic/db_tools.py,sha256=nVZkpGdG63ooGngjX9g7YWyBZRtYMDpvzNasbO696nM,11498
|
|
32
|
+
vectara_agentic/llm_utils.py,sha256=dgomwK7FOVmH_prgOR60CjhG6kwt-AxxMLlFa8vWspY,7449
|
|
33
|
+
vectara_agentic/sub_query_workflow.py,sha256=wm2Lb2wbKrYx5bSq-npb3XbaxWzTcvK5BkW3NZ9vuIc,12968
|
|
34
|
+
vectara_agentic/tool_utils.py,sha256=whnQlk9coeIt01sqUnKnzUorefgn96yWqhtRfHxNL84,25921
|
|
35
|
+
vectara_agentic/tools.py,sha256=8gmC6UnHFTUr_hWWbuMyRNMMLkeY5Sb1FTgCsb7Hx1w,35689
|
|
36
|
+
vectara_agentic/tools_catalog.py,sha256=p6eRram-diJyMz5dZI703auSAm97FfW5wLAMyz_2sB0,4634
|
|
37
|
+
vectara_agentic/types.py,sha256=qKkK8vRNiLvEcMInMyOClK2bD7iFlrWGTkl3fGC6Xic,6117
|
|
38
|
+
vectara_agentic/utils.py,sha256=R9HitEG5K3Q_p2M_teosT181OUxkhs1-hnj98qDYGbE,2545
|
|
39
|
+
vectara_agentic/agent_core/__init__.py,sha256=R3KGbSOiY21FOjbeQ_GyIi6uR9Rz7PTfudO9RjSuEZQ,722
|
|
40
|
+
vectara_agentic/agent_core/factory.py,sha256=AMlUuAwUVocqwfOYkW-HJuUr81Kj0kUjcG4pPXmCZMM,14201
|
|
41
|
+
vectara_agentic/agent_core/prompts.py,sha256=HJ8b-5OEn6-suqWqQgeAVOZNEiPr7wKHeaczNdL-XN8,10127
|
|
42
|
+
vectara_agentic/agent_core/serialization.py,sha256=Ag9Ux497_IyxrexYP90wbG-UJy-lTH1ec_ANmpPmQjo,11731
|
|
43
|
+
vectara_agentic/agent_core/streaming.py,sha256=Xzz0kgt1LFeKlnhlDTsZmBze-asvYauwIlYJi2hgHjk,17772
|
|
44
|
+
vectara_agentic/agent_core/utils/__init__.py,sha256=y5Xf0IH-5TRxMBRA9IyhmWnGZOVIyqV45P6lX4c2Qsc,762
|
|
45
|
+
vectara_agentic/agent_core/utils/hallucination.py,sha256=XmV7tW-MBN9BrzM79zu0T7zaWil7fIkNQjLfDZE43v4,5312
|
|
46
|
+
vectara_agentic/agent_core/utils/logging.py,sha256=-Ll8iUelml92WuhNWScuY6H-RheyZOTBHNxXQ1UGy0M,1701
|
|
47
|
+
vectara_agentic/agent_core/utils/schemas.py,sha256=e7xhJBevgK7IM8cRT5hoO67T-Ep_FhNGp72Zo0OC_Jo,2853
|
|
48
|
+
vectara_agentic/agent_core/utils/tools.py,sha256=k9Gm-UUQ3ZeGxrkjyrjmjcGxOkvnpylcm_Krnr-0fsY,4748
|
|
49
|
+
vectara_agentic-0.4.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
50
|
+
vectara_agentic-0.4.1.dist-info/METADATA,sha256=PuM3HoXyagcOndjlq7XM5gPAGkjntAgIxI72OkHCLhw,35059
|
|
51
|
+
vectara_agentic-0.4.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
52
|
+
vectara_agentic-0.4.1.dist-info/top_level.txt,sha256=Y7TQTFdOYGYodQRltUGRieZKIYuzeZj2kHqAUpfCUfg,22
|
|
53
|
+
vectara_agentic-0.4.1.dist-info/RECORD,,
|
tests/test_agent_planning.py
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import unittest
|
|
2
|
-
|
|
3
|
-
from vectara_agentic.agent_config import AgentConfig
|
|
4
|
-
from vectara_agentic.agent import Agent
|
|
5
|
-
from vectara_agentic.tools import VectaraToolFactory
|
|
6
|
-
|
|
7
|
-
# SETUP special test account credentials for vectara
|
|
8
|
-
# It's okay to expose these credentials in the test code
|
|
9
|
-
vectara_corpus_key = "vectara-docs_1"
|
|
10
|
-
vectara_api_key = 'zqt_UXrBcnI2UXINZkrv4g1tQPhzj02vfdtqYJIDiA'
|
|
11
|
-
|
|
12
|
-
vec_factory = VectaraToolFactory(vectara_api_key=vectara_api_key,
|
|
13
|
-
vectara_corpus_key=vectara_corpus_key)
|
|
14
|
-
summarizer = 'vectara-summary-table-md-query-ext-jan-2025-gpt-4o'
|
|
15
|
-
ask_vectara = vec_factory.create_rag_tool(
|
|
16
|
-
tool_name = "ask_vectara",
|
|
17
|
-
tool_description = "This tool can respond to questions about Vectara.",
|
|
18
|
-
reranker = "multilingual_reranker_v1", rerank_k = 100, rerank_cutoff = 0.1,
|
|
19
|
-
n_sentences_before = 2, n_sentences_after = 2, lambda_val = 0.005,
|
|
20
|
-
summary_num_results = 10,
|
|
21
|
-
vectara_summarizer = summarizer,
|
|
22
|
-
include_citations = True,
|
|
23
|
-
verbose=False,
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
class TestAgentPlanningPackage(unittest.TestCase):
|
|
27
|
-
|
|
28
|
-
def test_no_planning(self):
|
|
29
|
-
tools = [ask_vectara]
|
|
30
|
-
topic = "vectara"
|
|
31
|
-
instructions = "Answer user queries about Vectara."
|
|
32
|
-
|
|
33
|
-
query = "What is Vectara and what demos are available of the Vectara platform?"
|
|
34
|
-
agent = Agent(
|
|
35
|
-
tools=tools,
|
|
36
|
-
topic=topic,
|
|
37
|
-
custom_instructions=instructions,
|
|
38
|
-
agent_config=AgentConfig(),
|
|
39
|
-
)
|
|
40
|
-
res = agent.chat(query)
|
|
41
|
-
self.assertIn("demos", res.response)
|
|
42
|
-
self.assertIn("Vectara", res.response)
|
|
43
|
-
|
|
44
|
-
def test_structured_planning(self):
|
|
45
|
-
tools = [ask_vectara]
|
|
46
|
-
topic = "vectara"
|
|
47
|
-
instructions = "Answer user queries about Vectara."
|
|
48
|
-
|
|
49
|
-
query = "What is Vectara and what demos are available of the Vectara platform?"
|
|
50
|
-
agent = Agent(
|
|
51
|
-
tools=tools,
|
|
52
|
-
topic=topic,
|
|
53
|
-
custom_instructions=instructions,
|
|
54
|
-
agent_config=AgentConfig(),
|
|
55
|
-
use_structured_planning=True,
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
res = agent.chat(query)
|
|
59
|
-
self.assertIn("demos", res.response)
|
|
60
|
-
self.assertIn("Vectara", res.response)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if __name__ == "__main__":
|
|
64
|
-
unittest.main()
|
tests/test_hhem.py
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
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, VectaraToolFactory
|
|
6
|
-
from vectara_agentic.types import ModelProvider
|
|
7
|
-
|
|
8
|
-
import nest_asyncio
|
|
9
|
-
|
|
10
|
-
nest_asyncio.apply()
|
|
11
|
-
|
|
12
|
-
vectara_corpus_key = "vectara-docs_1"
|
|
13
|
-
vectara_api_key = 'zqt_UXrBcnI2UXINZkrv4g1tQPhzj02vfdtqYJIDiA'
|
|
14
|
-
|
|
15
|
-
vec_factory = VectaraToolFactory(vectara_api_key=vectara_api_key,
|
|
16
|
-
vectara_corpus_key=vectara_corpus_key)
|
|
17
|
-
summarizer = 'vectara-summary-table-md-query-ext-jan-2025-gpt-4o'
|
|
18
|
-
ask_vectara = vec_factory.create_rag_tool(
|
|
19
|
-
tool_name = "ask_vectara",
|
|
20
|
-
tool_description = "This tool can respond to questions about Vectara.",
|
|
21
|
-
reranker = "multilingual_reranker_v1", rerank_k = 100, rerank_cutoff = 0.1,
|
|
22
|
-
n_sentences_before = 2, n_sentences_after = 2, lambda_val = 0.005,
|
|
23
|
-
summary_num_results = 10,
|
|
24
|
-
vectara_summarizer = summarizer,
|
|
25
|
-
include_citations = True,
|
|
26
|
-
verbose=False,
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
statements = [
|
|
31
|
-
"The sky is blue.",
|
|
32
|
-
"Cats are better than dogs.",
|
|
33
|
-
"Python is a great programming language.",
|
|
34
|
-
"The Earth revolves around the Sun.",
|
|
35
|
-
"Chocolate is the best ice cream flavor.",
|
|
36
|
-
]
|
|
37
|
-
st_inx = 0
|
|
38
|
-
def get_statement() -> str:
|
|
39
|
-
"Generate next statement"
|
|
40
|
-
global st_inx
|
|
41
|
-
st = statements[st_inx]
|
|
42
|
-
st_inx += 1
|
|
43
|
-
return st
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
fc_config = AgentConfig(
|
|
47
|
-
agent_type=AgentType.FUNCTION_CALLING,
|
|
48
|
-
main_llm_provider=ModelProvider.ANTHROPIC,
|
|
49
|
-
tool_llm_provider=ModelProvider.ANTHROPIC,
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
class TestFCS(unittest.TestCase):
|
|
54
|
-
|
|
55
|
-
def test_fcs(self):
|
|
56
|
-
tools = [ToolsFactory().create_tool(get_statement)]
|
|
57
|
-
topic = "statements"
|
|
58
|
-
instructions = (
|
|
59
|
-
f"Call the get_statement tool multiple times to get all {len(statements)} statements."
|
|
60
|
-
f"Respond to the user question based exclusively on the statements you receive - do not use any other knowledge or information."
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
agent = Agent(
|
|
64
|
-
tools=tools,
|
|
65
|
-
topic=topic,
|
|
66
|
-
agent_config=fc_config,
|
|
67
|
-
custom_instructions=instructions,
|
|
68
|
-
vectara_api_key=vectara_api_key,
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
res = agent.chat("Are cats better than dogs?")
|
|
72
|
-
fcs = res.metadata.get("fcs", None)
|
|
73
|
-
self.assertIsNotNone(fcs, "FCS score should not be None")
|
|
74
|
-
self.assertIsInstance(fcs, float, "FCS score should be a float")
|
|
75
|
-
self.assertGreater(
|
|
76
|
-
fcs, 0.5, "FCS score should be higher than 0.5 for this question"
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
def test_vectara_corpus(self):
|
|
80
|
-
tools = [ask_vectara]
|
|
81
|
-
topic = "vectara"
|
|
82
|
-
instructions = "Answer user queries about Vectara."
|
|
83
|
-
|
|
84
|
-
query = "What is Vectara and what API endpoints are available of the Vectara platform?"
|
|
85
|
-
agent = Agent(
|
|
86
|
-
tools=tools,
|
|
87
|
-
topic=topic,
|
|
88
|
-
custom_instructions=instructions,
|
|
89
|
-
agent_config=AgentConfig(),
|
|
90
|
-
vectara_api_key=vectara_api_key,
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
res = agent.chat(query)
|
|
94
|
-
fcs = res.metadata.get("fcs", None)
|
|
95
|
-
self.assertIn("Vectara", res.response)
|
|
96
|
-
self.assertGreater(fcs, 0.5, "FCS score should be higher than 0.5 for this question")
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if __name__ == "__main__":
|
|
100
|
-
unittest.main()
|