Skip to content

Commit 77d090d

Browse files
committed
Merge remote-tracking branch 'upstream/main' into feature/toshandler
2 parents 808e9b4 + 1c0dcbd commit 77d090d

39 files changed

+1751
-883
lines changed

.github/workflows/publish-tag-to-pypi.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
with:
1717
python-version: "3.x"
1818
- name: Install build tool
19-
run: python3 -m pip install build --user
19+
run: python3 -m pip install build --user --upgrade
2020
- name: Build wheel and source distribution
2121
run: python3 -m build
2222
- name: Upload distributables as artifact
@@ -39,7 +39,7 @@ jobs:
3939
path: dist/
4040

4141
- name: Install Twine
42-
run: python3 -m pip install --user twine
42+
run: python3 -m pip install --user --upgrade twine packaging
4343

4444
- name: Publish to PyPI
4545
env:

pyproject.toml

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "veadk-python"
3-
version = "0.2.2"
3+
version = "0.2.4"
44
description = "Volcengine agent development kit, integrations with Volcengine cloud services."
55
readme = "README.md"
66
requires-python = ">=3.10"
@@ -18,19 +18,22 @@ dependencies = [
1818
"google-adk>=1.10.0", # For basic agent architecture
1919
"litellm>=1.74.3", # For model inference
2020
"loguru>=0.7.3", # For better logging
21-
"openinference-instrumentation-google-adk>=0.1.1", # For OpenInference instrumentation
2221
"opentelemetry-exporter-otlp>=1.35.0",
2322
"opentelemetry-instrumentation-logging>=0.56b0",
2423
"wrapt>=1.17.2", # For patching built-in functions
25-
"openai<1.100" # For fix https://github.com/BerriAI/litellm/issues/13710
24+
"openai<1.100", # For fix https://github.com/BerriAI/litellm/issues/13710
25+
"volcengine-python-sdk==4.0.3", # For Volcengine API
26+
"agent-pilot-sdk>=0.0.9", # Prompt optimization by Volcengine AgentPilot/PromptPilot toolkits
27+
"fastmcp>=2.11.3", # For running MCP
28+
"cookiecutter>=2.6.0", # For cloud deploy
29+
"opensearch-py==2.8.0" # For OpenSearch database
2630
]
2731

2832
[project.scripts]
2933
veadk = "veadk.cli.cli:veadk"
3034

3135
[project.optional-dependencies]
3236
database = [
33-
"opensearch-py==2.8.0", # For OpenSearch database
3437
"redis>=6.2.0", # For Redis database
3538
"pymysql>=1.1.1", # For MySQL database
3639
"volcengine>=1.0.193", # For Viking DB
@@ -41,12 +44,7 @@ eval = [
4144
"deepeval>=3.2.6", # For DeepEval-based evaluation
4245
"google-adk[eval]", # For Google ADK-based evaluation
4346
]
44-
cli = [
45-
"volcengine-python-sdk==4.0.3", # For Volcengine API
46-
"agent-pilot-sdk>=0.0.9", # Prompt optimization by Volcengine AgentPilot/PromptPilot toolkits
47-
"fastmcp>=2.11.3", # For running MCP
48-
"cookiecutter>=2.6.0", # For cloud deploy
49-
]
47+
cli = []
5048
dev = [
5149
"pre-commit>=4.2.0", # Format checking
5250
"pytest>=8.4.1",
@@ -77,4 +75,4 @@ include-package-data = true
7775
[tool.ruff]
7876
exclude = [
7977
"veadk/integrations/ve_faas/template/*"
80-
]
78+
]

tests/test_agent.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from google.adk.tools import load_memory
1616

1717
from veadk import Agent
18+
from veadk.consts import DEFAULT_MODEL_EXTRA_HEADERS
1819
from veadk.knowledgebase import KnowledgeBase
1920
from veadk.memory.long_term_memory import LongTermMemory
2021
from veadk.tools import load_knowledgebase_tool
@@ -26,11 +27,14 @@ def test_agent():
2627
long_term_memory = LongTermMemory(backend="local")
2728
tracer = OpentelemetryTracer()
2829

30+
model_extra_headers = {"test-header": "test-value"}
31+
2932
agent = Agent(
3033
model_name="test_model_name",
3134
model_provider="test_model_provider",
3235
model_api_key="test_model_api_key",
3336
model_api_base="test_model_api_base",
37+
model_extra_headers=model_extra_headers,
3438
tools=[],
3539
sub_agents=[],
3640
knowledgebase=knowledgebase,
@@ -39,7 +43,10 @@ def test_agent():
3943
serve_url="",
4044
)
4145

46+
model_extra_headers |= DEFAULT_MODEL_EXTRA_HEADERS
47+
4248
assert agent.model.model == f"{agent.model_provider}/{agent.model_name}"
49+
assert agent.model_extra_headers == model_extra_headers
4350

4451
assert agent.knowledgebase == knowledgebase
4552
assert agent.knowledgebase.backend == "local"
@@ -48,7 +55,3 @@ def test_agent():
4855

4956
assert agent.long_term_memory.backend == "local"
5057
assert load_memory in agent.tools
51-
52-
assert tracer.tracer_hook_before_model in agent.before_model_callback
53-
assert tracer.tracer_hook_after_model in agent.after_model_callback
54-
assert tracer.tracer_hook_after_tool in agent.after_tool_callback

tests/test_evaluator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def test_evaluator():
129129
with open(eval_set_file_path, "w") as f:
130130
json.dump(EVAL_SET_DATA, f)
131131

132-
base_evaluator.generate_eval_data(file_path=eval_set_file_path)
132+
base_evaluator.build_eval_set(file_path=eval_set_file_path)
133133

134134
assert len(base_evaluator.invocation_list) == 1
135135
assert len(base_evaluator.invocation_list[0].invocations) == 1
@@ -149,7 +149,7 @@ def test_tracing_file_to_evalset():
149149
with open(tracing_file_path, "w") as f:
150150
json.dump(TRACE_SET_DATA, f)
151151

152-
base_evaluator.generate_eval_data(file_path=tracing_file_path)
152+
base_evaluator.build_eval_set(file_path=tracing_file_path)
153153

154154
assert len(base_evaluator.invocation_list) == 1
155155
assert len(base_evaluator.invocation_list[0].invocations) == 1

tests/test_tracing.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ async def test_tracing():
8282
exporters = init_exporters()
8383
tracer = OpentelemetryTracer(exporters=exporters)
8484

85-
assert len(tracer.exporters) == 4 # with extra 1 built-in exporters
85+
assert len(tracer.exporters) == 3
8686

8787
# TODO: Ensure the tracing provider is set correctly after loading SDK
8888

@@ -98,7 +98,7 @@ async def test_tracing_with_global_provider():
9898
#
9999
tracer = OpentelemetryTracer(exporters=exporters)
100100

101-
assert len(tracer.exporters) == 4 # with extra 1 built-in exporters
101+
assert len(tracer.exporters) == 3 # with extra 1 built-in exporters
102102

103103

104104
@pytest.mark.asyncio
@@ -113,4 +113,4 @@ async def test_tracing_with_apmplus_global_provider():
113113
tracer = OpentelemetryTracer(exporters=exporters)
114114

115115
# apmplus exporter won't init again
116-
assert len(tracer.exporters) == 3 # with extra 1 built-in exporters
116+
assert len(tracer.exporters) == 2 # with extra 1 built-in exporters

veadk/agent.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
DEFALUT_MODEL_AGENT_PROVIDER,
3232
DEFAULT_MODEL_AGENT_API_BASE,
3333
DEFAULT_MODEL_AGENT_NAME,
34+
DEFAULT_MODEL_EXTRA_HEADERS,
3435
)
3536
from veadk.evaluation import EvalSetRecorder
3637
from veadk.knowledgebase import KnowledgeBase
@@ -40,6 +41,7 @@
4041
from veadk.tracing.base_tracer import BaseTracer
4142
from veadk.utils.logger import get_logger
4243
from veadk.utils.patches import patch_asyncio
44+
from veadk.version import VERSION
4345

4446
patch_asyncio()
4547
logger = get_logger(__name__)
@@ -72,6 +74,9 @@ class Agent(LlmAgent):
7274
model_api_key: str = Field(default_factory=lambda: getenv("MODEL_AGENT_API_KEY"))
7375
"""The api key of the model for agent running."""
7476

77+
model_extra_headers: dict = Field(default_factory=dict)
78+
"""The extra headers to include in the model requests."""
79+
7580
tools: list[ToolUnion] = []
7681
"""The tools provided to agent."""
7782

@@ -95,11 +100,23 @@ class Agent(LlmAgent):
95100

96101
def model_post_init(self, __context: Any) -> None:
97102
super().model_post_init(None) # for sub_agents init
98-
self.model = LiteLlm(
99-
model=f"{self.model_provider}/{self.model_name}",
100-
api_key=self.model_api_key,
101-
api_base=self.model_api_base,
102-
)
103+
104+
self.model_extra_headers |= DEFAULT_MODEL_EXTRA_HEADERS
105+
106+
if not self.model:
107+
self.model = LiteLlm(
108+
model=f"{self.model_provider}/{self.model_name}",
109+
api_key=self.model_api_key,
110+
api_base=self.model_api_base,
111+
extra_headers=self.model_extra_headers,
112+
)
113+
logger.debug(
114+
f"LiteLLM client created with extra headers: {self.model_extra_headers}"
115+
)
116+
else:
117+
logger.warning(
118+
"You are trying to use your own LiteLLM client, some default request headers may be missing."
119+
)
103120

104121
if self.knowledgebase:
105122
from veadk.tools import load_knowledgebase_tool
@@ -112,9 +129,7 @@ def model_post_init(self, __context: Any) -> None:
112129

113130
self.tools.append(load_memory)
114131

115-
if self.tracers:
116-
for tracer in self.tracers:
117-
tracer.do_hooks(self)
132+
logger.info(f"VeADK version: {VERSION}")
118133

119134
logger.info(f"{self.__class__.__name__} `{self.name}` init done.")
120135
logger.debug(
@@ -215,9 +230,6 @@ async def run(
215230
session_service=session_service,
216231
memory_service=self.long_term_memory,
217232
)
218-
if getattr(self, "tracers", None):
219-
for tracer in self.tracers:
220-
tracer.set_app_name(app_name)
221233

222234
logger.info(f"Begin to process prompt {prompt}")
223235
# run

veadk/agents/loop_agent.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from pydantic import ConfigDict, Field
2020
from typing_extensions import Any
2121

22-
from veadk.agent import Agent
2322
from veadk.prompts.agent_default_prompt import DEFAULT_DESCRIPTION, DEFAULT_INSTRUCTION
2423
from veadk.tracing.base_tracer import BaseTracer
2524
from veadk.utils.logger import get_logger
@@ -50,21 +49,7 @@ class LoopAgent(GoogleADKLoopAgent):
5049
tracers: list[BaseTracer] = []
5150
"""The tracers provided to agent."""
5251

53-
def set_sub_agents_tracer(self, tracer) -> None:
54-
from veadk.agents.parallel_agent import ParallelAgent
55-
from veadk.agents.sequential_agent import SequentialAgent
56-
57-
for sub_agent in self.sub_agents:
58-
if isinstance(sub_agent, Agent):
59-
tracer.do_hooks(sub_agent)
60-
elif isinstance(sub_agent, (SequentialAgent, LoopAgent, ParallelAgent)):
61-
sub_agent.set_sub_agents_tracer(tracer)
62-
6352
def model_post_init(self, __context: Any) -> None:
6453
super().model_post_init(None) # for sub_agents init
6554

66-
if self.tracers:
67-
for tracer in self.tracers:
68-
self.set_sub_agents_tracer(tracer)
69-
7055
logger.info(f"{self.__class__.__name__} `{self.name}` init done.")

veadk/agents/parallel_agent.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from pydantic import ConfigDict, Field
2020
from typing_extensions import Any
2121

22-
from veadk.agent import Agent
2322
from veadk.prompts.agent_default_prompt import DEFAULT_DESCRIPTION, DEFAULT_INSTRUCTION
2423
from veadk.tracing.base_tracer import BaseTracer
2524
from veadk.utils.logger import get_logger
@@ -50,24 +49,12 @@ class ParallelAgent(GoogleADKParallelAgent):
5049
tracers: list[BaseTracer] = []
5150
"""The tracers provided to agent."""
5251

53-
def set_sub_agents_tracer(self, tracer) -> None:
54-
from veadk.agents.loop_agent import LoopAgent
55-
from veadk.agents.sequential_agent import SequentialAgent
56-
57-
for sub_agent in self.sub_agents:
58-
if isinstance(sub_agent, Agent):
59-
tracer.do_hooks(sub_agent)
60-
elif isinstance(sub_agent, (SequentialAgent, LoopAgent, ParallelAgent)):
61-
sub_agent.set_sub_agents_tracer(tracer)
62-
6352
def model_post_init(self, __context: Any) -> None:
6453
super().model_post_init(None) # for sub_agents init
6554

6655
if self.tracers:
6756
logger.warning(
6857
"Enable tracing in ParallelAgent may cause OpenTelemetry context error. Issue see https://github.com/google/adk-python/issues/1670"
6958
)
70-
for tracer in self.tracers:
71-
self.set_sub_agents_tracer(tracer)
7259

7360
logger.info(f"{self.__class__.__name__} `{self.name}` init done.")

veadk/agents/sequential_agent.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from pydantic import ConfigDict, Field
2020
from typing_extensions import Any
2121

22-
from veadk.agent import Agent
2322
from veadk.prompts.agent_default_prompt import DEFAULT_DESCRIPTION, DEFAULT_INSTRUCTION
2423
from veadk.tracing.base_tracer import BaseTracer
2524
from veadk.utils.logger import get_logger
@@ -50,21 +49,7 @@ class SequentialAgent(GoogleADKSequentialAgent):
5049
tracers: list[BaseTracer] = []
5150
"""The tracers provided to agent."""
5251

53-
def set_sub_agents_tracer(self, tracer) -> None:
54-
from veadk.agents.loop_agent import LoopAgent
55-
from veadk.agents.parallel_agent import ParallelAgent
56-
57-
for sub_agent in self.sub_agents:
58-
if isinstance(sub_agent, Agent):
59-
tracer.do_hooks(sub_agent)
60-
elif isinstance(sub_agent, (SequentialAgent, LoopAgent, ParallelAgent)):
61-
sub_agent.set_sub_agents_tracer(tracer)
62-
6352
def model_post_init(self, __context: Any) -> None:
6453
super().model_post_init(None) # for sub_agents init
6554

66-
if self.tracers:
67-
for tracer in self.tracers:
68-
self.set_sub_agents_tracer(tracer)
69-
7055
logger.info(f"{self.__class__.__name__} `{self.name}` init done.")

veadk/cli/cli_web.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,32 @@ def _get_memory(
102102
return short_term_memory, long_term_memory
103103

104104

105+
def patch_adkwebserver_disable_openapi():
106+
"""
107+
Monkey patch AdkWebServer.get_fast_api to remove openapi.json route.
108+
"""
109+
import google.adk.cli.adk_web_server
110+
from fastapi.routing import APIRoute
111+
from starlette.routing import Route
112+
113+
original_get_fast_api = google.adk.cli.adk_web_server.AdkWebServer.get_fast_api_app
114+
115+
def wrapped_get_fast_api(self, *args, **kwargs):
116+
app = original_get_fast_api(self, *args, **kwargs)
117+
118+
paths = ["/openapi.json", "/docs", "/redoc"]
119+
new_routes = []
120+
for route in app.router.routes:
121+
if isinstance(route, (APIRoute, Route)) and route.path in paths:
122+
continue
123+
new_routes.append(route)
124+
app.router.routes = new_routes
125+
126+
return app
127+
128+
google.adk.cli.adk_web_server.AdkWebServer.get_fast_api_app = wrapped_get_fast_api
129+
130+
105131
@click.command()
106132
@click.option("--host", default="127.0.0.1", help="Host to run the web server on")
107133
def web(host: str) -> None:
@@ -145,6 +171,7 @@ def init_for_veadk(
145171
import google.adk.cli.adk_web_server
146172

147173
google.adk.cli.adk_web_server.AdkWebServer.__init__ = init_for_veadk
174+
patch_adkwebserver_disable_openapi()
148175

149176
import google.adk.cli.cli_tools_click as cli_tools_click
150177

0 commit comments

Comments
 (0)