veadk-python 0.1.0__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/__init__.py +31 -0
- veadk/a2a/__init__.py +13 -0
- veadk/a2a/agent_card.py +45 -0
- veadk/a2a/remote_ve_agent.py +19 -0
- veadk/a2a/ve_a2a_server.py +77 -0
- veadk/a2a/ve_agent_executor.py +78 -0
- veadk/a2a/ve_task_store.py +37 -0
- veadk/agent.py +253 -0
- veadk/cli/__init__.py +13 -0
- veadk/cli/main.py +278 -0
- veadk/cli/services/agentpilot/__init__.py +17 -0
- veadk/cli/services/agentpilot/agentpilot.py +77 -0
- veadk/cli/services/veapig/__init__.py +17 -0
- veadk/cli/services/veapig/apig.py +224 -0
- veadk/cli/services/veapig/apig_utils.py +332 -0
- veadk/cli/services/vefaas/__init__.py +17 -0
- veadk/cli/services/vefaas/template/deploy.py +44 -0
- veadk/cli/services/vefaas/template/src/app.py +30 -0
- veadk/cli/services/vefaas/template/src/config.py +58 -0
- veadk/cli/services/vefaas/vefaas.py +346 -0
- veadk/cli/services/vefaas/vefaas_utils.py +408 -0
- veadk/cli/services/vetls/__init__.py +17 -0
- veadk/cli/services/vetls/vetls.py +87 -0
- veadk/cli/studio/__init__.py +13 -0
- veadk/cli/studio/agent_processor.py +247 -0
- veadk/cli/studio/fast_api.py +232 -0
- veadk/cli/studio/model.py +116 -0
- veadk/cloud/__init__.py +13 -0
- veadk/cloud/cloud_agent_engine.py +144 -0
- veadk/cloud/cloud_app.py +123 -0
- veadk/cloud/template/app.py +30 -0
- veadk/cloud/template/config.py +55 -0
- veadk/config.py +131 -0
- veadk/consts.py +17 -0
- veadk/database/__init__.py +17 -0
- veadk/database/base_database.py +45 -0
- veadk/database/database_factory.py +80 -0
- veadk/database/kv/__init__.py +13 -0
- veadk/database/kv/redis_database.py +109 -0
- veadk/database/local_database.py +43 -0
- veadk/database/relational/__init__.py +13 -0
- veadk/database/relational/mysql_database.py +114 -0
- veadk/database/vector/__init__.py +13 -0
- veadk/database/vector/opensearch_vector_database.py +205 -0
- veadk/database/vector/type.py +50 -0
- veadk/database/viking/__init__.py +13 -0
- veadk/database/viking/viking_database.py +378 -0
- veadk/database/viking/viking_memory_db.py +521 -0
- veadk/evaluation/__init__.py +17 -0
- veadk/evaluation/adk_evaluator/__init__.py +13 -0
- veadk/evaluation/adk_evaluator/adk_evaluator.py +291 -0
- veadk/evaluation/base_evaluator.py +242 -0
- veadk/evaluation/deepeval_evaluator/__init__.py +17 -0
- veadk/evaluation/deepeval_evaluator/deepeval_evaluator.py +223 -0
- veadk/evaluation/eval_set_file_loader.py +28 -0
- veadk/evaluation/eval_set_recorder.py +91 -0
- veadk/evaluation/utils/prometheus.py +142 -0
- veadk/knowledgebase/__init__.py +17 -0
- veadk/knowledgebase/knowledgebase.py +83 -0
- veadk/knowledgebase/knowledgebase_database_adapter.py +259 -0
- veadk/memory/__init__.py +13 -0
- veadk/memory/long_term_memory.py +119 -0
- veadk/memory/memory_database_adapter.py +235 -0
- veadk/memory/short_term_memory.py +124 -0
- veadk/memory/short_term_memory_processor.py +90 -0
- veadk/prompts/__init__.py +13 -0
- veadk/prompts/agent_default_prompt.py +30 -0
- veadk/prompts/prompt_evaluator.py +20 -0
- veadk/prompts/prompt_memory_processor.py +55 -0
- veadk/prompts/prompt_optimization.py +158 -0
- veadk/runner.py +252 -0
- veadk/tools/__init__.py +13 -0
- veadk/tools/builtin_tools/__init__.py +13 -0
- veadk/tools/builtin_tools/lark.py +67 -0
- veadk/tools/builtin_tools/las.py +23 -0
- veadk/tools/builtin_tools/vesearch.py +49 -0
- veadk/tools/builtin_tools/web_scraper.py +76 -0
- veadk/tools/builtin_tools/web_search.py +192 -0
- veadk/tools/demo_tools.py +58 -0
- veadk/tools/load_knowledgebase_tool.py +144 -0
- veadk/tools/sandbox/__init__.py +13 -0
- veadk/tools/sandbox/browser_sandbox.py +27 -0
- veadk/tools/sandbox/code_sandbox.py +30 -0
- veadk/tools/sandbox/computer_sandbox.py +27 -0
- veadk/tracing/__init__.py +13 -0
- veadk/tracing/base_tracer.py +172 -0
- veadk/tracing/telemetry/__init__.py +13 -0
- veadk/tracing/telemetry/exporters/__init__.py +13 -0
- veadk/tracing/telemetry/exporters/apiserver_exporter.py +60 -0
- veadk/tracing/telemetry/exporters/apmplus_exporter.py +101 -0
- veadk/tracing/telemetry/exporters/base_exporter.py +28 -0
- veadk/tracing/telemetry/exporters/cozeloop_exporter.py +69 -0
- veadk/tracing/telemetry/exporters/inmemory_exporter.py +88 -0
- veadk/tracing/telemetry/exporters/tls_exporter.py +78 -0
- veadk/tracing/telemetry/metrics/__init__.py +13 -0
- veadk/tracing/telemetry/metrics/opentelemetry_metrics.py +73 -0
- veadk/tracing/telemetry/opentelemetry_tracer.py +167 -0
- veadk/types.py +23 -0
- veadk/utils/__init__.py +13 -0
- veadk/utils/logger.py +59 -0
- veadk/utils/misc.py +33 -0
- veadk/utils/patches.py +85 -0
- veadk/utils/volcengine_sign.py +199 -0
- veadk/version.py +15 -0
- veadk_python-0.1.0.dist-info/METADATA +124 -0
- veadk_python-0.1.0.dist-info/RECORD +110 -0
- veadk_python-0.1.0.dist-info/WHEEL +5 -0
- veadk_python-0.1.0.dist-info/entry_points.txt +2 -0
- veadk_python-0.1.0.dist-info/licenses/LICENSE +201 -0
- veadk_python-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
import json
|
|
17
|
+
import os
|
|
18
|
+
|
|
19
|
+
from deepeval.metrics import GEval
|
|
20
|
+
from deepeval.test_case import LLMTestCaseParams
|
|
21
|
+
from google.adk.agents.callback_context import CallbackContext
|
|
22
|
+
from google.adk.cli.utils.agent_loader import AgentLoader
|
|
23
|
+
from google.adk.models.llm_response import LlmResponse
|
|
24
|
+
|
|
25
|
+
from veadk.agent import Agent
|
|
26
|
+
from veadk.cli.services.agentpilot.agentpilot import AgentPilot
|
|
27
|
+
from veadk.config import getenv
|
|
28
|
+
from veadk.evaluation.deepeval_evaluator.deepeval_evaluator import DeepevalEvaluator
|
|
29
|
+
from veadk.evaluation.eval_set_recorder import EvalSetRecorder
|
|
30
|
+
from veadk.memory.short_term_memory import ShortTermMemory
|
|
31
|
+
from veadk.runner import Runner
|
|
32
|
+
from veadk.tracing.telemetry.exporters.inmemory_exporter import InMemoryExporter
|
|
33
|
+
from veadk.tracing.telemetry.opentelemetry_tracer import OpentelemetryTracer
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class AgentProcessor:
|
|
37
|
+
def __init__(self, agents_dir: str = ""):
|
|
38
|
+
self.agents_dir = agents_dir
|
|
39
|
+
|
|
40
|
+
self.agent: Agent = None
|
|
41
|
+
|
|
42
|
+
self.runner: Runner = None
|
|
43
|
+
|
|
44
|
+
self.prompt_optimizer: AgentPilot = AgentPilot(
|
|
45
|
+
api_key=getenv("AGENT_PILOT_API_KEY")
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
self.trace_dict = {}
|
|
49
|
+
|
|
50
|
+
self.short_term_memory = None
|
|
51
|
+
|
|
52
|
+
self.evaluator = None
|
|
53
|
+
self.evalset_recorder = None
|
|
54
|
+
|
|
55
|
+
def get_agent_names(self) -> list[str]:
|
|
56
|
+
agent_dirs = []
|
|
57
|
+
|
|
58
|
+
for dirpath, dirnames, filenames in os.walk(self.agents_dir):
|
|
59
|
+
required_files = {"agent.py", "__init__.py"}
|
|
60
|
+
existing_files = set(filenames)
|
|
61
|
+
if required_files.issubset(existing_files):
|
|
62
|
+
agent_dirs.append(dirpath)
|
|
63
|
+
|
|
64
|
+
return [agent_dir.split("/")[-1] for agent_dir in agent_dirs]
|
|
65
|
+
|
|
66
|
+
def _set_short_term_memory(self, backend: str, db_url: str):
|
|
67
|
+
return ShortTermMemory(backend=backend, db_url=db_url)
|
|
68
|
+
|
|
69
|
+
async def set_runner(
|
|
70
|
+
self,
|
|
71
|
+
app_name: str,
|
|
72
|
+
user_id: str,
|
|
73
|
+
session_id: str,
|
|
74
|
+
short_term_memory_backend: str,
|
|
75
|
+
short_term_memory_db_url: str,
|
|
76
|
+
):
|
|
77
|
+
short_term_memory = self._set_short_term_memory(
|
|
78
|
+
backend=short_term_memory_backend, db_url=short_term_memory_db_url
|
|
79
|
+
)
|
|
80
|
+
await short_term_memory.create_session(
|
|
81
|
+
app_name=app_name, user_id=user_id, session_id=session_id
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
self.short_term_memory = short_term_memory
|
|
85
|
+
|
|
86
|
+
def set_agent(
|
|
87
|
+
self,
|
|
88
|
+
agent_name: str,
|
|
89
|
+
):
|
|
90
|
+
try:
|
|
91
|
+
agent_loader = AgentLoader(agents_dir=self.agents_dir)
|
|
92
|
+
agent = agent_loader.load_agent(agent_name)
|
|
93
|
+
self.agent = agent
|
|
94
|
+
self.agent.after_model_callback = after_model_callback
|
|
95
|
+
if not self.agent.tracers:
|
|
96
|
+
exporter = InMemoryExporter()
|
|
97
|
+
self.agent.tracers = [OpentelemetryTracer(exporters=[exporter])]
|
|
98
|
+
self.runner = Runner(
|
|
99
|
+
agent=self.agent, short_term_memory=self.short_term_memory
|
|
100
|
+
)
|
|
101
|
+
self.evalset_recorder = EvalSetRecorder(
|
|
102
|
+
self.short_term_memory.session_service
|
|
103
|
+
)
|
|
104
|
+
except Exception as e:
|
|
105
|
+
print(e)
|
|
106
|
+
|
|
107
|
+
def get_memory_status(self) -> dict:
|
|
108
|
+
short_term_memory_backend = self.runner.short_term_memory.backend
|
|
109
|
+
long_term_memory_backend = "No long term memory provided."
|
|
110
|
+
if self.agent.long_term_memory:
|
|
111
|
+
long_term_memory_backend = self.agent.long_term_memory.backend
|
|
112
|
+
return {
|
|
113
|
+
"short_term_memory_backend": short_term_memory_backend,
|
|
114
|
+
"long_term_memory_backend": long_term_memory_backend,
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async def get_testcases(self, session_id: str):
|
|
118
|
+
try:
|
|
119
|
+
dump_path = await self.evalset_recorder.dump(
|
|
120
|
+
self.runner.app_name, self.runner.user_id, session_id
|
|
121
|
+
)
|
|
122
|
+
os.remove(dump_path)
|
|
123
|
+
except Exception as _:
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
dump_path = await self.evalset_recorder.dump(
|
|
127
|
+
self.runner.app_name, self.runner.user_id, session_id
|
|
128
|
+
)
|
|
129
|
+
self._eval_set_path = dump_path
|
|
130
|
+
|
|
131
|
+
# 2. build
|
|
132
|
+
self.evaluator = DeepevalEvaluator(self.agent)
|
|
133
|
+
self.evaluator.generate_eval_data(dump_path)
|
|
134
|
+
|
|
135
|
+
test_cases = self.evaluator.get_data()
|
|
136
|
+
|
|
137
|
+
return test_cases
|
|
138
|
+
|
|
139
|
+
async def evaluate(self):
|
|
140
|
+
metrics = [
|
|
141
|
+
GEval(
|
|
142
|
+
name="Correctness&MatchDegree",
|
|
143
|
+
criteria="Judge the correctness and match degree of the model output with the expected output.",
|
|
144
|
+
evaluation_params=[
|
|
145
|
+
LLMTestCaseParams.INPUT,
|
|
146
|
+
LLMTestCaseParams.ACTUAL_OUTPUT,
|
|
147
|
+
LLMTestCaseParams.EXPECTED_OUTPUT,
|
|
148
|
+
],
|
|
149
|
+
),
|
|
150
|
+
]
|
|
151
|
+
|
|
152
|
+
await self.evaluator.eval(
|
|
153
|
+
eval_set_file_path=self._eval_set_path, metrics=metrics
|
|
154
|
+
)
|
|
155
|
+
test_cases = self.evaluator.get_data()
|
|
156
|
+
|
|
157
|
+
os.remove(self._eval_set_path)
|
|
158
|
+
self._eval_set_path = ""
|
|
159
|
+
|
|
160
|
+
return test_cases
|
|
161
|
+
|
|
162
|
+
def optimize_prompt(self, prompt: str, feedback: str) -> str:
|
|
163
|
+
self.agent.instruction = prompt
|
|
164
|
+
return self.prompt_optimizer.optimize(agents=[self.agent], feedback=feedback)
|
|
165
|
+
|
|
166
|
+
async def get_history_sessions(self, session_id: str) -> list[str]:
|
|
167
|
+
events = []
|
|
168
|
+
|
|
169
|
+
session_service = self.runner.short_term_memory.session_service
|
|
170
|
+
session = await session_service.get_session(
|
|
171
|
+
app_name=self.runner.app_name,
|
|
172
|
+
user_id=self.runner.user_id,
|
|
173
|
+
session_id=session_id,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
# prevent no session created
|
|
177
|
+
if session:
|
|
178
|
+
for event in session.events:
|
|
179
|
+
event_string = event.model_dump_json(exclude_none=True, by_alias=True)
|
|
180
|
+
events.append(event_string)
|
|
181
|
+
print(event_string)
|
|
182
|
+
return events
|
|
183
|
+
else:
|
|
184
|
+
return []
|
|
185
|
+
|
|
186
|
+
async def get_event(self, session_id: str, invocation_id: str) -> str:
|
|
187
|
+
session_service = self.runner.short_term_memory.session_service
|
|
188
|
+
session = await session_service.get_session(
|
|
189
|
+
app_name=self.runner.app_name,
|
|
190
|
+
user_id=self.runner.user_id,
|
|
191
|
+
session_id=session_id,
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
# prevent no session created
|
|
195
|
+
if session:
|
|
196
|
+
for event in session.events:
|
|
197
|
+
if event.invocation_id == invocation_id:
|
|
198
|
+
# find model response
|
|
199
|
+
if (
|
|
200
|
+
event.author != "user"
|
|
201
|
+
and event.content.parts[0]
|
|
202
|
+
and event.content.parts[0].text
|
|
203
|
+
):
|
|
204
|
+
return event.model_dump_json(exclude_none=True, by_alias=True)
|
|
205
|
+
return ""
|
|
206
|
+
return ""
|
|
207
|
+
|
|
208
|
+
async def run_sse(self, session_id: str, prompt: str):
|
|
209
|
+
self.agent.model._additional_args["stream"] = True
|
|
210
|
+
self.agent.model._additional_args["stream_options"] = {"include_usage": True}
|
|
211
|
+
self.agent.after_model_callback = after_model_callback
|
|
212
|
+
|
|
213
|
+
if self.agent and self.runner:
|
|
214
|
+
async for chunk in self.runner.run_sse(
|
|
215
|
+
session_id=session_id, prompt=prompt
|
|
216
|
+
):
|
|
217
|
+
yield chunk
|
|
218
|
+
|
|
219
|
+
def trace(self, session_id: str) -> str:
|
|
220
|
+
tracing_file_path = self.runner.save_tracing_file(session_id=session_id)
|
|
221
|
+
|
|
222
|
+
content = "No content!"
|
|
223
|
+
with open(tracing_file_path, "r", encoding="utf-8") as file:
|
|
224
|
+
data = json.load(file)
|
|
225
|
+
content = json.dumps(data, ensure_ascii=False, indent=2)
|
|
226
|
+
|
|
227
|
+
# remove file
|
|
228
|
+
if os.path.exists(tracing_file_path):
|
|
229
|
+
os.remove(tracing_file_path)
|
|
230
|
+
|
|
231
|
+
return content
|
|
232
|
+
|
|
233
|
+
async def save_session_to_long_term_memory(self, session_id: str):
|
|
234
|
+
"""Save session to long term memory"""
|
|
235
|
+
await self.runner.save_session_to_long_term_memory(session_id)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def after_model_callback(callback_context: CallbackContext, llm_response: LlmResponse):
|
|
239
|
+
if llm_response.content and llm_response.content.parts:
|
|
240
|
+
valid_parts = [
|
|
241
|
+
part
|
|
242
|
+
for part in llm_response.content.parts
|
|
243
|
+
if not (part.function_call and not part.function_call.name)
|
|
244
|
+
]
|
|
245
|
+
if len(valid_parts) < len(llm_response.content.parts):
|
|
246
|
+
llm_response.content.parts = valid_parts
|
|
247
|
+
return llm_response
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
import os
|
|
15
|
+
|
|
16
|
+
from fastapi import FastAPI
|
|
17
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
18
|
+
from fastapi.responses import FileResponse, StreamingResponse
|
|
19
|
+
from fastapi.staticfiles import StaticFiles
|
|
20
|
+
|
|
21
|
+
from veadk.cli.studio.agent_processor import AgentProcessor
|
|
22
|
+
from veadk.cli.studio.model import (
|
|
23
|
+
GetAgentResponse,
|
|
24
|
+
GetAgentsResponse,
|
|
25
|
+
GetEventResponse,
|
|
26
|
+
GetHistorySessionsResponse,
|
|
27
|
+
GetMemoryResponse,
|
|
28
|
+
OptimizePromptRequest,
|
|
29
|
+
OptimizePromptResponse,
|
|
30
|
+
ReplacePromptRequest,
|
|
31
|
+
RunAgentRequest,
|
|
32
|
+
RunAgentResponse,
|
|
33
|
+
SetAgentRequest,
|
|
34
|
+
SetAgentResponse,
|
|
35
|
+
SetRunnerRequest,
|
|
36
|
+
TraceAgentResponse,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
app = FastAPI()
|
|
40
|
+
|
|
41
|
+
app.add_middleware(
|
|
42
|
+
CORSMiddleware,
|
|
43
|
+
allow_origins=["*"],
|
|
44
|
+
allow_credentials=True,
|
|
45
|
+
allow_methods=["*"],
|
|
46
|
+
allow_headers=["*"],
|
|
47
|
+
allow_origin_regex=None,
|
|
48
|
+
expose_headers=[],
|
|
49
|
+
max_age=600,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
NEXT_STATIC_DIR = os.path.join(os.path.dirname(__file__), "web")
|
|
53
|
+
NEXT_HTML_DIR = NEXT_STATIC_DIR
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@app.get("/")
|
|
57
|
+
async def read_root():
|
|
58
|
+
index_path = os.path.join(NEXT_HTML_DIR, "index.html")
|
|
59
|
+
if os.path.exists(index_path):
|
|
60
|
+
return FileResponse(index_path, media_type="text/html")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
agent_processor = AgentProcessor()
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# health check
|
|
67
|
+
@app.get("/ping")
|
|
68
|
+
async def root():
|
|
69
|
+
return {"message": "pong"}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# get all agents
|
|
73
|
+
@app.get("/agents")
|
|
74
|
+
async def get_agents() -> GetAgentsResponse:
|
|
75
|
+
agents_dir = agent_processor.agents_dir
|
|
76
|
+
agents = agent_processor.get_agent_names()
|
|
77
|
+
return GetAgentsResponse(agents_dir=agents_dir, agents=agents)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# set current agent
|
|
81
|
+
@app.post("/set_agent")
|
|
82
|
+
async def set_agent(request: SetAgentRequest) -> SetAgentResponse:
|
|
83
|
+
agent_processor.set_agent(
|
|
84
|
+
agent_name=request.agent_name,
|
|
85
|
+
)
|
|
86
|
+
return SetAgentResponse(
|
|
87
|
+
name=agent_processor.agent.name,
|
|
88
|
+
description=agent_processor.agent.description,
|
|
89
|
+
model_name=agent_processor.agent.model_name,
|
|
90
|
+
instruction=agent_processor.agent.instruction,
|
|
91
|
+
long_term_memory_backend=agent_processor.agent.long_term_memory.backend
|
|
92
|
+
if agent_processor.agent.long_term_memory
|
|
93
|
+
else "",
|
|
94
|
+
knowledgebase_backend=agent_processor.agent.knowledgebase.backend
|
|
95
|
+
if agent_processor.agent.knowledgebase
|
|
96
|
+
else "",
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@app.post("/set_runner")
|
|
101
|
+
async def set_runner(request: SetRunnerRequest):
|
|
102
|
+
await agent_processor.set_runner(
|
|
103
|
+
app_name=request.app_name,
|
|
104
|
+
user_id=request.user_id,
|
|
105
|
+
session_id=request.session_id,
|
|
106
|
+
short_term_memory_backend=request.short_term_memory_backend,
|
|
107
|
+
short_term_memory_db_url=request.short_term_memory_db_url,
|
|
108
|
+
)
|
|
109
|
+
# TODO: return long & short term memory state
|
|
110
|
+
return {"message": f"Runner set to {request.app_name}"}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@app.get("/memory")
|
|
114
|
+
async def get_memory() -> GetMemoryResponse:
|
|
115
|
+
memory_status = agent_processor.get_memory_status()
|
|
116
|
+
return GetMemoryResponse(
|
|
117
|
+
**memory_status,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
# get current agent
|
|
122
|
+
@app.get("/agent")
|
|
123
|
+
async def get_agent() -> GetAgentResponse:
|
|
124
|
+
return GetAgentResponse(
|
|
125
|
+
name=agent_processor.agent.name,
|
|
126
|
+
description=agent_processor.agent.description,
|
|
127
|
+
model_name=agent_processor.agent.model_name,
|
|
128
|
+
instruction=agent_processor.agent.instruction,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@app.post("/optimize_prompt")
|
|
133
|
+
async def optimize_prompt(request: OptimizePromptRequest) -> OptimizePromptResponse:
|
|
134
|
+
current_prompt = request.prompt
|
|
135
|
+
feedback = request.feedback
|
|
136
|
+
prompt = agent_processor.optimize_prompt(current_prompt, feedback)
|
|
137
|
+
return OptimizePromptResponse(prompt=prompt)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@app.post("/replace_prompt")
|
|
141
|
+
async def replace_prompt(request: ReplacePromptRequest):
|
|
142
|
+
agent_processor.agent.instruction = request.prompt
|
|
143
|
+
return {"message": "Prompt replaced"}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
@app.get("/save_session")
|
|
147
|
+
async def save_session(session_id: str):
|
|
148
|
+
"""Save session to long term memory"""
|
|
149
|
+
await agent_processor.save_session_to_long_term_memory(session_id)
|
|
150
|
+
return {"message": "Session saved"}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
@app.post("/update_prompt")
|
|
154
|
+
async def update_prompt(request: ReplacePromptRequest):
|
|
155
|
+
agent_processor.agent.instruction = request.prompt
|
|
156
|
+
return {"message": "Prompt replaced"}
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@app.get("/history_sessions")
|
|
160
|
+
async def get_history_sessions(session_id: str) -> GetHistorySessionsResponse:
|
|
161
|
+
events = await agent_processor.get_history_sessions(session_id)
|
|
162
|
+
return GetHistorySessionsResponse(events=events)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
# run agent with user ID
|
|
166
|
+
@app.post("/run")
|
|
167
|
+
async def run(request: RunAgentRequest) -> RunAgentResponse:
|
|
168
|
+
agent_processor.agent.model._additional_args["stream"] = False
|
|
169
|
+
agent_processor.agent.model._additional_args["stream_options"] = {}
|
|
170
|
+
|
|
171
|
+
session_id = request.session_id
|
|
172
|
+
message = request.message
|
|
173
|
+
response = await agent_processor.runner.run_with_final_event(
|
|
174
|
+
messages=message,
|
|
175
|
+
session_id=session_id,
|
|
176
|
+
)
|
|
177
|
+
return RunAgentResponse(event=response)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
@app.get("/testcases")
|
|
181
|
+
async def get_testcases(session_id: str):
|
|
182
|
+
testcases = await agent_processor.get_testcases(session_id)
|
|
183
|
+
return {"data": testcases}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@app.post("/evaluate")
|
|
187
|
+
async def evaluate():
|
|
188
|
+
agent_processor.agent.model._additional_args["stream"] = False
|
|
189
|
+
agent_processor.agent.model._additional_args["stream_options"] = {}
|
|
190
|
+
|
|
191
|
+
test_cases = await agent_processor.evaluate()
|
|
192
|
+
return {"data": test_cases}
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
@app.get("/run_sse")
|
|
196
|
+
async def run_sse(session_id: str, message: str):
|
|
197
|
+
return StreamingResponse(
|
|
198
|
+
agent_processor.run_sse(session_id, message),
|
|
199
|
+
media_type="text/event-stream",
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
@app.get("/trace")
|
|
204
|
+
def trace(session_id: str) -> TraceAgentResponse:
|
|
205
|
+
content = agent_processor.trace(
|
|
206
|
+
session_id=session_id,
|
|
207
|
+
)
|
|
208
|
+
return TraceAgentResponse(content=content)
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@app.get("/get/event")
|
|
212
|
+
async def get_event(session_id: str, invocation_id: str) -> GetEventResponse:
|
|
213
|
+
event_str = await agent_processor.get_event(session_id, invocation_id)
|
|
214
|
+
return GetEventResponse(event=event_str)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
app.mount(
|
|
218
|
+
"/_next",
|
|
219
|
+
StaticFiles(directory=os.path.join(NEXT_STATIC_DIR, "_next")),
|
|
220
|
+
name="next_static",
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
app.mount(
|
|
224
|
+
"/",
|
|
225
|
+
StaticFiles(directory=NEXT_STATIC_DIR, html=True),
|
|
226
|
+
name="static",
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def get_fast_api_app(agents_dir: str) -> FastAPI:
|
|
231
|
+
agent_processor.agents_dir = agents_dir
|
|
232
|
+
return app
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from pydantic import BaseModel
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class GetAgentsResponse(BaseModel):
|
|
19
|
+
agents_dir: str
|
|
20
|
+
agents: list[str]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class SetAgentRequest(BaseModel):
|
|
24
|
+
agent_name: str
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class SetAgentResponse(BaseModel):
|
|
28
|
+
name: str
|
|
29
|
+
description: str
|
|
30
|
+
model_name: str
|
|
31
|
+
instruction: str
|
|
32
|
+
long_term_memory_backend: str = ""
|
|
33
|
+
knowledgebase_backend: str = ""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class SetRunnerRequest(BaseModel):
|
|
37
|
+
app_name: str
|
|
38
|
+
user_id: str
|
|
39
|
+
session_id: str
|
|
40
|
+
short_term_memory_backend: str
|
|
41
|
+
short_term_memory_db_url: str
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class GetMemoryResponse(BaseModel):
|
|
45
|
+
short_term_memory_backend: str
|
|
46
|
+
# short_term_memory_session_number: str
|
|
47
|
+
long_term_memory_backend: str
|
|
48
|
+
# long_term_memory_session_number: str
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class GetAgentResponse(BaseModel):
|
|
52
|
+
name: str
|
|
53
|
+
description: str
|
|
54
|
+
model_name: str
|
|
55
|
+
instruction: str
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class GetHistorySessionsResponse(BaseModel):
|
|
59
|
+
events: list[str]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class OptimizePromptRequest(BaseModel):
|
|
63
|
+
prompt: str
|
|
64
|
+
feedback: str
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class OptimizePromptResponse(BaseModel):
|
|
68
|
+
prompt: str
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class ReplacePromptRequest(BaseModel):
|
|
72
|
+
prompt: str
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class RunAgentRequest(BaseModel):
|
|
76
|
+
session_id: str
|
|
77
|
+
message: str
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class RunAgentResponse(BaseModel):
|
|
81
|
+
event: str
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class TraceAgentResponse(BaseModel):
|
|
85
|
+
content: str
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class EvaluateAgentResponse(BaseModel):
|
|
89
|
+
content: str
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class GetEventResponse(BaseModel):
|
|
93
|
+
event: str
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# ========== messages ==========
|
|
97
|
+
# class BotMessage(BaseModel):
|
|
98
|
+
# type: str = "bot"
|
|
99
|
+
# event_id: str
|
|
100
|
+
# invocation_id: str
|
|
101
|
+
# timestamp: any
|
|
102
|
+
# content: str
|
|
103
|
+
# prompt_tokens: str
|
|
104
|
+
# candidate_tokens: str
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
# class ToolMessage(BaseModel):
|
|
108
|
+
# type: str = "tool"
|
|
109
|
+
# event_id: str
|
|
110
|
+
# invocation_id: str
|
|
111
|
+
# function_call_id: str
|
|
112
|
+
# tool_name: str
|
|
113
|
+
# tool_args: dict
|
|
114
|
+
# tool_response: str
|
|
115
|
+
# timestamp: any
|
|
116
|
+
# finish: bool
|
veadk/cloud/__init__.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|