Thanks for contributing to opencode-a2a.
This repository maintains an OpenCode A2A runtime. Changes should keep runtime behavior, Agent Card declarations, OpenAPI examples, and machine-readable extension contracts aligned.
- Read README.md for project scope and user/operator paths.
- Read docs/guide.md for runtime contracts and compatibility guidance.
- Read SECURITY.md before changing auth, deployment, or secret handling.
Requirements:
- Python 3.11, 3.12, 3.13, or 3.14
uv- A reachable OpenCode runtime if you need end-to-end manual checks
Install dependencies:
uv sync --all-extrasStart OpenCode in one terminal:
opencode serve --hostname 127.0.0.1 --port 4096Then start the A2A runtime in another terminal:
A2A_STATIC_AUTH_CREDENTIALS='[{"scheme":"bearer","token":"dev-token","principal":"automation"}]' \
OPENCODE_BASE_URL=http://127.0.0.1:4096 \
OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
uv run opencode-a2a serveRun the default validation baseline before opening a PR:
bash ./scripts/doctor.shdoctor.sh is the primary repository validation entrypoint. It currently runs locked-environment sync, dependency compatibility checks, pre-commit, mypy, pytest, the repository coverage gate, package build, and a built-wheel smoke test.
If you change shell scripts, also run bash -n on each modified script, for example:
bash -n scripts/doctor.sh
bash -n scripts/lint.shRepository-owned black-box compatibility probes stay outside the default regression baseline. Run them when transport or A2A protocol behavior changes:
bash ./scripts/conformance.shThe script does not download or bind to an external TCK. It checks the public Agent Card and both shipped transports against invariants maintained by this repository. A third-party TCK may be used independently as investigation input, but is not a repository dependency or certification claim.
If you change extension methods, extension metadata, or Agent Card/OpenAPI contract surfaces, also make sure the targeted contract checks stay green:
uv run pytest tests/contracts/test_extension_contract_consistency.py
uv run mypy src/opencode_a2aIf you change outbound authentication, tracing, protocol-version, or extension headers, run the SDK transport regression directly:
uv run pytest --no-cov tests/client/test_client_http_headers.pyAssertions against a mocked SDK client or ClientCallContext alone do not prove that headers reached the HTTP request. Keep at least one regression test across Agent Card resolution, the real SDK transport, and the final httpx.Request boundary.
- Keep code, comments, and docs in English.
- Keep issue / PR discussion in Simplified Chinese when collaborating in this repository.
- Do not drift Agent Card, OpenAPI examples, wire contract metadata, and runtime behavior.
- Prefer additive, explicit compatibility changes over silent behavior changes.
- Treat
opencode.*surfaces as provider-private unless the repository already defines them as shared A2A contracts.
- Branch from the latest
main. - Use
git fetchandgit merge --ff-onlyto sync mainline. - Do not push directly to protected branches.
- Link the relevant issue in commits and PR descriptions when applicable.
- Open PRs as Draft by default when the change still needs review or iteration.
Publish is the release workflow for tagged versions. It now supports both the normal tag-push path and explicit maintainer recovery runs.
- Tag pushes still perform the full release flow: regression checks, artifact builds, PyPI publish, and GitHub Release sync.
- Manual
workflow_dispatchruns require arelease_taginput so the workflow checks out and rebuilds the exact tagged revision instead of the current branch tip. - Manual
workflow_dispatchruns defaultpublish_to_pypi=falseso the safest recovery path is to repair the GitHub Release without attempting a duplicate PyPI publish. - Set
publish_to_pypi=trueonly when a maintainer intentionally needs the manual dispatch to publish artifacts to PyPI before syncing the GitHub Release. - GitHub Release sync is idempotent for the tagged release: it creates the release when missing and uploads only missing wheel/sdist assets.
If a release run publishes to PyPI successfully but fails while creating or uploading the GitHub Release, recover with a manual dispatch against the same tag and set publish_to_pypi=false.
Update docs together with code whenever you change:
- authentication or deployment behavior
- extension contracts or compatibility expectations
- user-facing request or response shapes
- operational scripts
Keep usage details in docs/guide.md and compatibility-sensitive stability guidance in docs/compatibility.md.
When changing extension contracts, update src/opencode_a2a/contracts/extensions.py first and keep these generated/documented surfaces aligned:
- Agent Card extension params
- OpenAPI
POST /extension metadata and examples - JSON-RPC notification behavior (
204 No Content)