vectara-agentic 0.2.22__tar.gz → 0.2.24__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.
- {vectara_agentic-0.2.22/vectara_agentic.egg-info → vectara_agentic-0.2.24}/PKG-INFO +9 -1
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/README.md +8 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/test_workflow.py +8 -35
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/_prompts.py +1 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/_version.py +1 -1
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/agent.py +17 -7
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/db_tools.py +1 -1
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/sub_query_workflow.py +31 -9
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/tools.py +20 -2
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24/vectara_agentic.egg-info}/PKG-INFO +9 -1
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/LICENSE +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/MANIFEST.in +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/requirements.txt +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/setup.cfg +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/setup.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/__init__.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/endpoint.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/test_agent.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/test_agent_planning.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/test_agent_type.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/test_api_endpoint.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/test_bedrock.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/test_fallback.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/test_gemini.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/test_groq.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/test_private_llm.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/test_return_direct.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/test_serialization.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/test_tools.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/tests/test_vectara_llms.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/__init__.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/_callback.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/_observability.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/agent_config.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/agent_endpoint.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/llm_utils.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/tool_utils.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/tools_catalog.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/types.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic/utils.py +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic.egg-info/SOURCES.txt +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic.egg-info/dependency_links.txt +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic.egg-info/requires.txt +0 -0
- {vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vectara_agentic
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.24
|
|
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
|
|
@@ -530,6 +530,9 @@ class MyWorkflow(Workflow):
|
|
|
530
530
|
class OutputsModel(BaseModel):
|
|
531
531
|
answer: str
|
|
532
532
|
|
|
533
|
+
class OutputModelOnFail(BaseModel):
|
|
534
|
+
partial_response: str = ""
|
|
535
|
+
|
|
533
536
|
@step
|
|
534
537
|
async def my_step(self, ev: StartEvent) -> StopEvent:
|
|
535
538
|
# do something here
|
|
@@ -587,6 +590,11 @@ workflow_result = asyncio.run(agent.run(inputs))
|
|
|
587
590
|
print(workflow_result.answer)
|
|
588
591
|
```
|
|
589
592
|
|
|
593
|
+
When a workflow reaches its timeout, the timeout handler builds and returns an `OutputModelOnFail`
|
|
594
|
+
by reading each field named in that model from the workflow’s Context; for any field that isn’t set in the context,
|
|
595
|
+
it uses the default value you’ve defined on `OutputModelOnFail`. In other words, every property in `OutputModelOnFail`
|
|
596
|
+
must declare a default so that even if the corresponding context variable is missing, the model can be fully populated and returned without errors.
|
|
597
|
+
|
|
590
598
|
### Built-in Workflows
|
|
591
599
|
|
|
592
600
|
`vectara-agentic` includes two workflow implementations that you can use right away:
|
|
@@ -454,6 +454,9 @@ class MyWorkflow(Workflow):
|
|
|
454
454
|
class OutputsModel(BaseModel):
|
|
455
455
|
answer: str
|
|
456
456
|
|
|
457
|
+
class OutputModelOnFail(BaseModel):
|
|
458
|
+
partial_response: str = ""
|
|
459
|
+
|
|
457
460
|
@step
|
|
458
461
|
async def my_step(self, ev: StartEvent) -> StopEvent:
|
|
459
462
|
# do something here
|
|
@@ -511,6 +514,11 @@ workflow_result = asyncio.run(agent.run(inputs))
|
|
|
511
514
|
print(workflow_result.answer)
|
|
512
515
|
```
|
|
513
516
|
|
|
517
|
+
When a workflow reaches its timeout, the timeout handler builds and returns an `OutputModelOnFail`
|
|
518
|
+
by reading each field named in that model from the workflow’s Context; for any field that isn’t set in the context,
|
|
519
|
+
it uses the default value you’ve defined on `OutputModelOnFail`. In other words, every property in `OutputModelOnFail`
|
|
520
|
+
must declare a default so that even if the corresponding context variable is missing, the model can be fully populated and returned without errors.
|
|
521
|
+
|
|
514
522
|
### Built-in Workflows
|
|
515
523
|
|
|
516
524
|
`vectara-agentic` includes two workflow implementations that you can use right away:
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import unittest
|
|
2
2
|
|
|
3
|
-
from pydantic import BaseModel
|
|
4
|
-
|
|
5
|
-
from llama_index.core.workflow import WorkflowTimeoutError
|
|
6
|
-
|
|
7
3
|
from vectara_agentic.agent import Agent
|
|
8
4
|
from vectara_agentic.agent_config import AgentConfig
|
|
9
5
|
from vectara_agentic.tools import ToolsFactory
|
|
@@ -68,7 +64,7 @@ class TestWorkflowPackage(unittest.IsolatedAsyncioTestCase):
|
|
|
68
64
|
|
|
69
65
|
class TestWorkflowFailure(unittest.IsolatedAsyncioTestCase):
|
|
70
66
|
|
|
71
|
-
async def
|
|
67
|
+
async def test_workflow_failure_sub_question(self):
|
|
72
68
|
tools = [ToolsFactory().create_tool(mult)] + [ToolsFactory().create_tool(add)]
|
|
73
69
|
topic = "AI topic"
|
|
74
70
|
instructions = "You are a helpful AI assistant."
|
|
@@ -84,50 +80,27 @@ class TestWorkflowFailure(unittest.IsolatedAsyncioTestCase):
|
|
|
84
80
|
inputs = SubQuestionQueryWorkflow.InputsModel(
|
|
85
81
|
query="Compute 5 times 3, then add 7 to the result."
|
|
86
82
|
)
|
|
83
|
+
res = await agent.run(inputs=inputs)
|
|
84
|
+
self.assertIsInstance(res, SubQuestionQueryWorkflow.OutputModelOnFail)
|
|
87
85
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
try:
|
|
91
|
-
res = await agent.run(inputs=inputs)
|
|
92
|
-
except Exception as e:
|
|
93
|
-
self.assertIsInstance(e, WorkflowTimeoutError)
|
|
94
|
-
|
|
95
|
-
self.assertIsNone(res)
|
|
96
|
-
|
|
97
|
-
async def test_workflow_with_fail_class(self):
|
|
86
|
+
async def test_workflow_failure_seq_sub_question(self):
|
|
98
87
|
tools = [ToolsFactory().create_tool(mult)] + [ToolsFactory().create_tool(add)]
|
|
99
88
|
topic = "AI topic"
|
|
100
89
|
instructions = "You are a helpful AI assistant."
|
|
101
|
-
|
|
102
|
-
class SubQuestionQueryWorkflowWithFailClass(SubQuestionQueryWorkflow):
|
|
103
|
-
class OutputModelOnFail(BaseModel):
|
|
104
|
-
"""
|
|
105
|
-
In case of failure, returns the user's original query
|
|
106
|
-
"""
|
|
107
|
-
original_query: str
|
|
108
|
-
|
|
109
90
|
agent = Agent(
|
|
110
91
|
tools=tools,
|
|
111
92
|
topic=topic,
|
|
112
93
|
custom_instructions=instructions,
|
|
113
94
|
agent_config = AgentConfig(),
|
|
114
|
-
workflow_cls =
|
|
95
|
+
workflow_cls = SequentialSubQuestionsWorkflow,
|
|
115
96
|
workflow_timeout = 1
|
|
116
97
|
)
|
|
117
98
|
|
|
118
|
-
inputs =
|
|
99
|
+
inputs = SequentialSubQuestionsWorkflow.InputsModel(
|
|
119
100
|
query="Compute 5 times 3, then add 7 to the result."
|
|
120
101
|
)
|
|
121
|
-
|
|
122
|
-
res
|
|
123
|
-
|
|
124
|
-
try:
|
|
125
|
-
res = await agent.run(inputs=inputs)
|
|
126
|
-
except Exception as e:
|
|
127
|
-
assert isinstance(e, WorkflowTimeoutError)
|
|
128
|
-
|
|
129
|
-
self.assertIsInstance(res, SubQuestionQueryWorkflowWithFailClass.OutputModelOnFail)
|
|
130
|
-
self.assertEqual(res.original_query, "Compute 5 times 3, then add 7 to the result.")
|
|
102
|
+
res = await agent.run(inputs=inputs)
|
|
103
|
+
self.assertIsInstance(res, SequentialSubQuestionsWorkflow.OutputModelOnFail)
|
|
131
104
|
|
|
132
105
|
|
|
133
106
|
if __name__ == "__main__":
|
|
@@ -44,6 +44,7 @@ GENERAL_INSTRUCTIONS = """
|
|
|
44
44
|
- If you are provided with database tools use them for analytical queries (such as counting, calculating max, min, average, sum, or other statistics).
|
|
45
45
|
For each database, the database tools include: x_list_tables, x_load_data, x_describe_tables, x_load_unique_values, and x_load_sample_data, where 'x' in the database name.
|
|
46
46
|
for example, if the database name is "ev", the tools are: ev_list_tables, ev_load_data, ev_describe_tables, ev_load_unique_values, and ev_load_sample_data.
|
|
47
|
+
Use ANSI SQL-92 syntax for the SQL queries, and do not use any other SQL dialect.
|
|
47
48
|
Before using the x_load_data with a SQL query, always follow these discovery steps:
|
|
48
49
|
- call the x_list_tables tool to list of available tables in the x database.
|
|
49
50
|
- Call the x_describe_tables tool to understand the schema of each table you want to query data from.
|
|
@@ -15,6 +15,8 @@ from collections import Counter
|
|
|
15
15
|
import inspect
|
|
16
16
|
from inspect import Signature, Parameter, ismethod
|
|
17
17
|
from pydantic import Field, create_model, ValidationError, BaseModel
|
|
18
|
+
from pydantic_core import PydanticUndefined
|
|
19
|
+
|
|
18
20
|
import cloudpickle as pickle
|
|
19
21
|
|
|
20
22
|
from dotenv import load_dotenv
|
|
@@ -1083,6 +1085,15 @@ class Agent:
|
|
|
1083
1085
|
if not isinstance(inputs, self.workflow_cls.InputsModel):
|
|
1084
1086
|
raise ValueError(f"Inputs must be an instance of {workflow.InputsModel}.")
|
|
1085
1087
|
|
|
1088
|
+
outputs_model_on_fail_cls = getattr(workflow.__class__, "OutputModelOnFail", None)
|
|
1089
|
+
if outputs_model_on_fail_cls:
|
|
1090
|
+
fields_without_default = []
|
|
1091
|
+
for name, field_info in outputs_model_on_fail_cls.model_fields.items():
|
|
1092
|
+
if field_info.default_factory is PydanticUndefined:
|
|
1093
|
+
fields_without_default.append(name)
|
|
1094
|
+
if fields_without_default:
|
|
1095
|
+
raise ValueError(f"Fields without default values: {fields_without_default}")
|
|
1096
|
+
|
|
1086
1097
|
workflow_context = Context(workflow=workflow)
|
|
1087
1098
|
try:
|
|
1088
1099
|
# run workflow
|
|
@@ -1102,15 +1113,14 @@ class Agent:
|
|
|
1102
1113
|
raise ValueError(f"Failed to map workflow output to model: {e}") from e
|
|
1103
1114
|
|
|
1104
1115
|
except Exception as e:
|
|
1105
|
-
|
|
1116
|
+
_missing = object()
|
|
1106
1117
|
if outputs_model_on_fail_cls:
|
|
1107
1118
|
model_fields = outputs_model_on_fail_cls.model_fields
|
|
1108
|
-
input_dict = {
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
# return output in the form of workflow.OutputModelOnFail(BaseModel)
|
|
1119
|
+
input_dict = {}
|
|
1120
|
+
for key in model_fields:
|
|
1121
|
+
value = await workflow_context.get(key, default=_missing)
|
|
1122
|
+
if value is not _missing:
|
|
1123
|
+
input_dict[key] = value
|
|
1114
1124
|
output = outputs_model_on_fail_cls.model_validate(input_dict)
|
|
1115
1125
|
else:
|
|
1116
1126
|
print(f"Vectara Agentic: Workflow failed with unexpected error: {e}")
|
|
@@ -114,7 +114,7 @@ class DatabaseTools:
|
|
|
114
114
|
if sql_query is None:
|
|
115
115
|
raise ValueError("A query parameter is necessary to filter the data.")
|
|
116
116
|
|
|
117
|
-
count_query = f"SELECT COUNT(*) FROM ({sql_query})"
|
|
117
|
+
count_query = f"SELECT COUNT(*) FROM ({sql_query}) c"
|
|
118
118
|
try:
|
|
119
119
|
count_rows = self._load_data(count_query)
|
|
120
120
|
except Exception as e:
|
|
@@ -5,7 +5,7 @@ that takes a user question and a list of tools, and outputs a list of sub-questi
|
|
|
5
5
|
|
|
6
6
|
import re
|
|
7
7
|
import json
|
|
8
|
-
from pydantic import BaseModel
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
9
|
|
|
10
10
|
from llama_index.core.workflow import (
|
|
11
11
|
step,
|
|
@@ -37,6 +37,13 @@ class SubQuestionQueryWorkflow(Workflow):
|
|
|
37
37
|
|
|
38
38
|
response: str
|
|
39
39
|
|
|
40
|
+
class OutputModelOnFail(BaseModel):
|
|
41
|
+
"""
|
|
42
|
+
Outputs for the workflow when it fails.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
qna: list[tuple[str,str]] = Field(default_factory=list, description="List of question-answer pairs")
|
|
46
|
+
|
|
40
47
|
# Workflow Event types
|
|
41
48
|
class QueryEvent(Event):
|
|
42
49
|
"""Event for a query."""
|
|
@@ -141,7 +148,7 @@ class SubQuestionQueryWorkflow(Workflow):
|
|
|
141
148
|
|
|
142
149
|
return None
|
|
143
150
|
|
|
144
|
-
@step(num_workers=
|
|
151
|
+
@step(num_workers=8)
|
|
145
152
|
async def sub_question(self, ctx: Context, ev: QueryEvent) -> AnswerEvent:
|
|
146
153
|
"""
|
|
147
154
|
Given a sub-question, return the answer to the sub-question, using the agent.
|
|
@@ -149,8 +156,11 @@ class SubQuestionQueryWorkflow(Workflow):
|
|
|
149
156
|
if await ctx.get("verbose"):
|
|
150
157
|
print(f"Sub-question is {ev.question}")
|
|
151
158
|
agent = await ctx.get("agent")
|
|
152
|
-
|
|
153
|
-
|
|
159
|
+
question = ev.question
|
|
160
|
+
response = await agent.achat(question)
|
|
161
|
+
answer = str(response)
|
|
162
|
+
await ctx.set("qna", await ctx.get("qna", []) + [(question, answer)])
|
|
163
|
+
return self.AnswerEvent(question=question, answer=answer)
|
|
154
164
|
|
|
155
165
|
@step
|
|
156
166
|
async def combine_answers(self, ctx: Context, ev: AnswerEvent) -> StopEvent | None:
|
|
@@ -209,6 +219,15 @@ class SequentialSubQuestionsWorkflow(Workflow):
|
|
|
209
219
|
|
|
210
220
|
response: str
|
|
211
221
|
|
|
222
|
+
class OutputModelOnFail(BaseModel):
|
|
223
|
+
"""
|
|
224
|
+
Outputs for the workflow when it fails.
|
|
225
|
+
"""
|
|
226
|
+
|
|
227
|
+
qna: list[tuple[str,str]] = Field(
|
|
228
|
+
default_factory=list, description="List of question-answer pairs"
|
|
229
|
+
)
|
|
230
|
+
|
|
212
231
|
# Workflow Event types
|
|
213
232
|
class QueryEvent(Event):
|
|
214
233
|
"""Event for a query."""
|
|
@@ -322,24 +341,27 @@ class SequentialSubQuestionsWorkflow(Workflow):
|
|
|
322
341
|
print(f"Sub-question is {ev.question}")
|
|
323
342
|
agent = await ctx.get("agent")
|
|
324
343
|
sub_questions = await ctx.get("sub_questions")
|
|
344
|
+
question = ev.question
|
|
325
345
|
if ev.prev_answer:
|
|
326
346
|
prev_question = sub_questions[ev.num - 1]
|
|
327
347
|
prompt = f"""
|
|
328
348
|
The answer to the question '{prev_question}' is: '{ev.prev_answer}'
|
|
329
|
-
Now answer the following question: '{
|
|
349
|
+
Now answer the following question: '{question}'
|
|
330
350
|
"""
|
|
331
351
|
response = await agent.achat(prompt)
|
|
332
352
|
else:
|
|
333
|
-
response = await agent.achat(
|
|
353
|
+
response = await agent.achat(question)
|
|
354
|
+
answer = response.response
|
|
334
355
|
if await ctx.get("verbose"):
|
|
335
|
-
print(f"Answer is {
|
|
356
|
+
print(f"Answer is {answer}")
|
|
336
357
|
|
|
337
358
|
if ev.num + 1 < len(sub_questions):
|
|
359
|
+
await ctx.set("qna", await ctx.get("qna", []) + [(question, answer)])
|
|
338
360
|
return self.QueryEvent(
|
|
339
361
|
question=sub_questions[ev.num + 1],
|
|
340
|
-
prev_answer=
|
|
362
|
+
prev_answer=answer,
|
|
341
363
|
num=ev.num + 1,
|
|
342
364
|
)
|
|
343
365
|
|
|
344
|
-
output = self.OutputsModel(response=
|
|
366
|
+
output = self.OutputsModel(response=answer)
|
|
345
367
|
return StopEvent(result=output)
|
|
@@ -129,6 +129,8 @@ class VectaraToolFactory:
|
|
|
129
129
|
- 'type': the type of each filter attribute in Vectara (doc or part).
|
|
130
130
|
- 'is_list': whether the filterable attribute is a list.
|
|
131
131
|
- 'filter_name': the name of the filterable attribute in Vectara.
|
|
132
|
+
summarize_docs (bool, optional): Whether to summarize the retrieved documents.
|
|
133
|
+
summarize_llm_name (str, optional): The name of the LLM to use for summarization.
|
|
132
134
|
fixed_filter (str, optional): A fixed Vectara filter condition to apply to all queries.
|
|
133
135
|
lambda_val (Union[List[float] | float], optional): Lambda value (or list of values for each corpora)
|
|
134
136
|
for the Vectara query, when using hybrid search.
|
|
@@ -234,10 +236,13 @@ class VectaraToolFactory:
|
|
|
234
236
|
)
|
|
235
237
|
unique_ids = set()
|
|
236
238
|
docs = []
|
|
239
|
+
doc_matches = {}
|
|
237
240
|
for doc in response:
|
|
238
241
|
if doc.id_ in unique_ids:
|
|
242
|
+
doc_matches[doc.id_].append(doc.node.get_content())
|
|
239
243
|
continue
|
|
240
244
|
unique_ids.add(doc.id_)
|
|
245
|
+
doc_matches[doc.id_] = [doc.node.get_content()]
|
|
241
246
|
docs.append((doc.id_, doc.metadata))
|
|
242
247
|
tool_output = "Matching documents:\n"
|
|
243
248
|
if summarize:
|
|
@@ -251,11 +256,24 @@ class VectaraToolFactory:
|
|
|
251
256
|
)
|
|
252
257
|
for doc_id, metadata in docs:
|
|
253
258
|
summary = summaries_dict.get(doc_id, "")
|
|
254
|
-
|
|
259
|
+
matching_text = "\n".join(
|
|
260
|
+
f"<match {i}>{piece}</match {i}>"
|
|
261
|
+
for i, piece in enumerate(doc_matches[doc_id], start=1)
|
|
262
|
+
)
|
|
263
|
+
tool_output += (
|
|
264
|
+
f"document_id: '{doc_id}'\nmetadata: '{metadata}'\n"
|
|
265
|
+
f"matching texts: '{matching_text}'\n"
|
|
266
|
+
f"summary: '{summary}'\n\n"
|
|
267
|
+
)
|
|
255
268
|
else:
|
|
256
269
|
for doc_id, metadata in docs:
|
|
270
|
+
matching_text = "\n".join(
|
|
271
|
+
f"<match {i}>{piece}</match {i}>"
|
|
272
|
+
for i, piece in enumerate(doc_matches[doc_id], start=1)
|
|
273
|
+
)
|
|
257
274
|
tool_output += (
|
|
258
|
-
f"document_id: '{doc_id}'\nmetadata: '{metadata}'\n
|
|
275
|
+
f"document_id: '{doc_id}'\nmetadata: '{metadata}'\n"
|
|
276
|
+
f"matching texts: '{matching_text}'\n"
|
|
259
277
|
)
|
|
260
278
|
|
|
261
279
|
out = ToolOutput(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vectara_agentic
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.24
|
|
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
|
|
@@ -530,6 +530,9 @@ class MyWorkflow(Workflow):
|
|
|
530
530
|
class OutputsModel(BaseModel):
|
|
531
531
|
answer: str
|
|
532
532
|
|
|
533
|
+
class OutputModelOnFail(BaseModel):
|
|
534
|
+
partial_response: str = ""
|
|
535
|
+
|
|
533
536
|
@step
|
|
534
537
|
async def my_step(self, ev: StartEvent) -> StopEvent:
|
|
535
538
|
# do something here
|
|
@@ -587,6 +590,11 @@ workflow_result = asyncio.run(agent.run(inputs))
|
|
|
587
590
|
print(workflow_result.answer)
|
|
588
591
|
```
|
|
589
592
|
|
|
593
|
+
When a workflow reaches its timeout, the timeout handler builds and returns an `OutputModelOnFail`
|
|
594
|
+
by reading each field named in that model from the workflow’s Context; for any field that isn’t set in the context,
|
|
595
|
+
it uses the default value you’ve defined on `OutputModelOnFail`. In other words, every property in `OutputModelOnFail`
|
|
596
|
+
must declare a default so that even if the corresponding context variable is missing, the model can be fully populated and returned without errors.
|
|
597
|
+
|
|
590
598
|
### Built-in Workflows
|
|
591
599
|
|
|
592
600
|
`vectara-agentic` includes two workflow implementations that you can use right away:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vectara_agentic-0.2.22 → vectara_agentic-0.2.24}/vectara_agentic.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|