adk-code-mode 1.1.0__tar.gz → 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- adk_code_mode-1.2.0/.release-please-manifest.json +3 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/CHANGELOG.md +7 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/PKG-INFO +1 -1
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/sandbox-wheel/src/adk_code_mode_sandbox/__about__.py +1 -1
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/__about__.py +1 -1
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/_artifact_tools.py +4 -1
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_artifact_tools.py +42 -8
- adk_code_mode-1.1.0/.release-please-manifest.json +0 -3
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/.githooks/pre-commit +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/.githooks/pre-push +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/.github/workflows/ci.yml +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/.github/workflows/release-please.yml +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/.gitignore +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/.prettierrc +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/.vscode/settings.json +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/.zed/settings.json +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/AGENTS.md +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/CLAUDE.md +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/LICENSE +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/Makefile +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/README.md +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/docker/Dockerfile +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/pyproject.toml +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/release-please-config.json +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/sandbox-wheel/README.md +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/sandbox-wheel/pyproject.toml +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/sandbox-wheel/src/adk_code_mode_sandbox/__init__.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/sandbox-wheel/src/adk_code_mode_sandbox/__main__.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/sandbox-wheel/src/adk_code_mode_sandbox/_entry.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/sandbox-wheel/src/adk_code_mode_sandbox/_http_server.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/sandbox-wheel/src/adk_code_mode_sandbox/_rpc_client.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/sandbox-wheel/src/adk_code_mode_sandbox/protocol.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/scripts/install-git-hooks.sh +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/__init__.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/output.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/py.typed +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/runtime/__init__.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/runtime/base.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/runtime/docker.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/runtime/protocol.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/runtime/remote.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/tool.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/tool_result_artifacts.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/tools/__init__.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/tools/catalog.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/tools/dispatcher.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/tools/namespacing.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/tools/normaliser.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/tools/stubs.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/workspace/__init__.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/src/adk_code_mode/workspace/files.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/__init__.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/_docker_helpers.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/_fake_runtime.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/conftest.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_agent_with_fake_llm.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_catalog.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_dispatcher.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_docker_image.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_docker_integration.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_host_loop.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_integration.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_namespacing.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_normaliser.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_output.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_protocol.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_remote_backend.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_remote_integration.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_runtime_docker.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_sandbox_rpc_client.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_stubs.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_tool.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_tool_result_artifacts.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_version.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/tests/test_workspace_files.py +0 -0
- {adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/uv.lock +0 -0
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.2.0](https://github.com/a2anet/adk-code-mode/compare/adk-code-mode-v1.1.0...adk-code-mode-v1.2.0) (2026-07-23)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add `custom_metadata` to the `save_artifact` tool ([dfd9a59](https://github.com/a2anet/adk-code-mode/commit/dfd9a59bf1718084a1d5c02cc1ea453269223f16))
|
|
9
|
+
|
|
3
10
|
## [1.1.0](https://github.com/a2anet/adk-code-mode/compare/adk-code-mode-v1.0.0...adk-code-mode-v1.1.0) (2026-07-15)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: adk-code-mode
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: A "Code Mode" sandboxed code-execution tool for ADK agents to interact with tools, files, and custom packages with Python
|
|
5
5
|
Project-URL: Documentation, https://github.com/A2ANet/adk-code-mode#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/A2ANet/adk-code-mode/issues
|
|
@@ -43,6 +43,7 @@ async def save_artifact(
|
|
|
43
43
|
filename: str,
|
|
44
44
|
content: str,
|
|
45
45
|
mime_type: str | None = None,
|
|
46
|
+
custom_metadata: dict[str, Any] | None = None,
|
|
46
47
|
tool_context: ToolContext,
|
|
47
48
|
) -> int:
|
|
48
49
|
"""Save an artifact to the session. Returns the new version number.
|
|
@@ -62,6 +63,8 @@ async def save_artifact(
|
|
|
62
63
|
content=base64.b64encode(image_bytes).decode("ascii"),
|
|
63
64
|
mime_type="image/png",
|
|
64
65
|
)
|
|
66
|
+
|
|
67
|
+
``custom_metadata`` is custom metadata to associate with the artifact.
|
|
65
68
|
"""
|
|
66
69
|
if _is_text_mime(mime_type):
|
|
67
70
|
part = genai_types.Part(
|
|
@@ -77,7 +80,7 @@ async def save_artifact(
|
|
|
77
80
|
mime_type=mime_type or "application/octet-stream",
|
|
78
81
|
)
|
|
79
82
|
)
|
|
80
|
-
return await tool_context.save_artifact(filename, part)
|
|
83
|
+
return await tool_context.save_artifact(filename, part, custom_metadata=custom_metadata)
|
|
81
84
|
|
|
82
85
|
|
|
83
86
|
async def load_artifact(
|
|
@@ -34,12 +34,17 @@ class _StubToolContext:
|
|
|
34
34
|
) -> None:
|
|
35
35
|
self._load_result = load_result
|
|
36
36
|
self._list_result = list_result or []
|
|
37
|
-
self.saved: list[tuple[str, genai_types.Part]] = []
|
|
37
|
+
self.saved: list[tuple[str, genai_types.Part, dict[str, Any] | None]] = []
|
|
38
38
|
self.loaded: list[tuple[str, int | None]] = []
|
|
39
39
|
self.listed = 0
|
|
40
40
|
|
|
41
|
-
async def save_artifact(
|
|
42
|
-
self
|
|
41
|
+
async def save_artifact(
|
|
42
|
+
self,
|
|
43
|
+
filename: str,
|
|
44
|
+
part: genai_types.Part,
|
|
45
|
+
custom_metadata: dict[str, Any] | None = None,
|
|
46
|
+
) -> int:
|
|
47
|
+
self.saved.append((filename, part, custom_metadata))
|
|
43
48
|
return len(self.saved)
|
|
44
49
|
|
|
45
50
|
async def load_artifact(
|
|
@@ -65,7 +70,7 @@ async def test_save_artifact_encodes_text_mime_as_utf8() -> None:
|
|
|
65
70
|
|
|
66
71
|
assert version == 1
|
|
67
72
|
assert len(ctx.saved) == 1
|
|
68
|
-
name, part = ctx.saved[0]
|
|
73
|
+
name, part, _ = ctx.saved[0]
|
|
69
74
|
assert name == "report.json"
|
|
70
75
|
assert part.inline_data is not None
|
|
71
76
|
assert part.inline_data.mime_type == "application/json"
|
|
@@ -82,7 +87,7 @@ async def test_save_artifact_treats_text_plus_subtype_as_text() -> None:
|
|
|
82
87
|
tool_context=ctx, # type: ignore[arg-type]
|
|
83
88
|
)
|
|
84
89
|
|
|
85
|
-
_, part = ctx.saved[0]
|
|
90
|
+
_, part, _ = ctx.saved[0]
|
|
86
91
|
assert part.inline_data is not None
|
|
87
92
|
assert part.inline_data.data == b"<svg/>"
|
|
88
93
|
|
|
@@ -98,7 +103,7 @@ async def test_save_artifact_decodes_base64_for_binary_mime() -> None:
|
|
|
98
103
|
tool_context=ctx, # type: ignore[arg-type]
|
|
99
104
|
)
|
|
100
105
|
|
|
101
|
-
_, part = ctx.saved[0]
|
|
106
|
+
_, part, _ = ctx.saved[0]
|
|
102
107
|
assert part.inline_data is not None
|
|
103
108
|
assert part.inline_data.data == raw
|
|
104
109
|
assert part.inline_data.mime_type == "application/octet-stream"
|
|
@@ -114,12 +119,41 @@ async def test_save_artifact_defaults_mime_when_none() -> None:
|
|
|
114
119
|
tool_context=ctx, # type: ignore[arg-type]
|
|
115
120
|
)
|
|
116
121
|
|
|
117
|
-
_, part = ctx.saved[0]
|
|
122
|
+
_, part, _ = ctx.saved[0]
|
|
118
123
|
assert part.inline_data is not None
|
|
119
124
|
assert part.inline_data.mime_type == "application/octet-stream"
|
|
120
125
|
assert part.inline_data.data == raw
|
|
121
126
|
|
|
122
127
|
|
|
128
|
+
@pytest.mark.asyncio
|
|
129
|
+
async def test_save_artifact_forwards_custom_metadata() -> None:
|
|
130
|
+
ctx = _StubToolContext()
|
|
131
|
+
await save_artifact(
|
|
132
|
+
filename="report.md",
|
|
133
|
+
content="# Report",
|
|
134
|
+
mime_type="text/markdown",
|
|
135
|
+
custom_metadata={"a2anet_agent_run.send_as_a2a_artifact": "true"},
|
|
136
|
+
tool_context=ctx, # type: ignore[arg-type]
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
_, _, custom_metadata = ctx.saved[0]
|
|
140
|
+
assert custom_metadata == {"a2anet_agent_run.send_as_a2a_artifact": "true"}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@pytest.mark.asyncio
|
|
144
|
+
async def test_save_artifact_defaults_custom_metadata_to_none() -> None:
|
|
145
|
+
ctx = _StubToolContext()
|
|
146
|
+
await save_artifact(
|
|
147
|
+
filename="scratch.txt",
|
|
148
|
+
content="notes",
|
|
149
|
+
mime_type="text/plain",
|
|
150
|
+
tool_context=ctx, # type: ignore[arg-type]
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
_, _, custom_metadata = ctx.saved[0]
|
|
154
|
+
assert custom_metadata is None
|
|
155
|
+
|
|
156
|
+
|
|
123
157
|
@pytest.mark.asyncio
|
|
124
158
|
async def test_load_artifact_returns_text_kind_for_text_mime() -> None:
|
|
125
159
|
part = genai_types.Part(
|
|
@@ -196,4 +230,4 @@ def test_artifact_tools_declarations_omit_tool_context_param() -> None:
|
|
|
196
230
|
assert save_decl is not None
|
|
197
231
|
properties: dict[str, Any] = save_decl.parameters.properties or {} # type: ignore[union-attr]
|
|
198
232
|
assert "tool_context" not in properties
|
|
199
|
-
assert {"filename", "content"}.issubset(properties.keys())
|
|
233
|
+
assert {"filename", "content", "custom_metadata"}.issubset(properties.keys())
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/sandbox-wheel/src/adk_code_mode_sandbox/__init__.py
RENAMED
|
File without changes
|
{adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/sandbox-wheel/src/adk_code_mode_sandbox/__main__.py
RENAMED
|
File without changes
|
{adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/sandbox-wheel/src/adk_code_mode_sandbox/_entry.py
RENAMED
|
File without changes
|
{adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/sandbox-wheel/src/adk_code_mode_sandbox/_http_server.py
RENAMED
|
File without changes
|
{adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/sandbox-wheel/src/adk_code_mode_sandbox/_rpc_client.py
RENAMED
|
File without changes
|
{adk_code_mode-1.1.0 → adk_code_mode-1.2.0}/sandbox-wheel/src/adk_code_mode_sandbox/protocol.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|