Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 6 additions & 12 deletions veadk/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,24 +114,18 @@ def model_post_init(self, __context: Any) -> None:

self.tools.append(load_memory)

self.before_model_callback = []
self.after_model_callback = []
self.update_tracers_callback()
if self.tracers:
self.before_model_callback = []
self.after_model_callback = []
for tracer in self.tracers:
self.before_model_callback.append(tracer.llm_metrics_hook)
self.after_model_callback.append(tracer.token_metrics_hook)

logger.info(f"Agent `{self.name}` init done.")
logger.debug(
f"Agent: {self.model_dump(include={'name', 'model_name', 'model_api_base', 'tools', 'serve_url'})}"
)

def update_tracers_callback(self) -> None:
"""Update tracer callbacks with tracers."""
for tracer in self.tracers:
# Add tracer callbacks if not already added
if tracer.llm_metrics_hook not in self.before_model_callback:
self.before_model_callback.append(tracer.llm_metrics_hook)
if tracer.token_metrics_hook not in self.after_model_callback:
self.after_model_callback.append(tracer.token_metrics_hook)

async def _run(
self,
runner,
Expand Down
16 changes: 8 additions & 8 deletions veadk/cli/services/vefaas/template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ We implement an minimal agent to report weather in terms of the given city.

## Structure

| File | Illustration |
| - | - |
| `src/app.py` | The entrypoint of VeFaaS server. |
| `src/run.sh` | The launch script of VeFaaS server. |
| File | Illustration |
|------------------------| - |
| `src/app.py` | The entrypoint of VeFaaS server. |
| `src/run.sh` | The launch script of VeFaaS server. |
| `src/requirements.txt` | Dependencies of your project. `VeADK`, `FastAPI`, and `uvicorn` must be included. |
| `src/config.py` | The agent and memory definitions. **You may edit this file.** |
| `config.yaml.example` | Envs for your project (e.g., `api_key`, `token`, ...). **You may edit this file.** |
| `deploy.py` | Local script for deployment. |
| `src/agent.py` | The agent and memory definitions. **You may edit this file.** |
| `config.yaml.example` | Envs for your project (e.g., `api_key`, `token`, ...). **You may edit this file.** |
| `deploy.py` | Local script for deployment. |

You must export your agent and short-term memory in `src/config.py`.
You must export your agent and short-term memory in `src/agent.py`.

## Deploy

Expand Down
9 changes: 9 additions & 0 deletions veadk/cli/services/vefaas/template/config.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ model:
name: doubao-1-5-pro-256k-250115
api_base: https://ark.cn-beijing.volces.com/api/v3/
api_key:
judge:
name: doubao-1-5-pro-256k-250115
api_base: https://ark.cn-beijing.volces.com/api/v3/
api_key:


agent_pilot:
api_key:


volcengine:
access_key:
Expand Down
24 changes: 16 additions & 8 deletions veadk/cli/services/vefaas/template/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,32 @@
SESSION_ID = "cloud_app_test_session"
USER_ID = "cloud_app_test_user"

USE_STUDIO = False


async def main():
engine = CloudAgentEngine()
cloud_app = engine.deploy(
path=str(Path(__file__).parent / "src"),
name="weather-reporter",
# gateway_name="", # <--- your gateway instance name if you have
name="weather-reporter", # <--- set your application name
use_studio=USE_STUDIO,
# gateway_name="", # <--- set your gateway instance name if you have one
)

response_message = await cloud_app.message_send(
"How is the weather like in Beijing?", SESSION_ID, USER_ID
)
if not USE_STUDIO:
response_message = await cloud_app.message_send(
"How is the weather like in Beijing?", SESSION_ID, USER_ID
)

print(f"Message ID: {response_message.messageId}")
print(f"Message ID: {response_message.messageId}")

print(f"Response from {cloud_app.endpoint}: {response_message.parts[0].root.text}")
print(
f"Response from {cloud_app.endpoint}: {response_message.parts[0].root.text}"
)

print(f"App ID: {cloud_app.app_id}")
print(f"App ID: {cloud_app.app_id}")
else:
print(f"VeADK Studio URL: {cloud_app.endpoint}")


if __name__ == "__main__":
Expand Down
23 changes: 23 additions & 0 deletions veadk/cli/services/vefaas/template/src/agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from veadk import Agent
from veadk.memory.short_term_memory import ShortTermMemory
from veadk.tools.demo_tools import get_city_weather

app_name: str = "weather-reporter" # <--- export your app name
agent: Agent = Agent(tools=[get_city_weather]) # <--- export your agent
short_term_memory: ShortTermMemory = (
ShortTermMemory()
) # <--- export your short term memory
53 changes: 44 additions & 9 deletions veadk/cli/services/vefaas/template/src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,53 @@

import os

from config import AGENT, APP_NAME, SHORT_TERM_MEMORY, TRACERS

from agent import agent, app_name, short_term_memory
from veadk.a2a.ve_a2a_server import init_app
from veadk.tracing.base_tracer import BaseTracer
from veadk.tracing.telemetry.opentelemetry_tracer import OpentelemetryTracer


# ==============================================================================
# Tracer Config ================================================================

TRACERS: list[BaseTracer] = []

exporters = []
if os.getenv("VEADK_TRACER_APMPLUS", "").lower() == "true":
from veadk.tracing.telemetry.exporters.apmplus_exporter import APMPlusExporter

exporters.append(APMPlusExporter())

if os.getenv("VEADK_TRACER_COZELOOP", "").lower() == "true":
from veadk.tracing.telemetry.exporters.cozeloop_exporter import CozeloopExporter

exporters.append(CozeloopExporter())

if os.getenv("VEADK_TRACER_TLS", "").lower() == "true":
from veadk.tracing.telemetry.exporters.tls_exporter import TLSExporter

exporters.append(TLSExporter())

TRACERS.append(OpentelemetryTracer(exporters=exporters))


SERVER_HOST = os.getenv("SERVER_HOST")
agent.tracers.extend(TRACERS)
if not getattr(agent, "before_model_callback", None):
agent.before_model_callback = []
if not getattr(agent, "after_model_callback", None):
agent.after_model_callback = []
for tracer in TRACERS:
if tracer.llm_metrics_hook not in agent.before_model_callback:
agent.before_model_callback.append(tracer.llm_metrics_hook)
if tracer.token_metrics_hook not in agent.after_model_callback:
agent.after_model_callback.append(tracer.token_metrics_hook)

AGENT.tracers.extend(TRACERS)
AGENT.update_tracers_callback()
# Tracer Config ================================================================
# ==============================================================================

app = init_app(
server_url=SERVER_HOST,
app_name=APP_NAME,
agent=AGENT,
short_term_memory=SHORT_TERM_MEMORY,
server_url="0.0.0.0", # Automatic identification is not supported yet.
app_name=app_name,
agent=agent,
short_term_memory=short_term_memory,
)
58 changes: 0 additions & 58 deletions veadk/cli/services/vefaas/template/src/config.py

This file was deleted.

21 changes: 19 additions & 2 deletions veadk/cli/services/vefaas/template/src/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,22 @@ python3 -m pip install uvicorn[standard]

python3 -m pip install fastapi

# running
exec python3 -m uvicorn app:app --host $HOST --port $PORT --timeout-graceful-shutdown $TIMEOUT
USE_STUDIO=${USE_STUDIO:-False}

if [ "$USE_STUDIO" = "True" ]; then
echo "USE_STUDIO is True, running veadk studio"
# running veadk studio
exec python3 -m uvicorn studio_app:app --host $HOST --port $PORT --timeout-graceful-shutdown $TIMEOUT --loop asyncio
elif [ "$USE_STUDIO" = "False" ]; then
echo "USE_STUDIO is False, running a2a server"

# running a2a server
exec python3 -m uvicorn app:app --host $HOST --port $PORT --timeout-graceful-shutdown $TIMEOUT --loop asyncio
else
echo "USE_STUDIO is an invalid value: $USE_STUDIO, running a2a server."

# running a2a server
exec python3 -m uvicorn app:app --host $HOST --port $PORT --timeout-graceful-shutdown $TIMEOUT --loop asyncio
fi


47 changes: 47 additions & 0 deletions veadk/cli/services/vefaas/template/src/studio_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
from importlib.util import module_from_spec, spec_from_file_location
from pathlib import Path

from veadk.cli.studio.fast_api import get_fast_api_app

path = Path(__file__).parent.resolve()

agent_py_path = os.path.join(path, "agent.py")
if not os.path.exists(agent_py_path):
raise FileNotFoundError(f"agent.py not found in {path}")

spec = spec_from_file_location("agent", agent_py_path)
if spec is None:
raise ImportError(f"Could not load spec for agent from {agent_py_path}")

module = module_from_spec(spec)

try:
spec.loader.exec_module(module)
except Exception as e:
raise ImportError(f"Failed to execute agent.py: {e}")

agent = None
short_term_memory = None
try:
agent = module.agent
short_term_memory = module.short_term_memory
except AttributeError as e:
missing = str(e).split("'")[1] if "'" in str(e) else "unknown"
raise AttributeError(f"agent.py is missing required variable: {missing}")

app = get_fast_api_app(agent, short_term_memory)
4 changes: 2 additions & 2 deletions veadk/cloud/cloud_agent_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ def _prepare(self, path: str, name: str):
f"Local agent project path `{path}` is not a directory."
)

assert os.path.exists(os.path.join(path, "config.py")), (
f"Local agent project path `{path}` does not contain `config.py` file. Please prepare it according to veadk-python/cloud/template/config.py.example"
assert os.path.exists(os.path.join(path, "agent.py")), (
f"Local agent project path `{path}` does not contain `agent.py` file. Please prepare it according to veadk-python/cloud/template/agent.py.example"
)

if os.path.exists(os.path.join(path, "app.py")):
Expand Down
19 changes: 19 additions & 0 deletions veadk/cloud/template/agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from veadk.agent import Agent
from veadk.memory.short_term_memory import ShortTermMemory

agent: Agent = ...
app_name: str = ...
short_term_memory: ShortTermMemory = ...
Loading