sprites-adk 0.1.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.
@@ -0,0 +1,44 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v[0-9]+.[0-9]+.[0-9]+'
7
+ - 'v[0-9]+.[0-9]+.[0-9]+-*'
8
+
9
+ jobs:
10
+ publish:
11
+ name: Build and publish to PyPI
12
+ runs-on: ubuntu-latest
13
+ permissions:
14
+ id-token: write
15
+ steps:
16
+ - name: Checkout code
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: '3.11'
23
+
24
+ - name: Update version
25
+ run: |
26
+ # Strip 'v' prefix from tag
27
+ VERSION="${GITHUB_REF_NAME#v}"
28
+ echo "Publishing version: ${VERSION}"
29
+ # Update pyproject.toml
30
+ sed -i "s/^version = \".*\"/version = \"${VERSION}\"/" pyproject.toml
31
+ # Update __version__ in the package
32
+ sed -i "s/__version__ = \".*\"/__version__ = \"${VERSION}\"/" sprites_adk/__init__.py
33
+
34
+ - name: Install and test
35
+ run: |
36
+ python -m pip install --upgrade pip
37
+ pip install '.[dev]' build
38
+ pytest -q
39
+
40
+ - name: Build package
41
+ run: python -m build
42
+
43
+ - name: Publish to PyPI
44
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,7 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .pytest_cache/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Fly.io
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,144 @@
1
+ Metadata-Version: 2.4
2
+ Name: sprites-adk
3
+ Version: 0.1.0
4
+ Summary: Google ADK plugin for Sprites: persistent, stateful Linux sandboxes with checkpoint/restore for AI agents.
5
+ Project-URL: Homepage, https://sprites.dev
6
+ Project-URL: Documentation, https://docs.sprites.dev
7
+ Project-URL: Repository, https://github.com/superfly/sprites-adk
8
+ Author: Fly.io
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: adk,agents,code-execution,fly.io,google-adk,sandbox,sprites
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: >=3.9
23
+ Requires-Dist: google-adk>=1.0.0
24
+ Requires-Dist: sprites-py>=0.2.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=7.0; extra == 'dev'
27
+ Description-Content-Type: text/markdown
28
+
29
+ # sprites-adk
30
+
31
+ Google [ADK](https://google.github.io/adk-docs/) integration for [Sprites](https://sprites.dev) — persistent, stateful Linux sandboxes for AI agents, with checkpoint/restore, from [Fly.io](https://fly.io).
32
+
33
+ Most agent sandboxes are ephemeral: the environment vanishes when the session ends. A Sprite is a **stateful Linux microVM** that suspends when idle and keeps everything — files, packages, databases, running services — so your agent can resume yesterday's environment today. And because Sprites support **checkpoints**, your agent can snapshot the whole environment before a risky change and roll back if it goes wrong.
34
+
35
+ ## Installation
36
+
37
+ ```sh
38
+ pip install sprites-adk
39
+ ```
40
+
41
+ You'll need a Sprites API token ([get started](https://docs.sprites.dev/quickstart/)):
42
+
43
+ ```sh
44
+ export SPRITES_TOKEN=...
45
+ ```
46
+
47
+ ## Quickstart
48
+
49
+ ```python
50
+ from google.adk.agents import Agent
51
+ from sprites_adk import SpritesPlugin
52
+
53
+ plugin = SpritesPlugin() # or SpritesPlugin(sprite_name="my-project") for a persistent env
54
+
55
+ root_agent = Agent(
56
+ model="gemini-flash-latest",
57
+ name="sprite_agent",
58
+ instruction="Run code and commands in the Sprite sandbox, not locally.",
59
+ tools=plugin.get_tools(),
60
+ )
61
+ ```
62
+
63
+ Pass the plugin to your runner to get lifecycle callbacks and error handling:
64
+
65
+ ```python
66
+ runner = InMemoryRunner(agent=root_agent, plugins=[plugin])
67
+ ```
68
+
69
+ ## Two modes
70
+
71
+ | | `SpritesPlugin()` | `SpritesPlugin(sprite_name="my-project")` |
72
+ |---|---|---|
73
+ | Sprite name | auto-generated `adk-…` | yours |
74
+ | Reused across sessions | no | **yes — full state persists** |
75
+ | Destroyed on `plugin.close()` | yes | no |
76
+
77
+ The Sprite is created lazily on first tool use; constructing the agent needs no network. Sprites suspend automatically when idle — a parked environment costs (almost) nothing.
78
+
79
+ ## Tools
80
+
81
+ | Tool | Description |
82
+ |---|---|
83
+ | `execute_command_in_sprite` | Run a shell command (cwd, timeout supported) |
84
+ | `execute_code_in_sprite` | Run a Python / JavaScript / bash snippet |
85
+ | `write_file_to_sprite` | Write a text file (parents auto-created) |
86
+ | `read_file_from_sprite` | Read a text file |
87
+ | `create_sprite_checkpoint` | Snapshot the entire environment |
88
+ | `list_sprite_checkpoints` | List checkpoints, newest first |
89
+ | `restore_sprite_checkpoint` | Roll back to a checkpoint (**destructive**, requires `confirm=true`) |
90
+
91
+ All tools return structured dicts (`success`, `stdout`/`stderr`/`exit_code`, …); failures come back as `{"success": false, "error": ...}` so the agent can adapt instead of crashing the run.
92
+
93
+ File reads and writes run as commands inside the Sprite (via `base64`, so quotes/newlines/unicode survive) rather than through a separate filesystem API. That keeps them consistent with everything else the agent does — in particular, files written this way are correctly reverted by `restore_sprite_checkpoint`. `write_file_to_sprite` is capped at 256 KB; generate larger files with a command inside the Sprite. `/tmp` is tmpfs and is not captured by checkpoints.
94
+
95
+ ### A note on restore
96
+
97
+ `restore_sprite_checkpoint` rewinds the **whole environment** and permanently discards anything newer than the checkpoint. The tool refuses to run unless `confirm=true` is passed, and its description instructs the model to get explicit user confirmation first.
98
+
99
+ ## Configuration
100
+
101
+ ```python
102
+ SpritesPlugin(
103
+ token=None, # default: $SPRITES_TOKEN
104
+ sprite_name=None, # default: auto-generated "adk-…"
105
+ plugin_name="sprites_plugin",
106
+ base_url="https://api.sprites.dev",
107
+ destroy_on_close=None, # default: True if unnamed, False if named
108
+ client_timeout=600.0, # HTTP timeout for Sprites API calls
109
+ )
110
+ ```
111
+
112
+ ## Examples
113
+
114
+ - [`examples/quickstart.py`](examples/quickstart.py) — minimal agent
115
+ - [`examples/persistent_environment.py`](examples/persistent_environment.py) — a named dev environment that survives across sessions
116
+ - [`examples/checkpoint_rollback.py`](examples/checkpoint_rollback.py) — snapshot, break things, roll back
117
+
118
+ ## Development
119
+
120
+ ```sh
121
+ python -m venv .venv && .venv/bin/pip install -e '.[dev]'
122
+ .venv/bin/pytest
123
+ ```
124
+
125
+ ### Releasing
126
+
127
+ Publishing to PyPI is automated via [`.github/workflows/publish.yml`](.github/workflows/publish.yml). Push a `vX.Y.Z` tag and the workflow stamps that version into `pyproject.toml` and `sprites_adk/__init__.py`, runs the tests, builds, and publishes via PyPI trusted publishing (OIDC — no API tokens):
128
+
129
+ ```sh
130
+ git tag v0.1.0
131
+ git push origin v0.1.0
132
+ ```
133
+
134
+ This requires a one-time [PyPI trusted publisher](https://docs.pypi.org/trusted-publishers/) configured for the `sprites-adk` project pointing at `superfly/sprites-adk` and workflow `publish.yml`.
135
+
136
+ ## Resources
137
+
138
+ - [Sprites docs](https://docs.sprites.dev)
139
+ - [Sprites Python SDK](https://github.com/superfly/sprites-py)
140
+ - [Google ADK docs](https://google.github.io/adk-docs/)
141
+
142
+ ## License
143
+
144
+ MIT
@@ -0,0 +1,116 @@
1
+ # sprites-adk
2
+
3
+ Google [ADK](https://google.github.io/adk-docs/) integration for [Sprites](https://sprites.dev) — persistent, stateful Linux sandboxes for AI agents, with checkpoint/restore, from [Fly.io](https://fly.io).
4
+
5
+ Most agent sandboxes are ephemeral: the environment vanishes when the session ends. A Sprite is a **stateful Linux microVM** that suspends when idle and keeps everything — files, packages, databases, running services — so your agent can resume yesterday's environment today. And because Sprites support **checkpoints**, your agent can snapshot the whole environment before a risky change and roll back if it goes wrong.
6
+
7
+ ## Installation
8
+
9
+ ```sh
10
+ pip install sprites-adk
11
+ ```
12
+
13
+ You'll need a Sprites API token ([get started](https://docs.sprites.dev/quickstart/)):
14
+
15
+ ```sh
16
+ export SPRITES_TOKEN=...
17
+ ```
18
+
19
+ ## Quickstart
20
+
21
+ ```python
22
+ from google.adk.agents import Agent
23
+ from sprites_adk import SpritesPlugin
24
+
25
+ plugin = SpritesPlugin() # or SpritesPlugin(sprite_name="my-project") for a persistent env
26
+
27
+ root_agent = Agent(
28
+ model="gemini-flash-latest",
29
+ name="sprite_agent",
30
+ instruction="Run code and commands in the Sprite sandbox, not locally.",
31
+ tools=plugin.get_tools(),
32
+ )
33
+ ```
34
+
35
+ Pass the plugin to your runner to get lifecycle callbacks and error handling:
36
+
37
+ ```python
38
+ runner = InMemoryRunner(agent=root_agent, plugins=[plugin])
39
+ ```
40
+
41
+ ## Two modes
42
+
43
+ | | `SpritesPlugin()` | `SpritesPlugin(sprite_name="my-project")` |
44
+ |---|---|---|
45
+ | Sprite name | auto-generated `adk-…` | yours |
46
+ | Reused across sessions | no | **yes — full state persists** |
47
+ | Destroyed on `plugin.close()` | yes | no |
48
+
49
+ The Sprite is created lazily on first tool use; constructing the agent needs no network. Sprites suspend automatically when idle — a parked environment costs (almost) nothing.
50
+
51
+ ## Tools
52
+
53
+ | Tool | Description |
54
+ |---|---|
55
+ | `execute_command_in_sprite` | Run a shell command (cwd, timeout supported) |
56
+ | `execute_code_in_sprite` | Run a Python / JavaScript / bash snippet |
57
+ | `write_file_to_sprite` | Write a text file (parents auto-created) |
58
+ | `read_file_from_sprite` | Read a text file |
59
+ | `create_sprite_checkpoint` | Snapshot the entire environment |
60
+ | `list_sprite_checkpoints` | List checkpoints, newest first |
61
+ | `restore_sprite_checkpoint` | Roll back to a checkpoint (**destructive**, requires `confirm=true`) |
62
+
63
+ All tools return structured dicts (`success`, `stdout`/`stderr`/`exit_code`, …); failures come back as `{"success": false, "error": ...}` so the agent can adapt instead of crashing the run.
64
+
65
+ File reads and writes run as commands inside the Sprite (via `base64`, so quotes/newlines/unicode survive) rather than through a separate filesystem API. That keeps them consistent with everything else the agent does — in particular, files written this way are correctly reverted by `restore_sprite_checkpoint`. `write_file_to_sprite` is capped at 256 KB; generate larger files with a command inside the Sprite. `/tmp` is tmpfs and is not captured by checkpoints.
66
+
67
+ ### A note on restore
68
+
69
+ `restore_sprite_checkpoint` rewinds the **whole environment** and permanently discards anything newer than the checkpoint. The tool refuses to run unless `confirm=true` is passed, and its description instructs the model to get explicit user confirmation first.
70
+
71
+ ## Configuration
72
+
73
+ ```python
74
+ SpritesPlugin(
75
+ token=None, # default: $SPRITES_TOKEN
76
+ sprite_name=None, # default: auto-generated "adk-…"
77
+ plugin_name="sprites_plugin",
78
+ base_url="https://api.sprites.dev",
79
+ destroy_on_close=None, # default: True if unnamed, False if named
80
+ client_timeout=600.0, # HTTP timeout for Sprites API calls
81
+ )
82
+ ```
83
+
84
+ ## Examples
85
+
86
+ - [`examples/quickstart.py`](examples/quickstart.py) — minimal agent
87
+ - [`examples/persistent_environment.py`](examples/persistent_environment.py) — a named dev environment that survives across sessions
88
+ - [`examples/checkpoint_rollback.py`](examples/checkpoint_rollback.py) — snapshot, break things, roll back
89
+
90
+ ## Development
91
+
92
+ ```sh
93
+ python -m venv .venv && .venv/bin/pip install -e '.[dev]'
94
+ .venv/bin/pytest
95
+ ```
96
+
97
+ ### Releasing
98
+
99
+ Publishing to PyPI is automated via [`.github/workflows/publish.yml`](.github/workflows/publish.yml). Push a `vX.Y.Z` tag and the workflow stamps that version into `pyproject.toml` and `sprites_adk/__init__.py`, runs the tests, builds, and publishes via PyPI trusted publishing (OIDC — no API tokens):
100
+
101
+ ```sh
102
+ git tag v0.1.0
103
+ git push origin v0.1.0
104
+ ```
105
+
106
+ This requires a one-time [PyPI trusted publisher](https://docs.pypi.org/trusted-publishers/) configured for the `sprites-adk` project pointing at `superfly/sprites-adk` and workflow `publish.yml`.
107
+
108
+ ## Resources
109
+
110
+ - [Sprites docs](https://docs.sprites.dev)
111
+ - [Sprites Python SDK](https://github.com/superfly/sprites-py)
112
+ - [Google ADK docs](https://google.github.io/adk-docs/)
113
+
114
+ ## License
115
+
116
+ MIT
@@ -0,0 +1,16 @@
1
+ # ADK docs catalog submission
2
+
3
+ This directory holds the draft page for the `google/adk-docs` integrations
4
+ catalog, per their [contributing guide](https://github.com/google/adk-docs/blob/main/CONTRIBUTING.md#integrations).
5
+
6
+ To submit, open a PR against `google/adk-docs` that adds:
7
+
8
+ 1. `docs/integrations/sprites.md` — the page in this directory.
9
+ 2. `docs/integrations/assets/sprites.png` — a square, card-sized Sprites
10
+ logo (not included here; export one from the sprites.dev brand assets).
11
+ 3. Optional but encouraged: screenshots of an agent session using the
12
+ integration, also under `docs/integrations/assets/`.
13
+
14
+ Their review criteria: working/testable code examples, clear value for ADK
15
+ developers, and terms-of-service compliance. Publish `sprites-adk` to PyPI
16
+ before opening the PR so the installation instructions work.
@@ -0,0 +1,79 @@
1
+ ---
2
+ catalog_title: Sprites
3
+ catalog_description: Persistent, stateful Linux sandboxes with checkpoint/restore for agent code execution, by Fly.io
4
+ catalog_icon: /integrations/assets/sprites.png
5
+ ---
6
+
7
+ # Sprites
8
+
9
+ [Sprites](https://sprites.dev) are persistent, stateful Linux sandboxes from [Fly.io](https://fly.io). Unlike ephemeral sandboxes, a Sprite keeps its filesystem, installed packages, and services between sessions — it suspends when idle and resumes in milliseconds. The `sprites-adk` plugin gives ADK agents a full Linux environment with a capability most sandboxes don't have: **checkpoint and restore**, so an agent can snapshot the environment before a risky change and roll back if it goes wrong.
10
+
11
+ Supported in ADK Python.
12
+
13
+ ## Use cases
14
+
15
+ - **Persistent development environments**: a named Sprite is reused across agent sessions — packages installed yesterday are still there today, so long-running projects don't rebuild the world every session.
16
+ - **Secure code execution**: run Python, JavaScript, or bash produced by the model in an isolated microVM instead of the host machine.
17
+ - **Fearless experimentation**: checkpoint the entire environment before package upgrades, migrations, or bulk edits; restore if the experiment breaks it.
18
+ - **File workflows**: write scripts and data into the sandbox, run them, and read results back.
19
+
20
+ ## Prerequisites
21
+
22
+ - A [Sprites account and API token](https://docs.sprites.dev/quickstart/) (`sprite tokens create`), exported as `SPRITES_TOKEN`.
23
+ - A Google API key for the Gemini model used by your agent.
24
+
25
+ ## Installation
26
+
27
+ ```sh
28
+ pip install sprites-adk
29
+ ```
30
+
31
+ ## Use with agent
32
+
33
+ ```python
34
+ from google.adk.agents import Agent
35
+ from sprites_adk import SpritesPlugin
36
+
37
+ # SpritesPlugin() creates an ephemeral sandbox, destroyed on plugin.close().
38
+ # SpritesPlugin(sprite_name="my-project") attaches to a persistent environment
39
+ # that keeps all state between sessions and is never destroyed automatically.
40
+ plugin = SpritesPlugin()
41
+
42
+ root_agent = Agent(
43
+ model="gemini-flash-latest",
44
+ name="sprite_agent",
45
+ instruction=(
46
+ "Run code and commands inside the Sprite sandbox, not locally. "
47
+ "Create a checkpoint before risky operations."
48
+ ),
49
+ tools=plugin.get_tools(),
50
+ )
51
+ ```
52
+
53
+ For lifecycle callbacks and structured tool-error handling, also register the plugin with your runner:
54
+
55
+ ```python
56
+ from google.adk.runners import InMemoryRunner
57
+
58
+ runner = InMemoryRunner(agent=root_agent, plugins=[plugin])
59
+ ```
60
+
61
+ The Sprite is created lazily on first tool use. Named Sprites are get-or-create: if a Sprite with that name already exists, the agent attaches to it with all of its state intact.
62
+
63
+ ## Available tools
64
+
65
+ | Tool | Description |
66
+ | --- | --- |
67
+ | `execute_command_in_sprite` | Run a shell command with optional working directory and timeout. |
68
+ | `execute_code_in_sprite` | Run a Python, JavaScript, or bash snippet. |
69
+ | `write_file_to_sprite` | Write a text file (parent directories auto-created). |
70
+ | `read_file_from_sprite` | Read a text file from the sandbox. |
71
+ | `create_sprite_checkpoint` | Snapshot the entire environment (filesystem, packages, processes). |
72
+ | `list_sprite_checkpoints` | List checkpoints, newest first. |
73
+ | `restore_sprite_checkpoint` | Roll back to a checkpoint. Destructive — discards newer state and requires explicit `confirm=true`. |
74
+
75
+ ## Resources
76
+
77
+ - [sprites-adk on PyPI](https://pypi.org/project/sprites-adk/)
78
+ - [Source code and examples](https://github.com/superfly/sprites-adk)
79
+ - [Sprites documentation](https://docs.sprites.dev)
@@ -0,0 +1,62 @@
1
+ """Checkpoint / rollback: let an agent experiment fearlessly.
2
+
3
+ The agent snapshots the Sprite before a risky change; if the change breaks
4
+ the environment, it rolls back to the checkpoint instead of trying to
5
+ hand-undo the damage. Restore is destructive (it discards state newer than
6
+ the checkpoint), so the restore tool requires explicit confirmation.
7
+
8
+ export SPRITES_TOKEN=...
9
+ export GOOGLE_API_KEY=...
10
+ python examples/checkpoint_rollback.py
11
+ """
12
+
13
+ import asyncio
14
+
15
+ from google.adk.agents import Agent
16
+ from google.adk.runners import InMemoryRunner
17
+ from google.genai import types
18
+
19
+ from sprites_adk import SpritesPlugin
20
+
21
+ PROMPT = """
22
+ Set up a marker file /work/state.txt containing "v1".
23
+ Then create a checkpoint with the comment "before-experiment".
24
+ Then simulate a failed experiment: overwrite /work/state.txt with "broken".
25
+ Finally, restore the checkpoint (I confirm the restore - discarding the
26
+ "broken" state is exactly what I want) and read /work/state.txt to prove
27
+ the environment was rolled back.
28
+ """
29
+
30
+
31
+ async def main() -> None:
32
+ plugin = SpritesPlugin() # ephemeral sprite, destroyed on close
33
+
34
+ agent = Agent(
35
+ model="gemini-flash-latest",
36
+ name="rollback_agent",
37
+ instruction=(
38
+ "You operate a Sprite sandbox with checkpoint/restore. Before "
39
+ "risky changes, create a checkpoint. Restoring discards newer "
40
+ "state, so only pass confirm=true when the user has clearly "
41
+ "agreed."
42
+ ),
43
+ tools=plugin.get_tools(),
44
+ )
45
+
46
+ runner = InMemoryRunner(agent=agent, plugins=[plugin])
47
+ session = await runner.session_service.create_session(
48
+ app_name=runner.app_name, user_id="demo"
49
+ )
50
+ async for event in runner.run_async(
51
+ user_id="demo",
52
+ session_id=session.id,
53
+ new_message=types.Content(role="user", parts=[types.Part(text=PROMPT)]),
54
+ ):
55
+ if event.content and event.content.parts and event.content.parts[0].text:
56
+ print(event.content.parts[0].text)
57
+
58
+ await plugin.close()
59
+
60
+
61
+ if __name__ == "__main__":
62
+ asyncio.run(main())
@@ -0,0 +1,61 @@
1
+ """A persistent development environment that survives across sessions.
2
+
3
+ Because the Sprite is named, every run of this script attaches to the SAME
4
+ Linux environment: packages installed yesterday are still installed today,
5
+ files are still there, and the agent picks up where it left off. Sprites
6
+ suspend automatically when idle, so a parked environment costs (almost)
7
+ nothing.
8
+
9
+ export SPRITES_TOKEN=...
10
+ export GOOGLE_API_KEY=...
11
+ python examples/persistent_environment.py "install uv and create a fastapi project in /app"
12
+ # ...later, a new process, same environment:
13
+ python examples/persistent_environment.py "add a /health endpoint to the project in /app"
14
+ """
15
+
16
+ import asyncio
17
+ import sys
18
+
19
+ from google.adk.agents import Agent
20
+ from google.adk.runners import InMemoryRunner
21
+ from google.genai import types
22
+
23
+ from sprites_adk import SpritesPlugin
24
+
25
+
26
+ async def main() -> None:
27
+ prompt = " ".join(sys.argv[1:]) or "What is in /app? Summarize the project state."
28
+
29
+ # Named sprite: reused across sessions, never auto-destroyed.
30
+ plugin = SpritesPlugin(sprite_name="my-dev-environment")
31
+
32
+ agent = Agent(
33
+ model="gemini-flash-latest",
34
+ name="dev_env_agent",
35
+ instruction=(
36
+ "You maintain a long-lived development environment inside a "
37
+ "Sprite. All commands, code, and files run inside the Sprite. "
38
+ "It persists between sessions, so check existing state before "
39
+ "assuming a fresh machine. Create a checkpoint before risky "
40
+ "changes."
41
+ ),
42
+ tools=plugin.get_tools(),
43
+ )
44
+
45
+ runner = InMemoryRunner(agent=agent, plugins=[plugin])
46
+ session = await runner.session_service.create_session(
47
+ app_name=runner.app_name, user_id="demo"
48
+ )
49
+ async for event in runner.run_async(
50
+ user_id="demo",
51
+ session_id=session.id,
52
+ new_message=types.Content(role="user", parts=[types.Part(text=prompt)]),
53
+ ):
54
+ if event.content and event.content.parts and event.content.parts[0].text:
55
+ print(event.content.parts[0].text)
56
+
57
+ await plugin.close() # named sprite is preserved
58
+
59
+
60
+ if __name__ == "__main__":
61
+ asyncio.run(main())
@@ -0,0 +1,31 @@
1
+ """Quickstart: an ADK agent with a Sprites sandbox.
2
+
3
+ Prerequisites:
4
+ pip install sprites-adk
5
+ export SPRITES_TOKEN=... # `sprite tokens create`
6
+ export GOOGLE_API_KEY=... # for the Gemini model
7
+
8
+ Run with the ADK CLI from the directory above this file:
9
+ adk run examples
10
+ or programmatically via Runner (see persistent_environment.py).
11
+ """
12
+
13
+ from google.adk.agents import Agent
14
+
15
+ from sprites_adk import SpritesPlugin
16
+
17
+ # No sprite_name: an ephemeral `adk-` prefixed Sprite is created on first
18
+ # tool use and destroyed when the plugin is closed.
19
+ plugin = SpritesPlugin()
20
+
21
+ root_agent = Agent(
22
+ model="gemini-flash-latest",
23
+ name="sprite_agent",
24
+ instruction=(
25
+ "You help users build and test code inside a persistent Linux "
26
+ "sandbox (a Sprite). Run commands and code in the sandbox, not "
27
+ "locally. Create a checkpoint before risky operations such as "
28
+ "package installs or migrations."
29
+ ),
30
+ tools=plugin.get_tools(),
31
+ )
@@ -0,0 +1,40 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "sprites-adk"
7
+ version = "0.1.0"
8
+ description = "Google ADK plugin for Sprites: persistent, stateful Linux sandboxes with checkpoint/restore for AI agents."
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.9"
12
+ authors = [{ name = "Fly.io" }]
13
+ keywords = ["adk", "google-adk", "agents", "sandbox", "sprites", "fly.io", "code-execution"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.9",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Topic :: Software Development :: Libraries :: Python Modules",
25
+ ]
26
+ dependencies = [
27
+ "google-adk>=1.0.0",
28
+ "sprites-py>=0.2.0",
29
+ ]
30
+
31
+ [project.urls]
32
+ Homepage = "https://sprites.dev"
33
+ Documentation = "https://docs.sprites.dev"
34
+ Repository = "https://github.com/superfly/sprites-adk"
35
+
36
+ [project.optional-dependencies]
37
+ dev = ["pytest>=7.0"]
38
+
39
+ [tool.hatch.build.targets.wheel]
40
+ packages = ["sprites_adk"]
@@ -0,0 +1,30 @@
1
+ """Google ADK integration for Sprites (https://sprites.dev).
2
+
3
+ Gives ADK agents a persistent, stateful Linux sandbox with checkpoint and
4
+ restore, backed by Fly.io's Sprites.
5
+ """
6
+
7
+ from .plugin import SpritesPlugin
8
+ from .tools import (
9
+ CreateCheckpointTool,
10
+ ExecuteCodeTool,
11
+ ExecuteCommandTool,
12
+ ListCheckpointsTool,
13
+ ReadFileTool,
14
+ RestoreCheckpointTool,
15
+ WriteFileTool,
16
+ )
17
+
18
+ __version__ = "0.1.0"
19
+
20
+ __all__ = [
21
+ "SpritesPlugin",
22
+ "ExecuteCommandTool",
23
+ "ExecuteCodeTool",
24
+ "WriteFileTool",
25
+ "ReadFileTool",
26
+ "CreateCheckpointTool",
27
+ "ListCheckpointsTool",
28
+ "RestoreCheckpointTool",
29
+ "__version__",
30
+ ]