Skip to content

Commit 7623f55

Browse files
committed
fix: fix type errors and add logs (#68)
* fix: fix type errors and add logs * fix type error in some files * remove useless tls package
1 parent 131e5b8 commit 7623f55

7 files changed

Lines changed: 328 additions & 47 deletions

File tree

veadk/cli/main.py

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
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 __future__ import annotations
16+
17+
import importlib.util
18+
import os
19+
import shutil
20+
import sys
21+
from importlib.util import module_from_spec, spec_from_file_location
22+
from pathlib import Path
23+
24+
import typer
25+
import uvicorn
26+
27+
from veadk.utils.logger import get_logger
28+
from veadk.version import VERSION
29+
30+
logger = get_logger(__name__)
31+
32+
app = typer.Typer(name="vego")
33+
34+
35+
def set_variable_in_file(file_path: str, setting_values: dict):
36+
import ast
37+
38+
with open(file_path, "r", encoding="utf-8") as f:
39+
source_code = f.read()
40+
41+
tree = ast.parse(source_code)
42+
43+
class VariableTransformer(ast.NodeTransformer):
44+
def visit_Assign(self, node: ast.Assign):
45+
for target in node.targets:
46+
if isinstance(target, ast.Name) and target.id in setting_values:
47+
node.value = ast.Constant(value=setting_values[target.id])
48+
return node
49+
50+
transformer = VariableTransformer()
51+
new_tree = transformer.visit(tree)
52+
ast.fix_missing_locations(new_tree)
53+
new_source_code = ast.unparse(new_tree)
54+
55+
with open(file_path, "w", encoding="utf-8") as f:
56+
f.write(new_source_code)
57+
58+
print("Your project has beed created.")
59+
60+
61+
@app.command()
62+
def init():
63+
"""Init a veadk project that can be deployed to Volcengine VeFaaS."""
64+
from rich.prompt import Confirm, Prompt
65+
66+
cwd = Path.cwd()
67+
template_dir = Path(__file__).parent.resolve() / "services" / "vefaas" / "template"
68+
69+
local_dir_name = Prompt.ask("Local directory name", default="veadk-cloud-proj")
70+
71+
target_dir = cwd / local_dir_name
72+
73+
if target_dir.exists():
74+
response = Confirm.ask(
75+
f"Target directory '{target_dir}' already exists, do you want to overwrite it?: "
76+
)
77+
if not response:
78+
print("Operation cancelled.")
79+
return
80+
else:
81+
shutil.rmtree(target_dir)
82+
print(f"Deleted existing directory: {target_dir}")
83+
84+
vefaas_application_name = Prompt.ask(
85+
"Volcengine FaaS application name", default="veadk-cloud-agent"
86+
)
87+
88+
gateway_name = Prompt.ask(
89+
"Volcengine gateway instance name", default="", show_default=True
90+
)
91+
92+
gateway_service_name = Prompt.ask(
93+
"Volcengine gateway service name", default="", show_default=True
94+
)
95+
96+
gateway_upstream_name = Prompt.ask(
97+
"Volcengine gateway upstream name", default="", show_default=True
98+
)
99+
100+
deploy_mode_options = {
101+
"1": "A2A/MCP Server",
102+
"2": "VeADK Studio",
103+
"3": "VeADK Web / Google ADK Web",
104+
}
105+
106+
deploy_mode = Prompt.ask(
107+
"""Choose your deploy mode:
108+
1. A2A/MCP Server
109+
2. VeADK Studio
110+
3. VeADK Web / Google ADK Web
111+
""",
112+
default="1",
113+
)
114+
115+
if deploy_mode in deploy_mode_options:
116+
deploy_mode = deploy_mode_options[deploy_mode]
117+
else:
118+
print("Invalid deploy mode, set default to A2A Server")
119+
deploy_mode = deploy_mode_options["1"]
120+
121+
setting_values = {
122+
"VEFAAS_APPLICATION_NAME": vefaas_application_name,
123+
"GATEWAY_NAME": gateway_name,
124+
"GATEWAY_SERVICE_NAME": gateway_service_name,
125+
"GATEWAY_UPSTREAM_NAME": gateway_upstream_name,
126+
"USE_STUDIO": deploy_mode == deploy_mode_options["2"],
127+
"USE_ADK_WEB": deploy_mode == deploy_mode_options["3"],
128+
}
129+
130+
shutil.copytree(template_dir, target_dir)
131+
set_variable_in_file(target_dir / "deploy.py", setting_values)
132+
133+
134+
@app.command()
135+
def web(
136+
session_service_uri: str = typer.Option(
137+
None,
138+
"--session_service_uri",
139+
),
140+
host: str = typer.Option(
141+
"127.0.0.1",
142+
"--host",
143+
),
144+
):
145+
from google.adk.memory import in_memory_memory_service
146+
147+
from veadk.memory.long_term_memory import LongTermMemory
148+
149+
in_memory_memory_service.InMemoryMemoryService = LongTermMemory
150+
151+
from google.adk.cli import cli_tools_click
152+
153+
importlib.reload(cli_tools_click)
154+
agents_dir = os.getcwd()
155+
if not session_service_uri:
156+
session_service_uri = ""
157+
158+
cli_tools_click.cli_web.main(
159+
args=[agents_dir, "--session_service_uri", session_service_uri, "--host", host]
160+
)
161+
162+
163+
@app.command()
164+
def studio(
165+
path: str = typer.Option(".", "--path", help="Project path"),
166+
):
167+
from veadk.cli.studio.fast_api import get_fast_api_app
168+
169+
path = Path(path).resolve()
170+
171+
agent_py_path = os.path.join(path, "agent.py")
172+
if not os.path.exists(agent_py_path):
173+
raise FileNotFoundError(f"agent.py not found in {path}")
174+
175+
spec = spec_from_file_location("agent", agent_py_path)
176+
if spec is None:
177+
raise ImportError(f"Could not load spec for agent from {agent_py_path}")
178+
179+
module = module_from_spec(spec)
180+
181+
try:
182+
spec.loader.exec_module(module)
183+
except Exception as e:
184+
raise ImportError(f"Failed to execute agent.py: {e}")
185+
186+
agent = None
187+
short_term_memory = None
188+
try:
189+
agent = module.agent
190+
short_term_memory = module.short_term_memory
191+
except AttributeError as e:
192+
missing = str(e).split("'")[1] if "'" in str(e) else "unknown"
193+
raise AttributeError(f"agent.py is missing required variable: {missing}")
194+
195+
app = get_fast_api_app(agent, short_term_memory)
196+
197+
uvicorn.run(
198+
app,
199+
host="127.0.0.1",
200+
port=8000,
201+
log_level="info",
202+
loop="asyncio", # for deepeval
203+
)
204+
205+
206+
@app.command()
207+
def prompt(
208+
path: str = typer.Option(
209+
...,
210+
"--path",
211+
help="Your agent file path. Please ensure that your agent(s) are global variable(s).",
212+
),
213+
feedback: str = typer.Option(
214+
"",
215+
"--feedback",
216+
help="Feedback of prompt from agent evaluation.",
217+
),
218+
api_key: str = typer.Option(
219+
..., "--api-key", help="API Key of AgentPilot Platform"
220+
),
221+
model_name: str = typer.Option(
222+
"doubao-1.5-pro-32k-250115",
223+
"--model-name",
224+
help="Model name for prompt optimization",
225+
),
226+
):
227+
from veadk import Agent
228+
229+
"""
230+
NOTE(nkfyz): Detecting agents from a file is not fully correct, we will fix this feature asap.
231+
"""
232+
module_name = "veadk_agent"
233+
path = Path(path).resolve()
234+
logger.info(f"Detect agents in {path}")
235+
236+
spec = importlib.util.spec_from_file_location(module_name, path)
237+
module = importlib.util.module_from_spec(spec)
238+
sys.modules[module_name] = module
239+
spec.loader.exec_module(module)
240+
globals_in_module = vars(module) # get all global variables in module
241+
242+
agents = []
243+
for global_variable_name, global_variable_value in globals_in_module.items():
244+
if isinstance(global_variable_value, Agent):
245+
agent = global_variable_value
246+
agents.append(agent)
247+
logger.info(f"Found {len(agents)} agent(s) in {path}")
248+
249+
if len(agents) == 0:
250+
logger.info(
251+
"No agent found. Please put your agent definition as a global variable in your agent file."
252+
)
253+
print(
254+
f"No agent found in {path}. Please put your agent definition as a global variable in your agent file."
255+
)
256+
return
257+
258+
from veadk.cli.services.agentpilot import AgentPilot
259+
260+
ap = AgentPilot(api_key)
261+
ap.optimize(agents=agents, feedback=feedback, model_name=model_name)
262+
263+
264+
@app.command()
265+
def deploy(
266+
access_key: str = typer.Option(..., "--access-key", help="Access Key"),
267+
secret_key: str = typer.Option(..., "--secret-key", help="Secret Key"),
268+
name: str = typer.Option(..., "--name", help="Deployment name"),
269+
path: str = typer.Option(".", "--path", help="Project path"),
270+
):
271+
from veadk.cli.services.vefaas import VeFaaS
272+
273+
path = Path(path).resolve()
274+
vefaas = VeFaaS(access_key, secret_key)
275+
vefaas.deploy(name=name, path=path)
276+
277+
278+
@app.command()
279+
def version():
280+
print(f"VeADK {VERSION}")
281+
282+
283+
if __name__ == "__main__":
284+
app()

veadk/database/viking/viking_database.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import json
1717
import os
1818
import uuid
19-
from typing import Any, BinaryIO, Literal, Optional, TextIO
19+
from typing import Any, BinaryIO, Literal, TextIO
2020

2121
import requests
2222
import tos
@@ -44,42 +44,44 @@
4444

4545

4646
class VolcengineTOSConfig(BaseModel):
47-
endpoint: Optional[str] = Field(
48-
default=getenv("DATABASE_TOS_ENDPOINT", "tos-cn-beijing.volces.com"),
47+
endpoint: str = Field(
48+
default_factory=lambda: getenv(
49+
"DATABASE_TOS_ENDPOINT", "tos-cn-beijing.volces.com"
50+
),
4951
description="VikingDB TOS endpoint",
5052
)
51-
region: Optional[str] = Field(
52-
default=getenv("DATABASE_TOS_REGION", "cn-beijing"),
53+
region: str = Field(
54+
default_factory=lambda: getenv("DATABASE_TOS_REGION", "cn-beijing"),
5355
description="VikingDB TOS region",
5456
)
55-
bucket: Optional[str] = Field(
56-
default=getenv("DATABASE_TOS_BUCKET"),
57+
bucket: str = Field(
58+
default_factory=lambda: getenv("DATABASE_TOS_BUCKET"),
5759
description="VikingDB TOS bucket",
5860
)
59-
base_key: Optional[str] = Field(
61+
base_key: str = Field(
6062
default="veadk",
6163
description="VikingDB TOS base key",
6264
)
6365

6466

6567
class VikingDatabaseConfig(BaseModel):
66-
volcengine_ak: Optional[str] = Field(
67-
default=getenv("VOLCENGINE_ACCESS_KEY"),
68+
volcengine_ak: str = Field(
69+
default_factory=lambda: getenv("VOLCENGINE_ACCESS_KEY"),
6870
description="VikingDB access key",
6971
)
70-
volcengine_sk: Optional[str] = Field(
71-
default=getenv("VOLCENGINE_SECRET_KEY"),
72+
volcengine_sk: str = Field(
73+
default_factory=lambda: getenv("VOLCENGINE_SECRET_KEY"),
7274
description="VikingDB secret key",
7375
)
74-
project: Optional[str] = Field(
75-
default=getenv("DATABASE_VIKING_PROJECT"),
76+
project: str = Field(
77+
default_factory=lambda: getenv("DATABASE_VIKING_PROJECT"),
7678
description="VikingDB project name",
7779
)
78-
region: Optional[str] = Field(
79-
default=getenv("DATABASE_VIKING_REGION"),
80+
region: str = Field(
81+
default_factory=lambda: getenv("DATABASE_VIKING_REGION"),
8082
description="VikingDB region",
8183
)
82-
tos: Optional[VolcengineTOSConfig] = Field(
84+
tos: VolcengineTOSConfig = Field(
8385
default_factory=VolcengineTOSConfig,
8486
description="VikingDB TOS configuration",
8587
)

veadk/database/viking/viking_memory_db.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import threading
1919
import time
2020
from datetime import datetime
21-
from typing import Any, Optional
21+
from typing import Any
2222

2323
from pydantic import BaseModel, Field
2424
from volcengine.ApiInfo import ApiInfo
@@ -35,20 +35,20 @@
3535

3636

3737
class VikingMemConfig(BaseModel):
38-
volcengine_ak: Optional[str] = Field(
39-
default=getenv("VOLCENGINE_ACCESS_KEY"),
38+
volcengine_ak: str = Field(
39+
default_factory=lambda: getenv("VOLCENGINE_ACCESS_KEY"),
4040
description="VikingDB access key",
4141
)
42-
volcengine_sk: Optional[str] = Field(
43-
default=getenv("VOLCENGINE_SECRET_KEY"),
42+
volcengine_sk: str = Field(
43+
default_factory=lambda: getenv("VOLCENGINE_SECRET_KEY"),
4444
description="VikingDB secret key",
4545
)
46-
project: Optional[str] = Field(
47-
default=getenv("DATABASE_VIKING_PROJECT"),
46+
project: str = Field(
47+
default_factory=lambda: getenv("DATABASE_VIKING_PROJECT"),
4848
description="VikingDB project name",
4949
)
50-
region: Optional[str] = Field(
51-
default=getenv("DATABASE_VIKING_REGION"),
50+
region: str = Field(
51+
default_factory=lambda: getenv("DATABASE_VIKING_REGION"),
5252
description="VikingDB region",
5353
)
5454

0 commit comments

Comments
 (0)