Skip to content

Commit 52da215

Browse files
docs: document release preparation and publication workflow (#323)
## Summary Document version preparation, validation, and publication for crates, Python wheels, and Docker Hub containers. Explain the explicit crates-to-container/website handoff, credentials and environment rules, nightly retention, artifact verification, and container-only recovery after a partial release. Link the guide from the developer and Python installation docs, MkDocs navigation, and AGENTS.md. Use GitHub's `role_name` in release preparation so maintainers can run it, matching the crates and container workflows. The legacy `permission` field maps maintainers to `write` and rejected them. Correct release notes by moving the newly merged image changes from 0.6.0 to Unreleased, adding the Rust content-type migration notes, and documenting MCP pagination and container publishing. ## Test Plan - Cross-checked instructions against all five release/website workflow files and current package metadata; independent review completed. - Executed the actual preparation authorization step against stub API fixtures: reproduced maintainer rejection before the fix; afterward admin/maintain pass and write/triage/read/none remain rejected. - `pre-commit run --all-files` passed. - `mkdocs build --strict` passed. - `git diff --cached --check` passed. No release workflows were dispatched or artifacts published. --------- Signed-off-by: Francisco Javier Arceo <farceo@redhat.com>
1 parent b70edd4 commit 52da215

7 files changed

Lines changed: 252 additions & 46 deletions

File tree

‎.github/workflows/prepare-release-pr.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
set -euo pipefail
3232
permission="$(gh api \
3333
"repos/${{ github.repository }}/collaborators/${{ github.actor }}/permission" \
34-
--jq '.permission')"
34+
--jq '.role_name')"
3535
3636
case "$permission" in
3737
admin|maintain)

‎AGENTS.md‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,22 @@ uv pip install -r docs/requirements.txt
8484
uv run mkdocs serve
8585
```
8686

87+
## Releases
88+
89+
- Read [the release guide](docs/developing/releases.md) before preparing or publishing a release or changing release
90+
automation. Keep that guide synchronized with the workflow inputs and checks.
91+
- PRs and merges validate artifacts; they do not publish packages. Release preparation, crates publication, and PyPI
92+
publication use separate GitHub Actions workflows. Trigger publishing on `main` after checking the run's commit
93+
and version; GitHub Actions handles validation and registry uploads. The crates workflow also publishes the
94+
container from the release tag. Container-only recovery uses the dedicated workflow; do not republish packages
95+
to repair an image or website failure.
96+
- Use the Cargo workspace's declared version as the source of truth. Keep the core dependency and lockfile aligned;
97+
do not invent a default release version or a separate Python version.
98+
- Preserve duplicate-version failures and all platform-specific wheel checks. Inspect registry state before retrying
99+
any failed publication; never add `skip-existing` or blindly retry a partial upload.
100+
- Verify actual registry artifacts before reporting a release complete or updating website install versions. PyPI
101+
README/metadata fixes require a new release to reach the published package page.
102+
87103
## Code Style
88104

89105
- Rust edition: 2024.

‎CHANGELOG.md‎

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,23 @@ All notable changes to Agentic API are documented here.
66

77
### Added
88

9+
- Verified image preservation through the Responses gateway end to end (#253): integration coverage for mixed
10+
text/image ordering, multiple images per turn, client-executed `view_image` tool output, `previous_response_id`
11+
continuation, `conversation_id` rehydration, stateless `store: false` proxying, and compaction of retained
12+
image-bearing user messages, over both the HTTP and WebSocket transports.
13+
- Recorded paired image cassettes — client → OpenAI as the reference and client → gateway → vLLM serving
14+
`Qwen/Qwen2.5-VL-3B-Instruct` — for a text-and-image message, two interleaved images, a `previous_response_id`
15+
follow-up, and a client-executed tool returning an image through a structured `function_call_output`, each
16+
streaming and non-streaming. Replay coverage compares request shape, completed-response structure, the streaming
17+
event lifecycle, and the history the gateway forwards on continuation; model wording is never compared (#253).
18+
The cassette recorder accepts `--input-file` for the first of several turns and sends a tool handler's list of
19+
content parts as a structured output array.
20+
- Added automated Docker Hub release and nightly container publishing with 30-day nightly tag retention (#322).
921
- Added typed per-model input-modality overrides to `config.toml`
1022
(`[models."<served-model-id>"] input_modalities = ["text", "image"]`), validated at startup:
1123
unknown modality names, empty lists, duplicates, and image-only lists are rejected with the
1224
offending file and line (#252).
13-
- Added Brave Search as a selectable backend for the gateway-owned `web_search` tool (#294, Phase 2 of #291).
25+
- Added Brave Search as a selectable backend for the gateway-executed built-in `web_search` tool (#294, Phase 2 of #291).
1426
Select it with `AGENTIC_WEB_SEARCH_PROVIDER=brave` or `[web_search] provider = "brave"` and supply `BRAVE_API_KEY`;
1527
the endpoint defaults to `https://api.search.brave.com` and can be overridden with `AGENTIC_WEB_SEARCH_BASE_URL`
1628
or `[web_search] base_url`. Web and news results come from one request per query. The gateway adapts the shared
@@ -27,6 +39,13 @@ All notable changes to Agentic API are documented here.
2739

2840
### Changed
2941

42+
- Modeled `refusal` as an assistant-history content part so OpenAI-style history replays through the typed
43+
Responses executor instead of being rejected as unmodeled (#253).
44+
- Changed Rust input-content APIs (#263): `InputTextContent`, `InputImageContent`, and `InputFileContent` now retain
45+
unmodeled fields in `extra`. Use `InputTextContent::new(text)` or supply `extra: Default::default()` when migrating
46+
struct literals. `InputContent` gains `Refusal(RefusalContent)` and replaces the unit `Unknown` variant with
47+
`Unknown(String)`; update exhaustive matches and constructors. `Unknown` cannot be serialized and typed execution
48+
rejects it with the original content type in the error. Existing content-type re-export paths are preserved.
3049
- Rust `agentic_core::config::Config` struct literals must now provide `responses: ResponsesConfig::default()`
3150
(or validated custom limits). `ExecutionContext::new` keeps its signature and defaults; use
3251
`ExecutionContext::with_responses_config` to override them. `ExecuteRequest::with_max_stream_event_bytes` and
@@ -56,6 +75,14 @@ All notable changes to Agentic API are documented here.
5675

5776
### Fixed
5877

78+
- Rejected message content the typed Responses executor cannot convey — unmodeled part types and empty part arrays,
79+
alongside the existing `input_file` rejection — with a `400` naming the offending part, instead of forwarding a
80+
synthetic `{"type": "unknown"}` part or silently dropping it. Modeled parts keep their unmodeled extension fields
81+
through the typed path, so a message is never mutated in transit, never means something different on the typed
82+
path than on the raw `store: false` path, and is never persisted with content the client did not send (#253).
83+
- Counted an image referenced by `file_id` as retained context during compaction, matching inline images (#253).
84+
- Followed MCP `tools/list` pagination to discover tools beyond the first page, including opaque empty cursors;
85+
reject repeated cursors and bounded-pagination failures instead of exposing partial discovery (#311).
5986
- Accounted for unrestricted output role/type/status strings, empty web-search query entries, pending or late-bound
6087
item identities, and terminal error details in response limits. Kept reasoning-part and shell-command completion
6188
accounting linear for sequential multipart streams (#304).
@@ -160,17 +187,6 @@ All notable changes to Agentic API are documented here.
160187
stream, and bounded concurrency across streams (#240).
161188
- Added compile-time OpenAPI 3.1 schema generation and checked-in schema validation for the HTTP API (#229).
162189
- Added pinned SGLang conformance recordings, replay coverage, and launch and recording guidance (#267).
163-
- Verified image preservation through the Responses gateway end to end (#253): integration coverage for mixed
164-
text/image ordering, multiple images per turn, client-executed `view_image` tool output, `previous_response_id`
165-
continuation, `conversation_id` rehydration, stateless `store: false` proxying, and compaction of retained
166-
image-bearing user messages, over both the HTTP and WebSocket transports.
167-
- Recorded paired image cassettes — client → OpenAI as the reference and client → gateway → vLLM serving
168-
`Qwen/Qwen2.5-VL-3B-Instruct` — for a text-and-image message, two interleaved images, a `previous_response_id`
169-
follow-up, and a client-executed tool returning an image through a structured `function_call_output`, each
170-
streaming and non-streaming. Replay coverage compares request shape, completed-response structure, the streaming
171-
event lifecycle, and the history the gateway forwards on continuation; model wording is never compared (#253).
172-
The cassette recorder accepts `--input-file` for the first of several turns and sends a tool handler's list of
173-
content parts as a structured output array.
174190

175191
### Changed
176192

@@ -186,8 +202,6 @@ All notable changes to Agentic API are documented here.
186202
architecture (#246).
187203
- Updated the execution architecture documentation to match the current scheduler and llm-d backend (#270).
188204
- Preserved the typed `ignore_eos` extension when forwarding Responses requests to vLLM (#268).
189-
- Modeled `refusal` as an assistant-history content part so OpenAI-style history replays through the typed
190-
Responses executor instead of being rejected as unmodeled (#253).
191205

192206
### Fixed
193207

@@ -199,12 +213,6 @@ All notable changes to Agentic API are documented here.
199213
- Required a healthy packaged gateway before `agentic-api doctor --mode local` reports success (#223).
200214
- Rebuilt workspace crates after `cargo-chef` dependency cooking so container binaries carry current source and package
201215
metadata (#208, #209).
202-
- Rejected message content the typed Responses executor cannot convey — unmodeled part types and empty part arrays,
203-
alongside the existing `input_file` rejection — with a `400` naming the offending part, instead of forwarding a
204-
synthetic `{"type": "unknown"}` part or silently dropping it. Modeled parts keep their unmodeled extension fields
205-
through the typed path, so a message is never mutated in transit, never means something different on the typed
206-
path than on the raw `store: false` path, and is never persisted with content the client did not send (#253).
207-
- Counted an image referenced by `file_id` as retained context during compaction, matching inline images (#253).
208216
- Hardened split execution with atomic duplicate persistence, strict relayed-response validation, independent secret
209217
validation, bounded hydrate and persist payloads, stable error envelopes, and graceful shutdown error propagation
210218
(#235).

‎docs/developing/getting-started.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,8 @@ options.
9696
[sccache]: https://github.com/mozilla/sccache
9797
[sccache-install]: https://github.com/mozilla/sccache#installation
9898
[sccache-usage]: https://github.com/mozilla/sccache#usage
99+
100+
## Releases
101+
102+
Maintainers should follow the [release guide](releases.md) to prepare a version and trigger the GitHub Actions
103+
workflows that validate and publish to crates.io and PyPI. Merging a PR does not publish a package.

0 commit comments

Comments
 (0)