Skip to content

Commit e456f30

Browse files
authored
docs(readme): rewrite docs for client-side APIs and simplify codebase (#24)
* docs(readme): rewrite docs for client-side APIs and simplify codebase * docs(agents): add async client TODO to AGENTS.md * ci(publish): add PyPI publish workflow and bump version to 0.1.1 * ci(publish): restrict build job to read-only permissions * docs(readme): rewrite intro and section structure for clarity * docs(readme): annotate architecture diagram with SDK component mappings
1 parent 55cbf25 commit e456f30

10 files changed

Lines changed: 167 additions & 176 deletions

File tree

.github/workflows/publish.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Publish to PyPI
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
jobs:
8+
build:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
contents: read
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Install uv
16+
uses: astral-sh/setup-uv@v4
17+
18+
- name: Set up Python
19+
run: uv python install 3.12
20+
21+
- name: Build package
22+
run: uv build
23+
24+
- name: Upload build artifacts
25+
uses: actions/upload-artifact@v4
26+
with:
27+
name: dist
28+
path: dist/
29+
30+
publish:
31+
needs: build
32+
runs-on: ubuntu-latest
33+
environment: pypi
34+
permissions:
35+
id-token: write
36+
steps:
37+
- name: Download build artifacts
38+
uses: actions/download-artifact@v4
39+
with:
40+
name: dist
41+
path: dist/
42+
43+
- name: Install uv
44+
uses: astral-sh/setup-uv@v4
45+
46+
- name: Publish to PyPI
47+
run: uv publish dist/*

AGENTS.md

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ cd examples/strands_math_agent && uv sync && uv run python rl_app.py
4949
|------|---------|
5050
| `src/agentcore_rl_toolkit/app.py` | `AgentCoreRLApp` base class, `@rollout_entrypoint` decorator |
5151
| `src/agentcore_rl_toolkit/frameworks/strands/vllm_model.py` | `vLLMModel` with token ID collection for RL training |
52-
| `src/agentcore_rl_toolkit/client.py` | `RolloutClient` for batch evaluation |
52+
| `src/agentcore_rl_toolkit/client.py` | `RolloutClient` and `RolloutFuture` for training integration and batch evaluation |
5353
| `src/agentcore_rl_toolkit/reward_function.py` | `RewardFunction` base class |
5454
| `examples/strands_math_agent/` | GSM8K math agent example |
5555
| `examples/strands_migration_agent/` | Java migration agent example |
@@ -68,9 +68,7 @@ agentcore-rl-toolkit/
6868
│ └── frameworks/
6969
│ └── strands/
7070
│ ├── __init__.py
71-
│ ├── app.py # StrandsAgentCoreRLApp (legacy)
72-
│ ├── vllm_model.py # vLLMModel with token ID collection
73-
│ └── rollout_collector.py # StrandsRolloutCollector (legacy)
71+
│ └── vllm_model.py # vLLMModel with token ID collection
7472
├── examples/
7573
│ ├── strands_math_agent/ # GSM8K example
7674
│ │ ├── .bedrock_agentcore/ # Dockerfiles for deployment
@@ -160,15 +158,15 @@ agent = Agent(
160158

161159

162160
@app.entrypoint
163-
async def invoke_agent(payload):
161+
def invoke_agent(payload):
164162
"""
165163
Invoke the agent with a payload
166164
"""
167165
user_input = payload.get("prompt")
168166

169167
print("User input:", user_input)
170168

171-
response = await agent.invoke_async(user_input)
169+
response = agent(user_input)
172170

173171
return response.message["content"][0]["text"]
174172

@@ -199,12 +197,14 @@ Since the client won't get results directly from HTTP:
199197
- Client polls S3 using efficient HEAD requests to detect when each result is available
200198
- No additional messaging infrastructure required — S3 is the single source of truth
201199

200+
On the client side, `RolloutClient` and `RolloutFuture` are the complement to these server-side patterns — they handle submitting requests to ACR and polling S3 for results, so both sides work together to manage long-running async agent tasks end-to-end. See the [Evaluation](#evaluation) section for details.
201+
202202
#### Core Classes
203203

204204
**AgentCoreRLApp** (`src/agentcore_rl_toolkit/app.py`)
205205
- Inherits `BedrockAgentCoreApp` - drop-in replacement
206206
- Provides `@app.rollout_entrypoint` decorator
207-
- Expects `_rollout` dict in payload following `RolloutConfig` model (experiment id, input id, s3_bucket, base_url, model_id)
207+
- Expects `_rollout` dict in payload with `RolloutConfig` fields (`exp_id`, `input_id`, `s3_bucket`) plus optional pass-through config (`base_url`, `model_id`, `sampling_params`)
208208
- Framework-agnostic: works with any agent framework, not just Strands
209209

210210
#### Utilities
@@ -253,9 +253,11 @@ See `examples/strands_math_agent` for a complete example adapting from `basic_ap
253253
- model = BedrockModel(model_id="us.anthropic.claude-sonnet-4-20250514-v1:0")
254254
- agent = Agent(model=model, tools=[calculator], system_prompt="...")
255255

256-
@app.rollout_entrypoint
257-
def invoke_agent(payload: dict):
258-
- response = await agent.invoke_async(user_input)
256+
- @app.entrypoint
257+
- def invoke_agent(payload):
258+
- response = agent(user_input)
259+
+ @app.rollout_entrypoint
260+
+ def invoke_agent(payload: dict):
259261
+ base_url = payload["_rollout"]["base_url"]
260262
+ model_id = payload["_rollout"]["model_id"]
261263
+ params = payload["_rollout"].get("sampling_params", {})
@@ -302,7 +304,13 @@ This package relies on [bedrock-agentcore-starter-toolkit](https://github.com/aw
302304

303305
Users can evaluate agents before and after training using the same `rl_app.py`.
304306

305-
**RolloutClient** (`src/agentcore_rl_toolkit/client.py`) orchestrates parallel evaluation:
307+
**RolloutClient** (`src/agentcore_rl_toolkit/client.py`) provides two invocation patterns:
308+
- **`invoke()`**: Returns a `RolloutFuture` for fine-grained control — ideal for training loops (e.g., GRPO) where you submit individual rollouts and group results by `input_id`
309+
- **`run_batch()`**: Higher-level API for batch evaluation — manages concurrency, timeouts, and polling automatically
310+
311+
Concretely, `invoke()` sends the request to ACR and returns a `RolloutFuture` immediately — meaning ACR has received the request and a background agent session is processing it. Calling `future.result(timeout=...)` blocks until the result appears in S3, polling with exponential backoff. It returns the complete rollout data (token IDs, rewards, etc.) once the agent finishes and writes to S3.
312+
313+
Both patterns share the same infrastructure:
306314
- **Rate limiting**: Handles ACR TPS limits (25)
307315
- **Concurrency control**: Manages ACR session limits (1000/account) and model API rate limits
308316
- **S3 HEAD polling**: Polls S3 for completed results using efficient HEAD requests
@@ -339,9 +347,8 @@ See `.env.example` for template. The build script sources `.env` for deployment
339347
### Adding Support for a New Framework
340348

341349
1. Create `src/agentcore_rl_toolkit/frameworks/{framework}/`
342-
2. Implement `{Framework}AgentCoreRLApp` extending `AgentCoreRLApp`
343-
3. Implement rollout collector appropriate for the framework
344-
4. Export in `src/agentcore_rl_toolkit/__init__.py`
350+
2. Implement framework-specific model or utility (e.g., `vLLMModel` for Strands) that collects token IDs and rollout data
351+
3. Export in the framework's `__init__.py`
345352

346353
### Running Tests
347354

@@ -426,15 +433,9 @@ uv run pre-commit install
426433

427434
## Known Limitations & TODOs
428435

429-
### Testing & CI
430-
- Limited test coverage (expansion planned)
431-
- No CI/CD pipeline yet (planned)
432-
433436
### Design Improvements
434-
- **Model creation**: `vLLMModel` is currently under `frameworks/strands/` but is largely framework-agnostic; may be moved to a shared location
435-
436-
### Dependency Updates
437-
- **bedrock-agentcore-starter-toolkit**: Needs upgrade to latest version for better Docker utilities and local testing support
437+
- **Model gateway**: `vLLMModel` is currently framework specific under `frameworks/strands/`. In the future, we want to eliminate the need for a customized model to collect token ids. Instead, a gateway server will be used to direct model inference calls, automatically intercept the token ids, and persist to databases so that users don't have to manually collect them. This will also better reveal the status of a rollout session and preserve partial rollouts.
438+
- **Async client**: `RolloutClient` and `RolloutFuture` are currently synchronous (blocking). We plan to add async-compatible versions so they can be used natively in `asyncio` event loops.
438439

439440
---
440441

0 commit comments

Comments
 (0)