feat(cli): add env support in agent_metadata.yaml#315
feat(cli): add env support in agent_metadata.yaml#315volcano-sh-bot merged 1 commit intovolcano-sh:mainfrom
Conversation
|
Welcome @madmecodes! It looks like this is your first PR to volcano-sh/agentcube 🎉 |
There was a problem hiding this comment.
Code Review
This pull request adds support for user-defined environment variables in agent_metadata.yaml by introducing an env field to the AgentMetadata model. The PublishRuntime logic was updated to merge these variables with CLI options during deployment, and a comprehensive test suite was added to ensure correct parsing and forwarding. Feedback suggests using dictionary unpacking to simplify the environment variable merging logic and reduce code duplication.
| env_vars = dict(metadata.env) if metadata.env else {} | ||
| if options.get('env_vars'): | ||
| env_vars.update(options['env_vars']) |
There was a problem hiding this comment.
The logic for merging environment variables can be simplified using dictionary unpacking. This approach is more concise and handles potential None values gracefully while ensuring that CLI options correctly override metadata values.
| env_vars = dict(metadata.env) if metadata.env else {} | |
| if options.get('env_vars'): | |
| env_vars.update(options['env_vars']) | |
| env_vars = {**(metadata.env or {}), **(options.get('env_vars') or {})} |
| env_vars = dict(metadata.env) if metadata.env else {} | ||
| if options.get('env_vars'): | ||
| env_vars.update(options['env_vars']) |
There was a problem hiding this comment.
This merge logic is duplicated from _publish_cr_to_k8s. Using a concise dictionary unpacking approach improves readability and maintainability by reducing the boilerplate needed for merging optional dictionaries.
| env_vars = dict(metadata.env) if metadata.env else {} | |
| if options.get('env_vars'): | |
| env_vars.update(options['env_vars']) | |
| env_vars = {**(metadata.env or {}), **(options.get('env_vars') or {})} |
There was a problem hiding this comment.
Pull request overview
This PR adds first-class support for user-defined environment variables in agent_metadata.yaml and wires them through the CLI publish flow so they are injected into sandbox pod containers for both the AgentRuntime CRD (“agentcube” provider) and standard Deployment (“k8s” provider).
Changes:
- Extend the
AgentMetadatamodel to include an optionalenv: Dict[str, str]field that is omitted from saved YAML whenNone. - Merge
metadata.envwith any programmaticenv_varsoptions during publish (options take precedence) and forward the merged env to both deployment providers. - Add unit tests covering metadata YAML round-trip and env forwarding behavior.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| cmd/cli/agentcube/services/metadata_service.py | Adds env field to AgentMetadata and relies on existing exclude_none=True YAML saving behavior. |
| cmd/cli/agentcube/runtime/publish_runtime.py | Merges metadata.env into env_vars and forwards to both AgentCube and Kubernetes providers. |
| cmd/cli/tests/test_env_support.py | New tests for env parsing/persistence and publish-time env forwarding. |
| cmd/cli/tests/init.py | No functional changes (file present for test package). |
| from unittest.mock import MagicMock, patch | ||
|
|
||
| import yaml | ||
| import pytest |
|
|
||
| with tempfile.TemporaryDirectory() as tmpdir: | ||
| result = runtime.publish(Path(tmpdir), provider="agentcube") | ||
|
|
| with tempfile.TemporaryDirectory() as tmpdir: | ||
| result = runtime.publish(Path(tmpdir), provider="k8s") | ||
|
|
| with tempfile.TemporaryDirectory() as tmpdir: | ||
| result = runtime.publish(Path(tmpdir), provider="agentcube") | ||
|
|
| # Merge user-defined env from metadata with any env_vars from options | ||
| env_vars = dict(metadata.env) if metadata.env else {} | ||
| if options.get('env_vars'): | ||
| env_vars.update(options['env_vars']) |
| # Merge user-defined env from metadata with any env_vars from options | ||
| env_vars = dict(metadata.env) if metadata.env else {} | ||
| if options.get('env_vars'): | ||
| env_vars.update(options['env_vars']) |
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #315 +/- ##
==========================================
+ Coverage 47.57% 47.75% +0.18%
==========================================
Files 30 30
Lines 2819 2854 +35
==========================================
+ Hits 1341 1363 +22
- Misses 1338 1343 +5
- Partials 140 148 +8
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
74413a8 to
c8f5957
Compare
c8f5957 to
4927514
Compare
| if options.get('env_vars'): | ||
| env_vars.update(options['env_vars']) |
| # Merge user-defined env from metadata with any env_vars from options | ||
| env_vars = dict(metadata.env) if metadata.env else {} | ||
| if options.get('env_vars'): | ||
| env_vars.update(options['env_vars']) |
| # User-defined environment variables injected into sandbox pods | ||
| env: Optional[Dict[str, str]] = Field( | ||
| None, description="Extra env vars to inject into the agent container" | ||
| ) |
| passed_env = call_kwargs.kwargs.get("env_vars") or call_kwargs[1].get("env_vars") | ||
| assert passed_env is not None | ||
| assert "LLM_BASE_URL" in passed_env | ||
| assert passed_env["LLM_BASE_URL"] == "http://llm" | ||
| assert passed_env["LLM_API_KEY"] == "sk-123" | ||
|
|
4927514 to
ba4a7ba
Compare
Signed-off-by: madmecodes <ayushguptadev1@gmail.com>
ba4a7ba to
d8f9bc2
Compare
hzxuzhonghu
left a comment
There was a problem hiding this comment.
/lgtm
Should we update document as well like docs/design/AgentRun-CLI-Design.md
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: hzxuzhonghu The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
LLM_API_KEY should better reference a secret key in k8s spec |
|
🚀 cool, need this feature ~ |
Summary
Adds first-class
envsupport toagent_metadata.yamlso users can declare extra environment variables that get injected into sandbox pod containers during publish.Right now the only way to get custom env vars (like
LLM_BASE_URL,LLM_API_KEY) into a deployed agent is to manually patch the CRD afterkubectl agentcube publish, and that gets overwritten on the next publish. This change lets you put them straight in the metadata file:What changed
metadata_service.py-- addedenv: Optional[Dict[str, str]]field toAgentMetadatamodel. Defaults toNone, excluded from saved YAML when absent.publish_runtime.py-- both_publish_cr_to_k8s(AgentRuntime CR) and_publish_k8s(standard Deployment) now readmetadata.envand merge it into theenv_varsdict before passing to providers. Programmaticenv_varsfrom options still override metadata values.tests/test_env_support.py-- 10 unit tests covering model validation, YAML round-trip, and env forwarding to both providers.Fixes #222
Test plan
AgentMetadataacceptsenvdict, defaults toNoneenvcorrectlyenvomits the field from YAMLenvfrom metadata forwarded to AgentCube providerenvfrom metadata forwarded to K8s providerenvpassesNoneto providers (no regression)