Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
29 changes: 28 additions & 1 deletion docs/docs/agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,28 @@ Agent中主要包括如下属性:
| knowledgebase | Vector database | 知识库,后端通常为一个向量数据库(Vector database),能够检索 |
| tracers | list | 追踪器列表,能够定义不同的追踪方式,并在Agent执行完毕后对整体Tracing信息保存至本地 |

## A2A智能体

当你的智能体部署到云上后,可以在本地被初始化为一个Remote Agent,也就是能够通过A2A协议来访问的智能体,初始化方法如下:

```python
remote_agent = RemoteVeAgent(
name="a2a_agent",
url="..." # <--- url from cloud platform
)

short_term_memory = ShortTermMemory()
runner = Runner(
agent=remote_agent,
short_term_memory=short_term_memory
)

res = await runner.run(
messages="...",
session_id="sample_session"
)
```

## 运行

在生产环境中,我们推荐您使用`Runner`来进行多租户服务:
Expand All @@ -29,6 +51,11 @@ USER_ID = ""
SESSION_ID = ""

agent = Agent()
runner = Runner(agent=agent, short_term_memory=ShortTermMemory())

runner = Runner(
agent=agent,
short_term_memory=ShortTermMemory()
)

response = await runner.run(messages=prompt, session_id=session_id)
```
21 changes: 21 additions & 0 deletions veadk/a2a/remote_ve_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import json

import requests
from a2a.types import AgentCard
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent

AGENT_CARD_WELL_KNOWN_PATH = "/.well-known/agent-card.json"


class RemoteVeAgent(RemoteA2aAgent):
def __init__(self, name: str, url: str):
agent_card_dict = requests.get(url + AGENT_CARD_WELL_KNOWN_PATH).json()
agent_card_dict["url"] = url

agent_card_json_str = json.dumps(agent_card_dict, ensure_ascii=False, indent=2)

agent_card_object = AgentCard.model_validate_json(str(agent_card_json_str))

super().__init__(
name=name, description="weather reporter", agent_card=agent_card_object
Copy link

Copilot AI Aug 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardcoded description 'weather reporter' should be made configurable or derived from the agent card to make this class more generic and reusable.

Suggested change
name=name, description="weather reporter", agent_card=agent_card_object
name=name, description=agent_card_dict.get("description", ""), agent_card=agent_card_object

Copilot uses AI. Check for mistakes.
)
37 changes: 37 additions & 0 deletions veadk/cli/services/vefaas/template/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Template project for Vefaas

This is a template project for Vefaas. You can use it as a starting point for your own project.

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. |
| `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. |

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

## Deploy

We recommand you deploy this project by the `cloud` module of VeADK.
Copy link

Copilot AI Aug 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling error: 'recommand' should be 'recommend'.

Suggested change
We recommand you deploy this project by the `cloud` module of VeADK.
We recommend you deploy this project by the `cloud` module of VeADK.

Copilot uses AI. Check for mistakes.

```bash
python deploy.py
```

You may see output like this:

```bash
Successfully deployed on:

https://....volceapi.com
Message ID: ...
Response from ...: The weather in Beijing is sunny, with a temperature of 25°C.
App ID: ...
```
10 changes: 10 additions & 0 deletions veadk/cli/services/vefaas/template/config.yaml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
model:
agent:
provider: openai
name: doubao-1-5-pro-256k-250115
api_base: https://ark.cn-beijing.volces.com/api/v3/
api_key:

volcengine:
access_key:
secret_key:
44 changes: 44 additions & 0 deletions veadk/cli/services/vefaas/template/deploy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# 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 asyncio
from pathlib import Path

from veadk.cloud.cloud_agent_engine import CloudAgentEngine

SESSION_ID = "cloud_app_test_session"
USER_ID = "cloud_app_test_user"


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
)

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"Response from {cloud_app.endpoint}: {response_message.parts[0].root.text}")

print(f"App ID: {cloud_app.app_id}")


if __name__ == "__main__":
asyncio.run(main())
30 changes: 30 additions & 0 deletions veadk/cli/services/vefaas/template/src/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# 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 config import AGENT, APP_NAME, SHORT_TERM_MEMORY, TRACERS

from veadk.a2a.ve_a2a_server import init_app

SERVER_HOST = os.getenv("SERVER_HOST")

AGENT.tracers = TRACERS

app = init_app(
server_url=SERVER_HOST,
app_name=APP_NAME,
agent=AGENT,
short_term_memory=SHORT_TERM_MEMORY,
)
58 changes: 58 additions & 0 deletions veadk/cli/services/vefaas/template/src/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# 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 veadk import Agent
from veadk.memory.short_term_memory import ShortTermMemory
from veadk.tools.demo_tools import get_city_weather
from veadk.tracing.base_tracer import BaseTracer
from veadk.tracing.telemetry.opentelemetry_tracer import OpentelemetryTracer

# =============
# Generated by VeADK, do not edit!!!
# =============
TRACERS: list[BaseTracer] = []

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

exporters.append(APMPlusExporter())

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

exporters.append(CozeloopExporter())

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

exporters.append(TLSExporter())

TRACERS.append(OpentelemetryTracer(exporters=exporters))

# =============
# Required [you can edit here]
# =============
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

# =============
# Optional
# =============
# Other global variables
3 changes: 3 additions & 0 deletions veadk/cli/services/vefaas/template/src/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
git+https://github.com/volcengine/veadk-python.git
uvicorn[standard]
fastapi
42 changes: 42 additions & 0 deletions veadk/cli/services/vefaas/template/src/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash
set -ex
cd `dirname $0`

# A special check for CLI users (run.sh should be located at the 'root' dir)
if [ -d "output" ]; then
cd ./output/
fi

# Default values for host and port
HOST="0.0.0.0"
PORT=${_FAAS_RUNTIME_PORT:-8000}
TIMEOUT=${_FAAS_FUNC_TIMEOUT}

export SERVER_HOST=$HOST
export SERVER_PORT=$PORT

export PYTHONPATH=$PYTHONPATH:./site-packages
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--port)
PORT="$2"
shift 2
;;
--host)
HOST="$2"
shift 2
;;
*)
shift
;;
esac
done

# in case of uvicorn and fastapi not installed in user's requirements.txt
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
18 changes: 8 additions & 10 deletions veadk/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from google.genai import types
from google.genai.types import Blob

from veadk.a2a.remote_ve_agent import RemoteVeAgent
from veadk.agent import Agent
from veadk.evaluation import EvalSetRecorder
from veadk.memory.short_term_memory import ShortTermMemory
Expand All @@ -41,7 +42,7 @@
class Runner:
def __init__(
self,
agent: Agent,
agent: Agent | RemoteVeAgent,
short_term_memory: ShortTermMemory,
app_name: str = "veadk_default_app",
user_id: str = "veadk_default_user",
Expand All @@ -56,7 +57,10 @@ def __init__(
self.short_term_memory = short_term_memory
self.session_service = short_term_memory.session_service

self.long_term_memory = self.agent.long_term_memory
if isinstance(self.agent, Agent):
self.long_term_memory = self.agent.long_term_memory
else:
self.long_term_memory = None

# maintain a in-memory runner for fast inference
self.runner = ADKRunner(
Expand All @@ -67,13 +71,6 @@ def __init__(
)

def _convert_messages(self, messages) -> list:
# RunnerMessage = Union[
# str, # single turn text-based prompt
# list[str], # multiple turn text-based prompt
# dict, # single turn prompt with media
# list[dict], # multiple turn prompt with media
# list[dict | str], # multiple turn prompt with media and text-based prompt
# ]
if isinstance(messages, str):
messages = [types.Content(role="user", parts=[types.Part(text=messages)])]
elif isinstance(messages, MediaMessage):
Expand Down Expand Up @@ -159,7 +156,8 @@ async def run(
final_output = await self._run(session_id, message, stream)

# try to save tracing file
self.save_tracing_file(session_id)
if isinstance(self.agent, Agent):
self.save_tracing_file(session_id)

return final_output

Expand Down