veadk-python 0.2.6__py3-none-any.whl → 0.2.8__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 veadk-python might be problematic. Click here for more details.
- veadk/agent.py +11 -18
- veadk/agent_builder.py +94 -0
- veadk/{database/__init__.py → auth/base_auth.py} +7 -2
- veadk/auth/veauth/apmplus_veauth.py +65 -0
- veadk/auth/veauth/ark_veauth.py +77 -0
- veadk/auth/veauth/base_veauth.py +50 -0
- veadk/auth/veauth/opensearch_veauth.py +75 -0
- veadk/auth/veauth/postgresql_veauth.py +75 -0
- veadk/auth/veauth/prompt_pilot_veauth.py +60 -0
- veadk/auth/veauth/vesearch_veauth.py +62 -0
- veadk/cli/cli.py +4 -0
- veadk/cli/cli_deploy.py +3 -2
- veadk/cli/cli_eval.py +160 -0
- veadk/cli/cli_init.py +1 -1
- veadk/cli/cli_pipeline.py +220 -0
- veadk/cli/cli_prompt.py +4 -4
- veadk/cli/cli_web.py +3 -1
- veadk/config.py +45 -81
- veadk/configs/database_configs.py +117 -0
- veadk/configs/model_configs.py +74 -0
- veadk/configs/tool_configs.py +42 -0
- veadk/configs/tracing_configs.py +110 -0
- veadk/consts.py +13 -1
- veadk/evaluation/base_evaluator.py +60 -44
- veadk/evaluation/deepeval_evaluator/deepeval_evaluator.py +18 -12
- veadk/evaluation/eval_set_recorder.py +2 -2
- veadk/integrations/ve_code_pipeline/__init__.py +13 -0
- veadk/integrations/ve_code_pipeline/ve_code_pipeline.py +431 -0
- veadk/integrations/ve_cozeloop/__init__.py +13 -0
- veadk/integrations/ve_cozeloop/ve_cozeloop.py +96 -0
- veadk/integrations/ve_cr/ve_cr.py +20 -5
- veadk/integrations/ve_faas/template/cookiecutter.json +1 -1
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/deploy.py +2 -2
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/agent.py +1 -1
- veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh +1 -5
- veadk/integrations/ve_faas/ve_faas.py +351 -36
- veadk/integrations/ve_prompt_pilot/ve_prompt_pilot.py +6 -3
- veadk/integrations/ve_tls/__init__.py +13 -0
- veadk/integrations/ve_tls/utils.py +117 -0
- veadk/integrations/ve_tls/ve_tls.py +208 -0
- veadk/integrations/ve_tos/ve_tos.py +71 -75
- veadk/knowledgebase/backends/__init__.py +13 -0
- veadk/knowledgebase/backends/base_backend.py +59 -0
- veadk/knowledgebase/backends/in_memory_backend.py +82 -0
- veadk/knowledgebase/backends/opensearch_backend.py +136 -0
- veadk/knowledgebase/backends/redis_backend.py +144 -0
- veadk/knowledgebase/backends/utils.py +91 -0
- veadk/knowledgebase/backends/vikingdb_knowledge_backend.py +412 -0
- veadk/knowledgebase/knowledgebase.py +109 -55
- veadk/memory/__init__.py +22 -0
- veadk/memory/long_term_memory.py +120 -51
- veadk/memory/long_term_memory_backends/__init__.py +13 -0
- veadk/{database/base_database.py → memory/long_term_memory_backends/base_backend.py} +10 -22
- veadk/memory/long_term_memory_backends/in_memory_backend.py +65 -0
- veadk/memory/long_term_memory_backends/opensearch_backend.py +120 -0
- veadk/memory/long_term_memory_backends/redis_backend.py +127 -0
- veadk/memory/long_term_memory_backends/vikingdb_memory_backend.py +148 -0
- veadk/memory/short_term_memory.py +80 -72
- veadk/memory/short_term_memory_backends/__init__.py +13 -0
- veadk/memory/short_term_memory_backends/base_backend.py +31 -0
- veadk/memory/short_term_memory_backends/mysql_backend.py +41 -0
- veadk/memory/short_term_memory_backends/postgresql_backend.py +41 -0
- veadk/memory/short_term_memory_backends/sqlite_backend.py +48 -0
- veadk/memory/short_term_memory_processor.py +9 -4
- veadk/runner.py +204 -247
- veadk/tools/builtin_tools/vesearch.py +2 -2
- veadk/tools/builtin_tools/video_generate.py +27 -20
- veadk/tools/builtin_tools/web_scraper.py +1 -1
- veadk/tools/builtin_tools/web_search.py +7 -7
- veadk/tools/load_knowledgebase_tool.py +1 -1
- veadk/tracing/telemetry/attributes/extractors/llm_attributes_extractors.py +20 -2
- veadk/tracing/telemetry/exporters/apmplus_exporter.py +178 -14
- veadk/tracing/telemetry/exporters/cozeloop_exporter.py +6 -9
- veadk/tracing/telemetry/exporters/inmemory_exporter.py +22 -8
- veadk/tracing/telemetry/exporters/tls_exporter.py +6 -10
- veadk/tracing/telemetry/opentelemetry_tracer.py +5 -8
- veadk/tracing/telemetry/telemetry.py +66 -60
- veadk/utils/logger.py +1 -1
- veadk/utils/misc.py +63 -0
- veadk/utils/volcengine_sign.py +6 -2
- veadk/version.py +1 -1
- {veadk_python-0.2.6.dist-info → veadk_python-0.2.8.dist-info}/METADATA +16 -3
- {veadk_python-0.2.6.dist-info → veadk_python-0.2.8.dist-info}/RECORD +93 -64
- veadk/database/database_adapter.py +0 -368
- veadk/database/database_factory.py +0 -80
- veadk/database/kv/redis_database.py +0 -159
- veadk/database/local_database.py +0 -61
- veadk/database/relational/mysql_database.py +0 -173
- veadk/database/vector/opensearch_vector_database.py +0 -263
- veadk/database/vector/type.py +0 -50
- veadk/database/viking/viking_database.py +0 -471
- veadk/database/viking/viking_memory_db.py +0 -525
- /veadk/{database/kv → auth}/__init__.py +0 -0
- /veadk/{database/relational → auth/veauth}/__init__.py +0 -0
- /veadk/{database/vector/__init__.py → auth/veauth/cozeloop_veauth.py} +0 -0
- /veadk/{database/viking → configs}/__init__.py +0 -0
- /veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{{ cookiecutter.app_name|replace('-', '_') }} → {{ cookiecutter.app_name }}}/__init__.py +0 -0
- /veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/{{{ cookiecutter.app_name|replace('-', '_') }} → {{ cookiecutter.app_name }}}/agent.py +0 -0
- {veadk_python-0.2.6.dist-info → veadk_python-0.2.8.dist-info}/WHEEL +0 -0
- {veadk_python-0.2.6.dist-info → veadk_python-0.2.8.dist-info}/entry_points.txt +0 -0
- {veadk_python-0.2.6.dist-info → veadk_python-0.2.8.dist-info}/licenses/LICENSE +0 -0
- {veadk_python-0.2.6.dist-info → veadk_python-0.2.8.dist-info}/top_level.txt +0 -0
veadk/runner.py
CHANGED
|
@@ -11,18 +11,20 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
import asyncio
|
|
16
|
+
import functools
|
|
17
|
+
from types import MethodType
|
|
15
18
|
from typing import Union
|
|
16
19
|
|
|
20
|
+
from google import genai
|
|
17
21
|
from google.adk.agents import RunConfig
|
|
22
|
+
from google.adk.agents.base_agent import BaseAgent
|
|
18
23
|
from google.adk.agents.invocation_context import LlmCallsLimitExceededError
|
|
19
|
-
from google.adk.agents.run_config import StreamingMode
|
|
20
|
-
from google.adk.plugins.base_plugin import BasePlugin
|
|
21
24
|
from google.adk.runners import Runner as ADKRunner
|
|
22
25
|
from google.genai import types
|
|
23
26
|
from google.genai.types import Blob
|
|
24
27
|
|
|
25
|
-
from veadk.a2a.remote_ve_agent import RemoteVeAgent
|
|
26
28
|
from veadk.agent import Agent
|
|
27
29
|
from veadk.agents.loop_agent import LoopAgent
|
|
28
30
|
from veadk.agents.parallel_agent import ParallelAgent
|
|
@@ -32,11 +34,10 @@ from veadk.evaluation import EvalSetRecorder
|
|
|
32
34
|
from veadk.memory.short_term_memory import ShortTermMemory
|
|
33
35
|
from veadk.types import MediaMessage
|
|
34
36
|
from veadk.utils.logger import get_logger
|
|
35
|
-
from veadk.utils.misc import read_png_to_bytes
|
|
37
|
+
from veadk.utils.misc import formatted_timestamp, read_png_to_bytes
|
|
36
38
|
|
|
37
39
|
logger = get_logger(__name__)
|
|
38
40
|
|
|
39
|
-
|
|
40
41
|
RunnerMessage = Union[
|
|
41
42
|
str, # single turn text-based prompt
|
|
42
43
|
list[str], # multiple turn text-based prompt
|
|
@@ -45,133 +46,227 @@ RunnerMessage = Union[
|
|
|
45
46
|
list[MediaMessage | str], # multiple turn prompt with media and text-based prompt
|
|
46
47
|
]
|
|
47
48
|
|
|
48
|
-
VeAgent = Union[Agent, RemoteVeAgent, SequentialAgent, ParallelAgent, LoopAgent]
|
|
49
49
|
|
|
50
|
+
def pre_run_process(self, process_func, new_message, user_id, session_id):
|
|
51
|
+
if new_message.parts:
|
|
52
|
+
for part in new_message.parts:
|
|
53
|
+
if (
|
|
54
|
+
part.inline_data
|
|
55
|
+
and part.inline_data.mime_type == "image/png"
|
|
56
|
+
and self.upload_inline_data_to_tos
|
|
57
|
+
):
|
|
58
|
+
process_func(
|
|
59
|
+
part,
|
|
60
|
+
self.app_name,
|
|
61
|
+
user_id,
|
|
62
|
+
session_id,
|
|
63
|
+
)
|
|
64
|
+
return
|
|
50
65
|
|
|
51
|
-
class Runner:
|
|
52
|
-
def __init__(
|
|
53
|
-
self,
|
|
54
|
-
agent: VeAgent,
|
|
55
|
-
short_term_memory: ShortTermMemory | None = None,
|
|
56
|
-
plugins: list[BasePlugin] | None = None,
|
|
57
|
-
app_name: str = "veadk_default_app",
|
|
58
|
-
user_id: str = "veadk_default_user",
|
|
59
|
-
):
|
|
60
|
-
self.app_name = app_name
|
|
61
|
-
self.user_id = user_id
|
|
62
66
|
|
|
63
|
-
|
|
67
|
+
def post_run_process(self):
|
|
68
|
+
return
|
|
64
69
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
70
|
+
|
|
71
|
+
def intercept_new_message(process_func):
|
|
72
|
+
def decorator(func):
|
|
73
|
+
@functools.wraps(func)
|
|
74
|
+
async def wrapper(
|
|
75
|
+
self,
|
|
76
|
+
*,
|
|
77
|
+
user_id: str,
|
|
78
|
+
session_id: str,
|
|
79
|
+
new_message: types.Content,
|
|
80
|
+
**kwargs,
|
|
81
|
+
):
|
|
82
|
+
pre_run_process(self, process_func, new_message, user_id, session_id)
|
|
83
|
+
|
|
84
|
+
async for event in func(
|
|
85
|
+
user_id=user_id,
|
|
86
|
+
session_id=session_id,
|
|
87
|
+
new_message=new_message,
|
|
88
|
+
**kwargs,
|
|
89
|
+
):
|
|
90
|
+
yield event
|
|
91
|
+
|
|
92
|
+
post_run_process(self)
|
|
93
|
+
|
|
94
|
+
return wrapper
|
|
95
|
+
|
|
96
|
+
return decorator
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _convert_messages(
|
|
100
|
+
messages: RunnerMessage,
|
|
101
|
+
app_name: str,
|
|
102
|
+
user_id: str,
|
|
103
|
+
session_id: str,
|
|
104
|
+
) -> list:
|
|
105
|
+
"""Convert VeADK formatted messages to Google ADK formatted messages."""
|
|
106
|
+
if isinstance(messages, str):
|
|
107
|
+
_messages = [types.Content(role="user", parts=[types.Part(text=messages)])]
|
|
108
|
+
elif isinstance(messages, MediaMessage):
|
|
109
|
+
assert messages.media.endswith(".png"), (
|
|
110
|
+
"The MediaMessage only supports PNG format file for now."
|
|
111
|
+
)
|
|
112
|
+
_messages = [
|
|
113
|
+
types.Content(
|
|
114
|
+
role="user",
|
|
115
|
+
parts=[
|
|
116
|
+
types.Part(text=messages.text),
|
|
117
|
+
types.Part(
|
|
118
|
+
inline_data=Blob(
|
|
119
|
+
display_name=messages.media,
|
|
120
|
+
data=read_png_to_bytes(messages.media),
|
|
121
|
+
mime_type="image/png",
|
|
122
|
+
)
|
|
123
|
+
),
|
|
124
|
+
],
|
|
68
125
|
)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
126
|
+
]
|
|
127
|
+
elif isinstance(messages, list):
|
|
128
|
+
converted_messages = []
|
|
129
|
+
for message in messages:
|
|
130
|
+
converted_messages.extend(
|
|
131
|
+
_convert_messages(message, app_name, user_id, session_id)
|
|
132
|
+
)
|
|
133
|
+
_messages = converted_messages
|
|
134
|
+
else:
|
|
135
|
+
raise ValueError(f"Unknown message type: {type(messages)}")
|
|
72
136
|
|
|
73
|
-
|
|
137
|
+
return _messages
|
|
74
138
|
|
|
75
|
-
# prevent VeRemoteAgent has no long-term memory attr
|
|
76
|
-
if isinstance(self.agent, Agent):
|
|
77
|
-
self.long_term_memory = self.agent.long_term_memory
|
|
78
|
-
else:
|
|
79
|
-
self.long_term_memory = None
|
|
80
139
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
140
|
+
def _upload_image_to_tos(
|
|
141
|
+
part: genai.types.Part, app_name: str, user_id: str, session_id: str
|
|
142
|
+
) -> None:
|
|
143
|
+
try:
|
|
144
|
+
if part.inline_data and part.inline_data.display_name and part.inline_data.data:
|
|
145
|
+
from veadk.integrations.ve_tos.ve_tos import VeTOS
|
|
146
|
+
|
|
147
|
+
ve_tos = VeTOS()
|
|
88
148
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
elif isinstance(messages, MediaMessage):
|
|
95
|
-
assert messages.media.endswith(".png"), (
|
|
96
|
-
"The MediaMessage only supports PNG format file for now."
|
|
149
|
+
object_key, tos_url = ve_tos.build_tos_url(
|
|
150
|
+
user_id=user_id,
|
|
151
|
+
app_name=app_name,
|
|
152
|
+
session_id=session_id,
|
|
153
|
+
data_path=part.inline_data.display_name,
|
|
97
154
|
)
|
|
98
|
-
data = read_png_to_bytes(messages.media)
|
|
99
|
-
tos_url = "<tos_url>"
|
|
100
|
-
if upload_inline_data_to_tos:
|
|
101
|
-
try:
|
|
102
|
-
from veadk.integrations.ve_tos.ve_tos import VeTOS
|
|
103
|
-
|
|
104
|
-
ve_tos = VeTOS()
|
|
105
|
-
object_key, tos_url = ve_tos.build_tos_url(
|
|
106
|
-
self.user_id, self.app_name, session_id, messages.media
|
|
107
|
-
)
|
|
108
|
-
upload_task = ve_tos.upload(object_key, data)
|
|
109
|
-
if upload_task is not None:
|
|
110
|
-
asyncio.create_task(upload_task)
|
|
111
|
-
except Exception as e:
|
|
112
|
-
logger.error(f"Upload to TOS failed: {e}")
|
|
113
|
-
tos_url = None
|
|
114
155
|
|
|
115
|
-
|
|
156
|
+
upload_task = ve_tos.upload(object_key, part.inline_data.data)
|
|
157
|
+
|
|
158
|
+
if upload_task is not None:
|
|
159
|
+
asyncio.create_task(upload_task)
|
|
160
|
+
|
|
161
|
+
part.inline_data.display_name = tos_url
|
|
162
|
+
except Exception as e:
|
|
163
|
+
logger.error(f"Upload to TOS failed: {e}")
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class Runner(ADKRunner):
|
|
167
|
+
def __init__(
|
|
168
|
+
self,
|
|
169
|
+
agent: BaseAgent | Agent,
|
|
170
|
+
short_term_memory: ShortTermMemory | None = None,
|
|
171
|
+
app_name: str = "veadk_default_app",
|
|
172
|
+
user_id: str = "veadk_default_user",
|
|
173
|
+
upload_inline_data_to_tos: bool = False,
|
|
174
|
+
*args,
|
|
175
|
+
**kwargs,
|
|
176
|
+
) -> None:
|
|
177
|
+
self.user_id = user_id
|
|
178
|
+
self.long_term_memory = None
|
|
179
|
+
self.short_term_memory = short_term_memory
|
|
180
|
+
self.upload_inline_data_to_tos = upload_inline_data_to_tos
|
|
181
|
+
|
|
182
|
+
session_service = kwargs.pop("session_service", None)
|
|
183
|
+
memory_service = kwargs.pop("memory_service", None)
|
|
184
|
+
|
|
185
|
+
if session_service:
|
|
186
|
+
if short_term_memory:
|
|
116
187
|
logger.warning(
|
|
117
|
-
"
|
|
188
|
+
"Short term memory is enabled, but session service is also provided. We will use session service from runner argument."
|
|
118
189
|
)
|
|
119
190
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
types.Part(
|
|
126
|
-
inline_data=Blob(
|
|
127
|
-
display_name=tos_url,
|
|
128
|
-
data=data,
|
|
129
|
-
mime_type="image/png",
|
|
130
|
-
)
|
|
131
|
-
),
|
|
132
|
-
],
|
|
191
|
+
if not session_service:
|
|
192
|
+
if short_term_memory:
|
|
193
|
+
session_service = short_term_memory.session_service
|
|
194
|
+
logger.debug(
|
|
195
|
+
f"Use session service {session_service} from short term memory."
|
|
133
196
|
)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
for message in messages:
|
|
138
|
-
converted_messages.extend(
|
|
139
|
-
self._convert_messages(
|
|
140
|
-
message, session_id, upload_inline_data_to_tos
|
|
141
|
-
)
|
|
197
|
+
else:
|
|
198
|
+
logger.warning(
|
|
199
|
+
"No short term memory or session service provided, use an in-memory one instead."
|
|
142
200
|
)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
201
|
+
short_term_memory = ShortTermMemory()
|
|
202
|
+
self.short_term_memory = short_term_memory
|
|
203
|
+
session_service = short_term_memory.session_service
|
|
146
204
|
|
|
147
|
-
|
|
205
|
+
if memory_service:
|
|
206
|
+
if hasattr(agent, "long_term_memory") and agent.long_term_memory: # type: ignore
|
|
207
|
+
self.long_term_memory = agent.long_term_memory # type: ignore
|
|
208
|
+
logger.warning(
|
|
209
|
+
"Long term memory in agent is enabled, but memory service is also provided. We will use memory service from runner argument."
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
if not memory_service:
|
|
213
|
+
if hasattr(agent, "long_term_memory") and agent.long_term_memory: # type: ignore
|
|
214
|
+
self.long_term_memory = agent.long_term_memory # type: ignore
|
|
215
|
+
memory_service = agent.long_term_memory # type: ignore
|
|
216
|
+
else:
|
|
217
|
+
logger.info("No long term memory provided.")
|
|
218
|
+
|
|
219
|
+
super().__init__(
|
|
220
|
+
agent=agent,
|
|
221
|
+
session_service=session_service,
|
|
222
|
+
memory_service=memory_service,
|
|
223
|
+
app_name=app_name,
|
|
224
|
+
*args,
|
|
225
|
+
**kwargs,
|
|
226
|
+
)
|
|
148
227
|
|
|
149
|
-
|
|
228
|
+
self.run_async = MethodType(
|
|
229
|
+
intercept_new_message(_upload_image_to_tos)(self.run_async), self
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
async def run(
|
|
150
233
|
self,
|
|
151
|
-
|
|
152
|
-
|
|
234
|
+
messages: RunnerMessage,
|
|
235
|
+
user_id: str = "",
|
|
236
|
+
session_id: str = f"tmp-session-{formatted_timestamp()}",
|
|
153
237
|
run_config: RunConfig | None = None,
|
|
154
|
-
|
|
238
|
+
save_tracing_data: bool = False,
|
|
239
|
+
upload_inline_data_to_tos: bool = False,
|
|
155
240
|
):
|
|
156
|
-
|
|
241
|
+
if upload_inline_data_to_tos:
|
|
242
|
+
_upload_inline_data_to_tos = self.upload_inline_data_to_tos
|
|
243
|
+
self.upload_inline_data_to_tos = upload_inline_data_to_tos
|
|
157
244
|
|
|
158
|
-
if
|
|
159
|
-
stream_mode = run_config.streaming_mode
|
|
160
|
-
else:
|
|
245
|
+
if not run_config:
|
|
161
246
|
run_config = RunConfig(
|
|
162
|
-
streaming_mode=stream_mode,
|
|
247
|
+
# streaming_mode=stream_mode,
|
|
163
248
|
max_llm_calls=int(getenv("MODEL_AGENT_MAX_LLM_CALLS", 100)),
|
|
164
249
|
)
|
|
165
|
-
|
|
166
250
|
logger.info(f"Run config: {run_config}")
|
|
167
251
|
|
|
168
|
-
|
|
252
|
+
user_id = user_id or self.user_id
|
|
253
|
+
|
|
254
|
+
converted_messages: list = _convert_messages(
|
|
255
|
+
messages, self.app_name, user_id, session_id
|
|
256
|
+
)
|
|
169
257
|
|
|
170
|
-
|
|
171
|
-
|
|
258
|
+
if self.short_term_memory:
|
|
259
|
+
await self.short_term_memory.create_session(
|
|
260
|
+
app_name=self.app_name, user_id=self.user_id, session_id=session_id
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
final_output = ""
|
|
264
|
+
for converted_message in converted_messages:
|
|
265
|
+
try:
|
|
266
|
+
async for event in self.run_async(
|
|
172
267
|
user_id=self.user_id,
|
|
173
268
|
session_id=session_id,
|
|
174
|
-
new_message=
|
|
269
|
+
new_message=converted_message,
|
|
175
270
|
run_config=run_config,
|
|
176
271
|
):
|
|
177
272
|
if event.get_function_calls():
|
|
@@ -183,45 +278,10 @@ class Runner:
|
|
|
183
278
|
and event.content.parts[0].text is not None
|
|
184
279
|
and len(event.content.parts[0].text.strip()) > 0
|
|
185
280
|
):
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if stream:
|
|
191
|
-
print(chunk, end="", flush=True)
|
|
192
|
-
final_output += chunk
|
|
193
|
-
if stream:
|
|
194
|
-
print() # end with a new line
|
|
195
|
-
except LlmCallsLimitExceededError as e:
|
|
196
|
-
logger.warning(f"Max number of llm calls limit exceeded: {e}")
|
|
197
|
-
final_output = ""
|
|
198
|
-
|
|
199
|
-
return final_output
|
|
200
|
-
|
|
201
|
-
async def run(
|
|
202
|
-
self,
|
|
203
|
-
messages: RunnerMessage,
|
|
204
|
-
session_id: str,
|
|
205
|
-
stream: bool = False,
|
|
206
|
-
run_config: RunConfig | None = None,
|
|
207
|
-
save_tracing_data: bool = False,
|
|
208
|
-
upload_inline_data_to_tos: bool = False,
|
|
209
|
-
):
|
|
210
|
-
converted_messages: list = self._convert_messages(
|
|
211
|
-
messages, session_id, upload_inline_data_to_tos
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
await self.short_term_memory.create_session(
|
|
215
|
-
app_name=self.app_name, user_id=self.user_id, session_id=session_id
|
|
216
|
-
)
|
|
217
|
-
|
|
218
|
-
logger.info("Begin to process user messages.")
|
|
219
|
-
|
|
220
|
-
final_output = ""
|
|
221
|
-
for converted_message in converted_messages:
|
|
222
|
-
final_output = await self._run(
|
|
223
|
-
session_id, converted_message, run_config, stream
|
|
224
|
-
)
|
|
281
|
+
final_output += event.content.parts[0].text
|
|
282
|
+
except LlmCallsLimitExceededError as e:
|
|
283
|
+
logger.warning(f"Max number of llm calls limit exceeded: {e}")
|
|
284
|
+
final_output = ""
|
|
225
285
|
|
|
226
286
|
# try to save tracing file
|
|
227
287
|
if save_tracing_data:
|
|
@@ -229,6 +289,9 @@ class Runner:
|
|
|
229
289
|
|
|
230
290
|
self._print_trace_id()
|
|
231
291
|
|
|
292
|
+
if upload_inline_data_to_tos:
|
|
293
|
+
self.upload_inline_data_to_tos = _upload_inline_data_to_tos # type: ignore
|
|
294
|
+
|
|
232
295
|
return final_output
|
|
233
296
|
|
|
234
297
|
def get_trace_id(self) -> str:
|
|
@@ -251,54 +314,6 @@ class Runner:
|
|
|
251
314
|
logger.warning(f"Get tracer id failed as {e}")
|
|
252
315
|
return "<unknown_trace_id>"
|
|
253
316
|
|
|
254
|
-
async def run_with_raw_message(
|
|
255
|
-
self,
|
|
256
|
-
message: types.Content,
|
|
257
|
-
session_id: str,
|
|
258
|
-
run_config: RunConfig | None = None,
|
|
259
|
-
):
|
|
260
|
-
run_config = (
|
|
261
|
-
RunConfig(max_llm_calls=int(getenv("MODEL_AGENT_MAX_LLM_CALLS", 100)))
|
|
262
|
-
if not run_config
|
|
263
|
-
else run_config
|
|
264
|
-
)
|
|
265
|
-
|
|
266
|
-
logger.info(f"Run config: {run_config}")
|
|
267
|
-
|
|
268
|
-
await self.short_term_memory.create_session(
|
|
269
|
-
app_name=self.app_name, user_id=self.user_id, session_id=session_id
|
|
270
|
-
)
|
|
271
|
-
|
|
272
|
-
try:
|
|
273
|
-
|
|
274
|
-
async def event_generator():
|
|
275
|
-
async for event in self.runner.run_async(
|
|
276
|
-
user_id=self.user_id,
|
|
277
|
-
session_id=session_id,
|
|
278
|
-
new_message=message,
|
|
279
|
-
run_config=run_config,
|
|
280
|
-
):
|
|
281
|
-
if event.get_function_calls():
|
|
282
|
-
for function_call in event.get_function_calls():
|
|
283
|
-
logger.debug(f"Function call: {function_call}")
|
|
284
|
-
elif (
|
|
285
|
-
event.content is not None
|
|
286
|
-
and event.content.parts
|
|
287
|
-
and event.content.parts[0].text is not None
|
|
288
|
-
and len(event.content.parts[0].text.strip()) > 0
|
|
289
|
-
):
|
|
290
|
-
yield event.content.parts[0].text
|
|
291
|
-
|
|
292
|
-
final_output = ""
|
|
293
|
-
|
|
294
|
-
async for chunk in event_generator():
|
|
295
|
-
final_output += chunk
|
|
296
|
-
except LlmCallsLimitExceededError as e:
|
|
297
|
-
logger.warning(f"Max number of llm calls limit exceeded: {e}")
|
|
298
|
-
final_output = ""
|
|
299
|
-
|
|
300
|
-
return final_output
|
|
301
|
-
|
|
302
317
|
def _print_trace_id(self) -> None:
|
|
303
318
|
if not isinstance(self.agent, Agent):
|
|
304
319
|
logger.warning(
|
|
@@ -369,61 +384,3 @@ class Runner:
|
|
|
369
384
|
|
|
370
385
|
await self.long_term_memory.add_session_to_memory(session)
|
|
371
386
|
logger.info(f"Add session `{session.id}` to long term memory.")
|
|
372
|
-
|
|
373
|
-
# [deprecated] we will not host a chat-service in VeADK, so the following two methods are deprecated
|
|
374
|
-
|
|
375
|
-
# async def run_with_final_event(
|
|
376
|
-
# self,
|
|
377
|
-
# messages: RunnerMessage,
|
|
378
|
-
# session_id: str,
|
|
379
|
-
# ):
|
|
380
|
-
# """non-streaming run with final event"""
|
|
381
|
-
# messages: list = self._convert_messages(messages)
|
|
382
|
-
|
|
383
|
-
# await self.short_term_memory.create_session(
|
|
384
|
-
# app_name=self.app_name, user_id=self.user_id, session_id=session_id
|
|
385
|
-
# )
|
|
386
|
-
|
|
387
|
-
# logger.info("Begin to process user messages.")
|
|
388
|
-
|
|
389
|
-
# final_event = ""
|
|
390
|
-
# async for event in self.runner.run_async(
|
|
391
|
-
# user_id=self.user_id, session_id=session_id, new_message=messages[0]
|
|
392
|
-
# ):
|
|
393
|
-
# if event.get_function_calls():
|
|
394
|
-
# for function_call in event.get_function_calls():
|
|
395
|
-
# logger.debug(f"Function call: {function_call}")
|
|
396
|
-
# elif (
|
|
397
|
-
# not event.partial
|
|
398
|
-
# and event.content.parts[0].text is not None
|
|
399
|
-
# and len(event.content.parts[0].text.strip()) > 0
|
|
400
|
-
# ):
|
|
401
|
-
# final_event = event.model_dump_json(exclude_none=True, by_alias=True)
|
|
402
|
-
|
|
403
|
-
# return final_event
|
|
404
|
-
|
|
405
|
-
# async def run_sse(
|
|
406
|
-
# self,
|
|
407
|
-
# session_id: str,
|
|
408
|
-
# prompt: str,
|
|
409
|
-
# ):
|
|
410
|
-
# message = types.Content(role="user", parts=[types.Part(text=prompt)])
|
|
411
|
-
|
|
412
|
-
# await self.short_term_memory.create_session(
|
|
413
|
-
# app_name=self.app_name, user_id=self.user_id, session_id=session_id
|
|
414
|
-
# )
|
|
415
|
-
|
|
416
|
-
# logger.info("Begin to process user messages under SSE method.")
|
|
417
|
-
|
|
418
|
-
# async for event in self.runner.run_async(
|
|
419
|
-
# user_id=self.user_id,
|
|
420
|
-
# session_id=session_id,
|
|
421
|
-
# new_message=message,
|
|
422
|
-
# run_config=RunConfig(streaming_mode=StreamingMode.SSE),
|
|
423
|
-
# ):
|
|
424
|
-
# # Format as SSE data
|
|
425
|
-
# sse_event = event.model_dump_json(exclude_none=True, by_alias=True)
|
|
426
|
-
# if event.get_function_calls():
|
|
427
|
-
# for function_call in event.get_function_calls():
|
|
428
|
-
# logger.debug(f"SSE function call event: {sse_event}")
|
|
429
|
-
# yield f"data: {sse_event}\n\n"
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import requests
|
|
16
16
|
|
|
17
|
-
from veadk.config import getenv
|
|
17
|
+
from veadk.config import getenv, settings
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def vesearch(query: str) -> str:
|
|
@@ -26,7 +26,7 @@ def vesearch(query: str) -> str:
|
|
|
26
26
|
Returns:
|
|
27
27
|
Summarized search results.
|
|
28
28
|
"""
|
|
29
|
-
api_key =
|
|
29
|
+
api_key = settings.tool.vesearch.api_key
|
|
30
30
|
bot_id = str(getenv("TOOL_VESEARCH_ENDPOINT"))
|
|
31
31
|
|
|
32
32
|
if api_key == "":
|
|
@@ -12,18 +12,22 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
from google.adk.tools import ToolContext
|
|
17
|
-
from volcenginesdkarkruntime import Ark
|
|
18
|
-
from veadk.config import getenv
|
|
15
|
+
import json
|
|
19
16
|
import time
|
|
20
17
|
import traceback
|
|
21
|
-
import
|
|
22
|
-
|
|
18
|
+
from typing import Dict, cast
|
|
19
|
+
|
|
20
|
+
from google.adk.tools import ToolContext
|
|
23
21
|
from opentelemetry import trace
|
|
24
22
|
from opentelemetry.trace import Span
|
|
23
|
+
from volcenginesdkarkruntime import Ark
|
|
24
|
+
from volcenginesdkarkruntime.types.content_generation.create_task_content_param import (
|
|
25
|
+
CreateTaskContentParam,
|
|
26
|
+
)
|
|
25
27
|
|
|
28
|
+
from veadk.config import getenv
|
|
26
29
|
from veadk.utils.logger import get_logger
|
|
30
|
+
from veadk.version import VERSION
|
|
27
31
|
|
|
28
32
|
logger = get_logger(__name__)
|
|
29
33
|
|
|
@@ -47,13 +51,16 @@ async def generate(prompt, first_frame_image=None, last_frame_image=None):
|
|
|
47
51
|
logger.debug("first frame generation")
|
|
48
52
|
response = client.content_generation.tasks.create(
|
|
49
53
|
model=getenv("MODEL_VIDEO_NAME"),
|
|
50
|
-
content=
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"type": "
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
content=cast(
|
|
55
|
+
list[CreateTaskContentParam], # avoid IDE warning
|
|
56
|
+
[
|
|
57
|
+
{"type": "text", "text": prompt},
|
|
58
|
+
{
|
|
59
|
+
"type": "image_url",
|
|
60
|
+
"image_url": {"url": first_frame_image},
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
),
|
|
57
64
|
)
|
|
58
65
|
else:
|
|
59
66
|
logger.debug("last frame generation")
|
|
@@ -277,13 +284,13 @@ async def video_generate(params: list, tool_context: ToolContext) -> Dict:
|
|
|
277
284
|
def add_span_attributes(
|
|
278
285
|
span: Span,
|
|
279
286
|
tool_context: ToolContext,
|
|
280
|
-
input_part: dict = None,
|
|
281
|
-
output_part: dict = None,
|
|
282
|
-
input_tokens: int = None,
|
|
283
|
-
output_tokens: int = None,
|
|
284
|
-
total_tokens: int = None,
|
|
285
|
-
request_model: str = None,
|
|
286
|
-
response_model: str = None,
|
|
287
|
+
input_part: dict | None = None,
|
|
288
|
+
output_part: dict | None = None,
|
|
289
|
+
input_tokens: int | None = None,
|
|
290
|
+
output_tokens: int | None = None,
|
|
291
|
+
total_tokens: int | None = None,
|
|
292
|
+
request_model: str | None = None,
|
|
293
|
+
response_model: str | None = None,
|
|
287
294
|
):
|
|
288
295
|
try:
|
|
289
296
|
# common attributes
|
|
@@ -180,13 +180,13 @@ def web_search(query: str) -> list[str]:
|
|
|
180
180
|
"WebSearch",
|
|
181
181
|
json.dumps(req),
|
|
182
182
|
)
|
|
183
|
+
|
|
183
184
|
try:
|
|
184
185
|
results: list = response_body["Result"]["WebResults"]
|
|
186
|
+
final_results = []
|
|
187
|
+
for result in results:
|
|
188
|
+
final_results.append(result["Summary"].strip())
|
|
189
|
+
return final_results
|
|
185
190
|
except Exception as e:
|
|
186
|
-
logger.error(f"Web search failed
|
|
187
|
-
return []
|
|
188
|
-
|
|
189
|
-
final_results = []
|
|
190
|
-
for result in results:
|
|
191
|
-
final_results.append(result["Summary"].strip())
|
|
192
|
-
return final_results
|
|
191
|
+
logger.error(f"Web search failed {e}, response body: {response_body}")
|
|
192
|
+
return [response_body]
|
|
@@ -55,7 +55,7 @@ async def search_knowledgebase(
|
|
|
55
55
|
) -> SearchKnowledgebaseResponse:
|
|
56
56
|
"""Searches the knowledgebase of the current user."""
|
|
57
57
|
if isinstance(knowledgebase, KnowledgeBase):
|
|
58
|
-
res = knowledgebase.search(query
|
|
58
|
+
res = knowledgebase.search(query)
|
|
59
59
|
entry_list = []
|
|
60
60
|
for r in res:
|
|
61
61
|
entry_list.append(KnowledgebaseEntry(content=r))
|