opencode-a2a 0.6.0__tar.gz → 0.6.1__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.
- opencode_a2a-0.6.1/.github/workflows/publish.yml +160 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/CODE_OF_CONDUCT.md +2 -6
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/CONTRIBUTING.md +17 -12
- {opencode_a2a-0.6.0/src/opencode_a2a.egg-info → opencode_a2a-0.6.1}/PKG-INFO +20 -50
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/README.md +19 -49
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/SECURITY.md +16 -35
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/SUPPORT.md +2 -4
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/docs/extension-specifications.md +17 -38
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/docs/guide.md +161 -386
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/scripts/README.md +1 -2
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/config.py +5 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/server/application.py +1 -2
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/server/state_store.py +33 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1/src/opencode_a2a.egg-info}/PKG-INFO +20 -50
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/config/test_settings.py +15 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/server/test_state_store.py +71 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/server/test_transport_contract.py +80 -4
- opencode_a2a-0.6.0/.github/workflows/publish.yml +0 -90
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/.github/workflows/ci.yml +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/.github/workflows/dependency-health.yml +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/.gitignore +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/.pre-commit-config.yaml +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/.secrets.baseline +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/AGENTS.md +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/LICENSE +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/pyproject.toml +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/scripts/check_coverage.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/scripts/dependency_health.sh +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/scripts/doctor.sh +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/scripts/health_common.sh +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/scripts/lint.sh +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/scripts/smoke_test_built_cli.sh +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/setup.cfg +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/cli.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/client/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/client/agent_card.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/client/auth.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/client/client.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/client/config.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/client/error_mapping.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/client/errors.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/client/payload_text.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/client/polling.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/client/request_context.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/contracts/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/contracts/extensions.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/execution/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/execution/event_helpers.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/execution/executor.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/execution/request_context.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/execution/session_manager.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/execution/stream_events.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/execution/stream_runtime.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/execution/stream_state.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/execution/tool_error_mapping.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/execution/upstream_error_translator.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/invocation.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/jsonrpc/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/jsonrpc/application.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/jsonrpc/dispatch.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/jsonrpc/error_responses.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/jsonrpc/handlers/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/jsonrpc/handlers/common.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/jsonrpc/handlers/interrupt_callbacks.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/jsonrpc/handlers/interrupt_queries.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/jsonrpc/handlers/provider_discovery.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/jsonrpc/handlers/session_control.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/jsonrpc/handlers/session_lifecycle.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/jsonrpc/handlers/session_queries.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/jsonrpc/handlers/workspace_control.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/jsonrpc/methods.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/jsonrpc/params.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/opencode_upstream_client.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/parts/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/parts/mapping.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/parts/text.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/profile/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/profile/runtime.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/runtime_state.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/sandbox_policy.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/server/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/server/agent_card.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/server/openapi.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/server/request_parsing.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/server/task_store.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a/upstream_taxonomy.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a.egg-info/SOURCES.txt +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a.egg-info/dependency_links.txt +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a.egg-info/entry_points.txt +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a.egg-info/requires.txt +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/src/opencode_a2a.egg-info/top_level.txt +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/client/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/client/test_agent_card.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/client/test_client_config.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/client/test_client_facade.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/client/test_error_mapping.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/client/test_payload_text.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/client/test_polling.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/client/test_request_context.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/config/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/conftest.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/contracts/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/contracts/test_extension_contract_consistency.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/execution/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/execution/test_agent_errors.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/execution/test_agent_helpers.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/execution/test_cancellation.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/execution/test_directory_validation.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/execution/test_metrics.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/execution/test_multipart_input.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/execution/test_opencode_agent_session_binding.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/execution/test_session_lock_lifecycle.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/execution/test_session_ownership.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/execution/test_streaming_output_contract_blocks.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/execution/test_streaming_output_contract_core.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/execution/test_streaming_output_contract_interrupts.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/execution/test_streaming_output_contract_logging.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/jsonrpc/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/jsonrpc/test_dispatch_registry.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/jsonrpc/test_error_responses.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/jsonrpc/test_jsonrpc_methods.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/jsonrpc/test_jsonrpc_params.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/jsonrpc/test_jsonrpc_unsupported_method.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/jsonrpc/test_opencode_session_extension_commands.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/jsonrpc/test_opencode_session_extension_interrupts.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/jsonrpc/test_opencode_session_extension_lifecycle.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/jsonrpc/test_opencode_session_extension_prompt_async.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/jsonrpc/test_opencode_session_extension_queries.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/jsonrpc/test_opencode_workspace_control_extension.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/package/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/package/test_version.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/parts/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/parts/test_parts_text.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/profile/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/profile/test_profile_runtime.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/scripts/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/scripts/test_script_health_contract.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/server/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/server/test_a2a_client_manager.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/server/test_agent_card.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/server/test_app_behaviors.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/server/test_call_context_builder.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/server/test_cancel_contract.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/server/test_cli.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/server/test_database_app_persistence.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/server/test_task_store_factory.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/support/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/support/helpers.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/support/session_extensions.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/support/streaming_output.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/upstream/__init__.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/tests/upstream/test_opencode_upstream_client_params.py +0 -0
- {opencode_a2a-0.6.0 → opencode_a2a-0.6.1}/uv.lock +0 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
release_tag:
|
|
10
|
+
description: Existing v* tag to publish or repair
|
|
11
|
+
required: true
|
|
12
|
+
type: string
|
|
13
|
+
publish_to_pypi:
|
|
14
|
+
description: Publish artifacts to PyPI before syncing the GitHub Release
|
|
15
|
+
required: true
|
|
16
|
+
default: false
|
|
17
|
+
type: boolean
|
|
18
|
+
sync_github_release:
|
|
19
|
+
description: Create or repair the GitHub Release and release assets
|
|
20
|
+
required: true
|
|
21
|
+
default: true
|
|
22
|
+
type: boolean
|
|
23
|
+
|
|
24
|
+
concurrency:
|
|
25
|
+
group: publish-${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref_name }}
|
|
26
|
+
cancel-in-progress: false
|
|
27
|
+
|
|
28
|
+
permissions:
|
|
29
|
+
contents: write
|
|
30
|
+
id-token: write
|
|
31
|
+
|
|
32
|
+
jobs:
|
|
33
|
+
publish:
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
|
|
36
|
+
steps:
|
|
37
|
+
- name: Checkout
|
|
38
|
+
uses: actions/checkout@v6
|
|
39
|
+
with:
|
|
40
|
+
fetch-depth: 0
|
|
41
|
+
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref }}
|
|
42
|
+
|
|
43
|
+
- name: Setup Python
|
|
44
|
+
uses: actions/setup-python@v6
|
|
45
|
+
with:
|
|
46
|
+
python-version: "3.13"
|
|
47
|
+
|
|
48
|
+
- name: Setup uv
|
|
49
|
+
uses: astral-sh/setup-uv@v7
|
|
50
|
+
with:
|
|
51
|
+
enable-cache: false
|
|
52
|
+
|
|
53
|
+
- name: Run regression baseline
|
|
54
|
+
run: bash ./scripts/doctor.sh
|
|
55
|
+
|
|
56
|
+
- name: Export runtime requirements for vulnerability audit
|
|
57
|
+
run: >
|
|
58
|
+
uv export --format requirements.txt --no-dev --locked --no-emit-project
|
|
59
|
+
--output-file /tmp/runtime-requirements.txt >/dev/null
|
|
60
|
+
|
|
61
|
+
- name: Run runtime dependency vulnerability audit
|
|
62
|
+
run: uv run pip-audit --requirement /tmp/runtime-requirements.txt
|
|
63
|
+
|
|
64
|
+
- name: Clean previous build artifacts
|
|
65
|
+
run: rm -rf build dist
|
|
66
|
+
|
|
67
|
+
- name: Build package artifacts
|
|
68
|
+
run: uv build --no-sources
|
|
69
|
+
|
|
70
|
+
- name: Verify published version matches tag
|
|
71
|
+
env:
|
|
72
|
+
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref_name }}
|
|
73
|
+
run: |
|
|
74
|
+
python - <<'PY'
|
|
75
|
+
import os
|
|
76
|
+
import pathlib
|
|
77
|
+
|
|
78
|
+
dist_dir = pathlib.Path("dist")
|
|
79
|
+
wheels = sorted(dist_dir.glob("opencode_a2a-*.whl"))
|
|
80
|
+
sdists = sorted(dist_dir.glob("opencode_a2a-*.tar.gz"))
|
|
81
|
+
if len(wheels) != 1:
|
|
82
|
+
raise SystemExit(f"Expected exactly one wheel in dist/, found {len(wheels)}")
|
|
83
|
+
if len(sdists) != 1:
|
|
84
|
+
raise SystemExit(f"Expected exactly one sdist in dist/, found {len(sdists)}")
|
|
85
|
+
wheel = wheels[0].name
|
|
86
|
+
sdist = sdists[0].name
|
|
87
|
+
version = wheel.removeprefix("opencode_a2a-").split("-py3", 1)[0]
|
|
88
|
+
sdist_version = sdist.removeprefix("opencode_a2a-").removesuffix(".tar.gz")
|
|
89
|
+
tag = os.environ["RELEASE_TAG"].removeprefix("v")
|
|
90
|
+
if version != tag:
|
|
91
|
+
raise SystemExit(f"Wheel version {version!r} does not match tag {tag!r}")
|
|
92
|
+
if sdist_version != tag:
|
|
93
|
+
raise SystemExit(f"sdist version {sdist_version!r} does not match tag {tag!r}")
|
|
94
|
+
print(f"Validated release version: {version}")
|
|
95
|
+
PY
|
|
96
|
+
|
|
97
|
+
- name: Smoke test wheel install
|
|
98
|
+
run: bash ./scripts/smoke_test_built_cli.sh dist/opencode_a2a-*.whl
|
|
99
|
+
|
|
100
|
+
- name: Smoke test sdist install
|
|
101
|
+
run: bash ./scripts/smoke_test_built_cli.sh dist/opencode_a2a-*.tar.gz
|
|
102
|
+
|
|
103
|
+
- name: Publish to PyPI
|
|
104
|
+
if: ${{ github.event_name != 'workflow_dispatch' || inputs.publish_to_pypi }}
|
|
105
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
106
|
+
|
|
107
|
+
- name: Sync GitHub Release
|
|
108
|
+
if: ${{ github.event_name != 'workflow_dispatch' || inputs.sync_github_release }}
|
|
109
|
+
env:
|
|
110
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
111
|
+
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.release_tag || github.ref_name }}
|
|
112
|
+
run: |
|
|
113
|
+
set -euo pipefail
|
|
114
|
+
|
|
115
|
+
retry() {
|
|
116
|
+
local attempts="$1"
|
|
117
|
+
local sleep_seconds="$2"
|
|
118
|
+
shift 2
|
|
119
|
+
|
|
120
|
+
local attempt=1
|
|
121
|
+
while true; do
|
|
122
|
+
if "$@"; then
|
|
123
|
+
return 0
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
if [ "$attempt" -ge "$attempts" ]; then
|
|
127
|
+
echo "Command failed after ${attempts} attempts: $*" >&2
|
|
128
|
+
return 1
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
echo "Retrying (${attempt}/${attempts}) after transient failure: $*" >&2
|
|
132
|
+
sleep "$sleep_seconds"
|
|
133
|
+
attempt=$((attempt + 1))
|
|
134
|
+
done
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
ensure_release() {
|
|
138
|
+
if retry 3 5 gh release view "$RELEASE_TAG" --json url >/dev/null; then
|
|
139
|
+
echo "Release ${RELEASE_TAG} already exists."
|
|
140
|
+
return 0
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
retry 3 5 gh release create "$RELEASE_TAG" --verify-tag --generate-notes
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
ensure_release
|
|
147
|
+
|
|
148
|
+
mapfile -t existing_assets < <(
|
|
149
|
+
retry 3 5 gh release view "$RELEASE_TAG" --json assets --jq '.assets[].name'
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
for asset in dist/*.tar.gz dist/*.whl; do
|
|
153
|
+
asset_name="$(basename "$asset")"
|
|
154
|
+
if printf '%s\n' "${existing_assets[@]}" | grep -Fxq "$asset_name"; then
|
|
155
|
+
echo "Release asset already present: $asset_name"
|
|
156
|
+
continue
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
retry 3 5 gh release upload "$RELEASE_TAG" "$asset"
|
|
160
|
+
done
|
|
@@ -18,12 +18,8 @@ This project expects respectful, technically focused collaboration.
|
|
|
18
18
|
|
|
19
19
|
## Reporting
|
|
20
20
|
|
|
21
|
-
For normal collaboration problems, open an issue or discussion with enough
|
|
22
|
-
context to review the situation. For security-sensitive or private concerns,
|
|
23
|
-
follow the disclosure path in [SECURITY.md](SECURITY.md).
|
|
21
|
+
For normal collaboration problems, open an issue or discussion with enough context to review the situation. For security-sensitive or private concerns, follow the disclosure path in [SECURITY.md](SECURITY.md).
|
|
24
22
|
|
|
25
23
|
## Enforcement
|
|
26
24
|
|
|
27
|
-
Repository maintainers may edit, hide, lock, or remove content that violates
|
|
28
|
-
this policy, and may restrict participation when needed to keep collaboration
|
|
29
|
-
safe and productive.
|
|
25
|
+
Repository maintainers may edit, hide, lock, or remove content that violates this policy, and may restrict participation when needed to keep collaboration safe and productive.
|
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Thanks for contributing to `opencode-a2a`.
|
|
4
4
|
|
|
5
|
-
This repository maintains an OpenCode A2A runtime. Changes
|
|
6
|
-
should keep runtime behavior, Agent Card declarations, OpenAPI examples, and
|
|
7
|
-
machine-readable extension contracts aligned.
|
|
5
|
+
This repository maintains an OpenCode A2A runtime. Changes should keep runtime behavior, Agent Card declarations, OpenAPI examples, and machine-readable extension contracts aligned.
|
|
8
6
|
|
|
9
7
|
## Before You Start
|
|
10
8
|
|
|
@@ -50,16 +48,14 @@ uv run pre-commit run --all-files
|
|
|
50
48
|
uv run pytest
|
|
51
49
|
```
|
|
52
50
|
|
|
53
|
-
If you change shell scripts, also run `bash -n` on each modified script, for
|
|
54
|
-
example:
|
|
51
|
+
If you change shell scripts, also run `bash -n` on each modified script, for example:
|
|
55
52
|
|
|
56
53
|
```bash
|
|
57
54
|
bash -n scripts/doctor.sh
|
|
58
55
|
bash -n scripts/lint.sh
|
|
59
56
|
```
|
|
60
57
|
|
|
61
|
-
If you change extension methods, extension metadata, or Agent Card/OpenAPI
|
|
62
|
-
contract surfaces, also run:
|
|
58
|
+
If you change extension methods, extension metadata, or Agent Card/OpenAPI contract surfaces, also run:
|
|
63
59
|
|
|
64
60
|
```bash
|
|
65
61
|
uv run pytest tests/contracts/test_extension_contract_consistency.py
|
|
@@ -82,6 +78,18 @@ uv run mypy src/opencode_a2a
|
|
|
82
78
|
- Link the relevant issue in commits and PR descriptions when applicable.
|
|
83
79
|
- Open PRs as Draft by default when the change still needs review or iteration.
|
|
84
80
|
|
|
81
|
+
## Release Recovery
|
|
82
|
+
|
|
83
|
+
`Publish` is the release workflow for tagged versions. It now supports both the normal tag-push path and explicit maintainer recovery runs.
|
|
84
|
+
|
|
85
|
+
- Tag pushes still perform the full release flow: regression checks, artifact builds, PyPI publish, and GitHub Release sync.
|
|
86
|
+
- Manual `workflow_dispatch` runs require a `release_tag` input so the workflow checks out and rebuilds the exact tagged revision instead of the current branch tip.
|
|
87
|
+
- Manual `workflow_dispatch` runs default `publish_to_pypi=false` so the safest recovery path is to repair the GitHub Release without attempting a duplicate PyPI publish.
|
|
88
|
+
- Set `publish_to_pypi=true` only when a maintainer intentionally needs the manual dispatch to publish artifacts to PyPI before syncing the GitHub Release.
|
|
89
|
+
- GitHub Release sync is idempotent for the tagged release: it creates the release when missing and uploads only missing wheel/sdist assets.
|
|
90
|
+
|
|
91
|
+
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`.
|
|
92
|
+
|
|
85
93
|
## Documentation
|
|
86
94
|
|
|
87
95
|
Update docs together with code whenever you change:
|
|
@@ -91,12 +99,9 @@ Update docs together with code whenever you change:
|
|
|
91
99
|
- user-facing request or response shapes
|
|
92
100
|
- operational scripts
|
|
93
101
|
|
|
94
|
-
Keep compatibility guidance centralized in [docs/guide.md](docs/guide.md) unless a
|
|
95
|
-
new standalone document is clearly necessary.
|
|
102
|
+
Keep compatibility guidance centralized in [docs/guide.md](docs/guide.md) unless a new standalone document is clearly necessary.
|
|
96
103
|
|
|
97
|
-
When changing extension contracts, update
|
|
98
|
-
[`src/opencode_a2a/contracts/extensions.py`](src/opencode_a2a/contracts/extensions.py)
|
|
99
|
-
first and keep these generated/documented surfaces aligned:
|
|
104
|
+
When changing extension contracts, update [`src/opencode_a2a/contracts/extensions.py`](src/opencode_a2a/contracts/extensions.py) first and keep these generated/documented surfaces aligned:
|
|
100
105
|
|
|
101
106
|
- Agent Card extension params
|
|
102
107
|
- OpenAPI `POST /` extension metadata and examples
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencode-a2a
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.1
|
|
4
4
|
Summary: OpenCode A2A runtime
|
|
5
5
|
Author: liujuanjuan1984@Intelligent-Internet
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -43,16 +43,12 @@ Dynamic: license-file
|
|
|
43
43
|
|
|
44
44
|
> Expose OpenCode through A2A.
|
|
45
45
|
|
|
46
|
-
`opencode-a2a` adds an A2A runtime layer to `opencode serve`, with
|
|
47
|
-
auth, streaming, session continuity, interrupt handling, and a clear
|
|
48
|
-
deployment boundary.
|
|
46
|
+
`opencode-a2a` adds an A2A runtime layer to `opencode serve`, with auth, streaming, session continuity, interrupt handling, and a clear deployment boundary.
|
|
49
47
|
|
|
50
48
|
## What This Is
|
|
51
49
|
|
|
52
|
-
- An A2A adapter service built on `opencode serve`, with inbound runtime
|
|
53
|
-
|
|
54
|
-
- It supports both roles in one process: serving as an A2A Server and hosting an
|
|
55
|
-
embedded A2A Client for `a2a_call`.
|
|
50
|
+
- An A2A adapter service built on `opencode serve`, with inbound runtime exposure plus outbound peer calling.
|
|
51
|
+
- It supports both roles in one process: serving as an A2A Server and hosting an embedded A2A Client for `a2a_call`.
|
|
56
52
|
|
|
57
53
|
## Architecture
|
|
58
54
|
|
|
@@ -95,8 +91,7 @@ Upgrade later with:
|
|
|
95
91
|
uv tool upgrade opencode-a2a
|
|
96
92
|
```
|
|
97
93
|
|
|
98
|
-
Make sure provider credentials and a default model are configured on the
|
|
99
|
-
OpenCode side, then start OpenCode:
|
|
94
|
+
Make sure provider credentials and a default model are configured on the OpenCode side, then start OpenCode:
|
|
100
95
|
|
|
101
96
|
```bash
|
|
102
97
|
opencode auth login
|
|
@@ -104,10 +99,7 @@ opencode models
|
|
|
104
99
|
opencode serve --hostname 127.0.0.1 --port 4096
|
|
105
100
|
```
|
|
106
101
|
|
|
107
|
-
Treat the deployed OpenCode user's HOME/XDG config directories as part of the
|
|
108
|
-
runtime state. If a packaged or service-managed deployment appears to ignore
|
|
109
|
-
fresh provider env vars, inspect that user's persisted OpenCode auth/config
|
|
110
|
-
files before assuming the A2A adapter layer is overriding credentials.
|
|
102
|
+
Treat the deployed OpenCode user's HOME/XDG config directories as part of the runtime state. If a packaged or service-managed deployment appears to ignore fresh provider env vars, inspect that user's persisted OpenCode auth/config files before assuming the A2A adapter layer is overriding credentials.
|
|
111
103
|
|
|
112
104
|
Then start `opencode-a2a` against that upstream:
|
|
113
105
|
|
|
@@ -130,11 +122,9 @@ curl http://127.0.0.1:8000/.well-known/agent-card.json
|
|
|
130
122
|
|
|
131
123
|
## Capabilities
|
|
132
124
|
|
|
133
|
-
- A2A HTTP+JSON endpoints such as `/v1/message:send` and
|
|
134
|
-
`/v1/message:stream`
|
|
125
|
+
- A2A HTTP+JSON endpoints such as `/v1/message:send` and `/v1/message:stream`
|
|
135
126
|
- A2A JSON-RPC support on `POST /`
|
|
136
|
-
- SDK-owned A2A task surfaces such as `GET /v1/tasks`, task push notification
|
|
137
|
-
config routes, and JSON-RPC `agent/getAuthenticatedExtendedCard`
|
|
127
|
+
- SDK-owned A2A task surfaces such as `GET /v1/tasks`, task push notification config routes, and JSON-RPC `agent/getAuthenticatedExtendedCard`
|
|
138
128
|
- Peering capabilities: can act as a client via `opencode-a2a call`
|
|
139
129
|
- Autonomous tool execution: supports `a2a_call` tool for outbound agent-to-agent communication
|
|
140
130
|
- SSE streaming with normalized `text`, `reasoning`, and `tool_call` blocks
|
|
@@ -163,21 +153,11 @@ opencode-a2a call http://other-agent:8000 "How are you?"
|
|
|
163
153
|
### Outbound Agent Calls (Tools)
|
|
164
154
|
The server can autonomously execute `a2a_call(url, message)` tool calls emitted by the OpenCode runtime. Results are fetched via A2A and returned to the model as tool results, enabling multi-agent orchestration.
|
|
165
155
|
|
|
166
|
-
When the target peer agent requires bearer auth, configure
|
|
167
|
-
`A2A_CLIENT_BEARER_TOKEN` for server-side outbound calls. When the target peer
|
|
168
|
-
agent requires Basic auth, use `A2A_CLIENT_BASIC_AUTH`.
|
|
169
|
-
These outbound credentials apply to the peer specified by `opencode-a2a call`
|
|
170
|
-
or `a2a_call(url, message)`, not to this service's inbound `A2A_BEARER_TOKEN`.
|
|
171
|
-
The CLI intentionally reads outbound credentials from environment variables only,
|
|
172
|
-
so secrets do not appear in shell history or process arguments.
|
|
156
|
+
When the target peer agent requires bearer auth, configure `A2A_CLIENT_BEARER_TOKEN` for server-side outbound calls. When the target peer agent requires Basic auth, use `A2A_CLIENT_BASIC_AUTH`. These outbound credentials apply to the peer specified by `opencode-a2a call` or `a2a_call(url, message)`, not to this service's inbound `A2A_BEARER_TOKEN`. The CLI intentionally reads outbound credentials from environment variables only, so secrets do not appear in shell history or process arguments.
|
|
173
157
|
|
|
174
|
-
Server-side outbound client settings are fully wired through runtime config:
|
|
175
|
-
`A2A_CLIENT_TIMEOUT_SECONDS`, `A2A_CLIENT_CARD_FETCH_TIMEOUT_SECONDS`,
|
|
176
|
-
`A2A_CLIENT_USE_CLIENT_PREFERENCE`, `A2A_CLIENT_BEARER_TOKEN`, `A2A_CLIENT_BASIC_AUTH`, and
|
|
177
|
-
`A2A_CLIENT_SUPPORTED_TRANSPORTS`.
|
|
158
|
+
Server-side outbound client settings are fully wired through runtime config: `A2A_CLIENT_TIMEOUT_SECONDS`, `A2A_CLIENT_CARD_FETCH_TIMEOUT_SECONDS`, `A2A_CLIENT_USE_CLIENT_PREFERENCE`, `A2A_CLIENT_BEARER_TOKEN`, `A2A_CLIENT_BASIC_AUTH`, and `A2A_CLIENT_SUPPORTED_TRANSPORTS`.
|
|
178
159
|
|
|
179
|
-
Detailed protocol contracts, examples, and extension docs live in
|
|
180
|
-
[`docs/guide.md`](docs/guide.md).
|
|
160
|
+
Detailed protocol contracts, examples, and extension docs live in [`docs/guide.md`](docs/guide.md).
|
|
181
161
|
|
|
182
162
|
## When To Use It
|
|
183
163
|
|
|
@@ -193,24 +173,17 @@ Look elsewhere if:
|
|
|
193
173
|
- you want this project to manage your process supervisor or host bootstrap
|
|
194
174
|
- you want a general client integration layer rather than a server wrapper
|
|
195
175
|
|
|
196
|
-
For client-side integration, prefer
|
|
197
|
-
[a2a-client-hub](https://github.com/liujuanjuan1984/a2a-client-hub).
|
|
176
|
+
For client-side integration, prefer [a2a-client-hub](https://github.com/liujuanjuan1984/a2a-client-hub).
|
|
198
177
|
|
|
199
178
|
## Deployment Boundary
|
|
200
179
|
|
|
201
|
-
This repository improves the service boundary around OpenCode, but it does not
|
|
202
|
-
turn OpenCode into a hardened multi-tenant platform.
|
|
180
|
+
This repository improves the service boundary around OpenCode, but it does not turn OpenCode into a hardened multi-tenant platform.
|
|
203
181
|
|
|
204
182
|
- `A2A_BEARER_TOKEN` protects the A2A surface.
|
|
205
|
-
- Provider auth and default model configuration remain on the OpenCode side; deployment-time
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
-
|
|
209
|
-
`a2a_call`.
|
|
210
|
-
- Deployment supervision is intentionally BYO. Use `systemd`, Docker,
|
|
211
|
-
Kubernetes, or another supervisor if you need long-running operation.
|
|
212
|
-
- For mutually untrusted tenants, run separate instance pairs with isolated
|
|
213
|
-
users, containers, workspaces, credentials, and ports.
|
|
183
|
+
- Provider auth and default model configuration remain on the OpenCode side; deployment-time precedence details and HOME/XDG state impact are documented in [docs/guide.md](docs/guide.md#troubleshooting-provider-auth-state).
|
|
184
|
+
- Use `A2A_CLIENT_BEARER_TOKEN` for server-side outbound peer calls initiated by `a2a_call`.
|
|
185
|
+
- Deployment supervision is intentionally BYO. Use `systemd`, Docker, Kubernetes, or another supervisor if you need long-running operation.
|
|
186
|
+
- For mutually untrusted tenants, run separate instance pairs with isolated users, containers, workspaces, credentials, and ports.
|
|
214
187
|
|
|
215
188
|
Read before deployment:
|
|
216
189
|
|
|
@@ -221,15 +194,12 @@ Read before deployment:
|
|
|
221
194
|
|
|
222
195
|
## Further Reading
|
|
223
196
|
|
|
224
|
-
- [docs/guide.md](docs/guide.md)
|
|
225
|
-
|
|
226
|
-
- [SECURITY.md](SECURITY.md)
|
|
227
|
-
Threat model, deployment caveats, and vulnerability disclosure guidance.
|
|
197
|
+
- [docs/guide.md](docs/guide.md) Usage guide, transport details, streaming behavior, extensions, and examples.
|
|
198
|
+
- [SECURITY.md](SECURITY.md) Threat model, deployment caveats, and vulnerability disclosure guidance.
|
|
228
199
|
|
|
229
200
|
## Development
|
|
230
201
|
|
|
231
|
-
For contributor workflow, local validation, and helper scripts, see
|
|
232
|
-
[CONTRIBUTING.md](CONTRIBUTING.md) and [scripts/README.md](scripts/README.md).
|
|
202
|
+
For contributor workflow, local validation, and helper scripts, see [CONTRIBUTING.md](CONTRIBUTING.md) and [scripts/README.md](scripts/README.md).
|
|
233
203
|
|
|
234
204
|
## License
|
|
235
205
|
|
|
@@ -2,16 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
> Expose OpenCode through A2A.
|
|
4
4
|
|
|
5
|
-
`opencode-a2a` adds an A2A runtime layer to `opencode serve`, with
|
|
6
|
-
auth, streaming, session continuity, interrupt handling, and a clear
|
|
7
|
-
deployment boundary.
|
|
5
|
+
`opencode-a2a` adds an A2A runtime layer to `opencode serve`, with auth, streaming, session continuity, interrupt handling, and a clear deployment boundary.
|
|
8
6
|
|
|
9
7
|
## What This Is
|
|
10
8
|
|
|
11
|
-
- An A2A adapter service built on `opencode serve`, with inbound runtime
|
|
12
|
-
|
|
13
|
-
- It supports both roles in one process: serving as an A2A Server and hosting an
|
|
14
|
-
embedded A2A Client for `a2a_call`.
|
|
9
|
+
- An A2A adapter service built on `opencode serve`, with inbound runtime exposure plus outbound peer calling.
|
|
10
|
+
- It supports both roles in one process: serving as an A2A Server and hosting an embedded A2A Client for `a2a_call`.
|
|
15
11
|
|
|
16
12
|
## Architecture
|
|
17
13
|
|
|
@@ -54,8 +50,7 @@ Upgrade later with:
|
|
|
54
50
|
uv tool upgrade opencode-a2a
|
|
55
51
|
```
|
|
56
52
|
|
|
57
|
-
Make sure provider credentials and a default model are configured on the
|
|
58
|
-
OpenCode side, then start OpenCode:
|
|
53
|
+
Make sure provider credentials and a default model are configured on the OpenCode side, then start OpenCode:
|
|
59
54
|
|
|
60
55
|
```bash
|
|
61
56
|
opencode auth login
|
|
@@ -63,10 +58,7 @@ opencode models
|
|
|
63
58
|
opencode serve --hostname 127.0.0.1 --port 4096
|
|
64
59
|
```
|
|
65
60
|
|
|
66
|
-
Treat the deployed OpenCode user's HOME/XDG config directories as part of the
|
|
67
|
-
runtime state. If a packaged or service-managed deployment appears to ignore
|
|
68
|
-
fresh provider env vars, inspect that user's persisted OpenCode auth/config
|
|
69
|
-
files before assuming the A2A adapter layer is overriding credentials.
|
|
61
|
+
Treat the deployed OpenCode user's HOME/XDG config directories as part of the runtime state. If a packaged or service-managed deployment appears to ignore fresh provider env vars, inspect that user's persisted OpenCode auth/config files before assuming the A2A adapter layer is overriding credentials.
|
|
70
62
|
|
|
71
63
|
Then start `opencode-a2a` against that upstream:
|
|
72
64
|
|
|
@@ -89,11 +81,9 @@ curl http://127.0.0.1:8000/.well-known/agent-card.json
|
|
|
89
81
|
|
|
90
82
|
## Capabilities
|
|
91
83
|
|
|
92
|
-
- A2A HTTP+JSON endpoints such as `/v1/message:send` and
|
|
93
|
-
`/v1/message:stream`
|
|
84
|
+
- A2A HTTP+JSON endpoints such as `/v1/message:send` and `/v1/message:stream`
|
|
94
85
|
- A2A JSON-RPC support on `POST /`
|
|
95
|
-
- SDK-owned A2A task surfaces such as `GET /v1/tasks`, task push notification
|
|
96
|
-
config routes, and JSON-RPC `agent/getAuthenticatedExtendedCard`
|
|
86
|
+
- SDK-owned A2A task surfaces such as `GET /v1/tasks`, task push notification config routes, and JSON-RPC `agent/getAuthenticatedExtendedCard`
|
|
97
87
|
- Peering capabilities: can act as a client via `opencode-a2a call`
|
|
98
88
|
- Autonomous tool execution: supports `a2a_call` tool for outbound agent-to-agent communication
|
|
99
89
|
- SSE streaming with normalized `text`, `reasoning`, and `tool_call` blocks
|
|
@@ -122,21 +112,11 @@ opencode-a2a call http://other-agent:8000 "How are you?"
|
|
|
122
112
|
### Outbound Agent Calls (Tools)
|
|
123
113
|
The server can autonomously execute `a2a_call(url, message)` tool calls emitted by the OpenCode runtime. Results are fetched via A2A and returned to the model as tool results, enabling multi-agent orchestration.
|
|
124
114
|
|
|
125
|
-
When the target peer agent requires bearer auth, configure
|
|
126
|
-
`A2A_CLIENT_BEARER_TOKEN` for server-side outbound calls. When the target peer
|
|
127
|
-
agent requires Basic auth, use `A2A_CLIENT_BASIC_AUTH`.
|
|
128
|
-
These outbound credentials apply to the peer specified by `opencode-a2a call`
|
|
129
|
-
or `a2a_call(url, message)`, not to this service's inbound `A2A_BEARER_TOKEN`.
|
|
130
|
-
The CLI intentionally reads outbound credentials from environment variables only,
|
|
131
|
-
so secrets do not appear in shell history or process arguments.
|
|
115
|
+
When the target peer agent requires bearer auth, configure `A2A_CLIENT_BEARER_TOKEN` for server-side outbound calls. When the target peer agent requires Basic auth, use `A2A_CLIENT_BASIC_AUTH`. These outbound credentials apply to the peer specified by `opencode-a2a call` or `a2a_call(url, message)`, not to this service's inbound `A2A_BEARER_TOKEN`. The CLI intentionally reads outbound credentials from environment variables only, so secrets do not appear in shell history or process arguments.
|
|
132
116
|
|
|
133
|
-
Server-side outbound client settings are fully wired through runtime config:
|
|
134
|
-
`A2A_CLIENT_TIMEOUT_SECONDS`, `A2A_CLIENT_CARD_FETCH_TIMEOUT_SECONDS`,
|
|
135
|
-
`A2A_CLIENT_USE_CLIENT_PREFERENCE`, `A2A_CLIENT_BEARER_TOKEN`, `A2A_CLIENT_BASIC_AUTH`, and
|
|
136
|
-
`A2A_CLIENT_SUPPORTED_TRANSPORTS`.
|
|
117
|
+
Server-side outbound client settings are fully wired through runtime config: `A2A_CLIENT_TIMEOUT_SECONDS`, `A2A_CLIENT_CARD_FETCH_TIMEOUT_SECONDS`, `A2A_CLIENT_USE_CLIENT_PREFERENCE`, `A2A_CLIENT_BEARER_TOKEN`, `A2A_CLIENT_BASIC_AUTH`, and `A2A_CLIENT_SUPPORTED_TRANSPORTS`.
|
|
137
118
|
|
|
138
|
-
Detailed protocol contracts, examples, and extension docs live in
|
|
139
|
-
[`docs/guide.md`](docs/guide.md).
|
|
119
|
+
Detailed protocol contracts, examples, and extension docs live in [`docs/guide.md`](docs/guide.md).
|
|
140
120
|
|
|
141
121
|
## When To Use It
|
|
142
122
|
|
|
@@ -152,24 +132,17 @@ Look elsewhere if:
|
|
|
152
132
|
- you want this project to manage your process supervisor or host bootstrap
|
|
153
133
|
- you want a general client integration layer rather than a server wrapper
|
|
154
134
|
|
|
155
|
-
For client-side integration, prefer
|
|
156
|
-
[a2a-client-hub](https://github.com/liujuanjuan1984/a2a-client-hub).
|
|
135
|
+
For client-side integration, prefer [a2a-client-hub](https://github.com/liujuanjuan1984/a2a-client-hub).
|
|
157
136
|
|
|
158
137
|
## Deployment Boundary
|
|
159
138
|
|
|
160
|
-
This repository improves the service boundary around OpenCode, but it does not
|
|
161
|
-
turn OpenCode into a hardened multi-tenant platform.
|
|
139
|
+
This repository improves the service boundary around OpenCode, but it does not turn OpenCode into a hardened multi-tenant platform.
|
|
162
140
|
|
|
163
141
|
- `A2A_BEARER_TOKEN` protects the A2A surface.
|
|
164
|
-
- Provider auth and default model configuration remain on the OpenCode side; deployment-time
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
-
|
|
168
|
-
`a2a_call`.
|
|
169
|
-
- Deployment supervision is intentionally BYO. Use `systemd`, Docker,
|
|
170
|
-
Kubernetes, or another supervisor if you need long-running operation.
|
|
171
|
-
- For mutually untrusted tenants, run separate instance pairs with isolated
|
|
172
|
-
users, containers, workspaces, credentials, and ports.
|
|
142
|
+
- Provider auth and default model configuration remain on the OpenCode side; deployment-time precedence details and HOME/XDG state impact are documented in [docs/guide.md](docs/guide.md#troubleshooting-provider-auth-state).
|
|
143
|
+
- Use `A2A_CLIENT_BEARER_TOKEN` for server-side outbound peer calls initiated by `a2a_call`.
|
|
144
|
+
- Deployment supervision is intentionally BYO. Use `systemd`, Docker, Kubernetes, or another supervisor if you need long-running operation.
|
|
145
|
+
- For mutually untrusted tenants, run separate instance pairs with isolated users, containers, workspaces, credentials, and ports.
|
|
173
146
|
|
|
174
147
|
Read before deployment:
|
|
175
148
|
|
|
@@ -180,15 +153,12 @@ Read before deployment:
|
|
|
180
153
|
|
|
181
154
|
## Further Reading
|
|
182
155
|
|
|
183
|
-
- [docs/guide.md](docs/guide.md)
|
|
184
|
-
|
|
185
|
-
- [SECURITY.md](SECURITY.md)
|
|
186
|
-
Threat model, deployment caveats, and vulnerability disclosure guidance.
|
|
156
|
+
- [docs/guide.md](docs/guide.md) Usage guide, transport details, streaming behavior, extensions, and examples.
|
|
157
|
+
- [SECURITY.md](SECURITY.md) Threat model, deployment caveats, and vulnerability disclosure guidance.
|
|
187
158
|
|
|
188
159
|
## Development
|
|
189
160
|
|
|
190
|
-
For contributor workflow, local validation, and helper scripts, see
|
|
191
|
-
[CONTRIBUTING.md](CONTRIBUTING.md) and [scripts/README.md](scripts/README.md).
|
|
161
|
+
For contributor workflow, local validation, and helper scripts, see [CONTRIBUTING.md](CONTRIBUTING.md) and [scripts/README.md](scripts/README.md).
|
|
192
162
|
|
|
193
163
|
## License
|
|
194
164
|
|
|
@@ -2,56 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
## Scope
|
|
4
4
|
|
|
5
|
-
This repository wraps OpenCode as an A2A runtime. It exposes A2A
|
|
6
|
-
HTTP+JSON and JSON-RPC interfaces, and adds authentication, task/session
|
|
7
|
-
contracts, streaming, interrupt handling, and runtime guidance. It does not
|
|
8
|
-
fully isolate upstream model credentials from OpenCode runtime behavior.
|
|
5
|
+
This repository wraps OpenCode as an A2A runtime. It exposes A2A HTTP+JSON and JSON-RPC interfaces, and adds authentication, task/session contracts, streaming, interrupt handling, and runtime guidance. It does not fully isolate upstream model credentials from OpenCode runtime behavior.
|
|
9
6
|
|
|
10
7
|
## Security Boundary
|
|
11
8
|
|
|
12
|
-
- `A2A_BEARER_TOKEN` protects access to the A2A surface, but it is not a
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
- Within one instance, consumers share the same underlying OpenCode
|
|
21
|
-
workspace/environment by default.
|
|
22
|
-
- LLM provider keys are consumed by the `opencode` process. Prompt injection or
|
|
23
|
-
indirect exfiltration attempts may still expose sensitive values.
|
|
24
|
-
- Payload logging is opt-in. When `A2A_LOG_PAYLOADS=true`, operators should
|
|
25
|
-
treat logs as potentially sensitive operational data.
|
|
26
|
-
- This project does not ship host bootstrap or process-manager wrappers as an
|
|
27
|
-
official product capability. Operators remain responsible for file
|
|
28
|
-
permissions, secret storage, service users, and supervisor-specific hardening.
|
|
9
|
+
- `A2A_BEARER_TOKEN` protects access to the A2A surface, but it is not a tenant-isolation boundary inside one deployed instance.
|
|
10
|
+
- One `OpenCode + opencode-a2a` instance pair is treated as a single-tenant trust boundary by design.
|
|
11
|
+
- Tenant isolation across consumers is expected to come from parameterized self-deployment.
|
|
12
|
+
- For mutually untrusted tenants, use separate instance pairs with distinct Linux users, workspace roots, credentials, and runtime ports.
|
|
13
|
+
- Within one instance, consumers share the same underlying OpenCode workspace/environment by default.
|
|
14
|
+
- LLM provider keys are consumed by the `opencode` process. Prompt injection or indirect exfiltration attempts may still expose sensitive values.
|
|
15
|
+
- Payload logging is opt-in. When `A2A_LOG_PAYLOADS=true`, operators should treat logs as potentially sensitive operational data.
|
|
16
|
+
- This project does not ship host bootstrap or process-manager wrappers as an official product capability. Operators remain responsible for file permissions, secret storage, service users, and supervisor-specific hardening.
|
|
29
17
|
|
|
30
18
|
## Threat Model
|
|
31
19
|
|
|
32
|
-
This project is currently best suited for trusted or internal environments.
|
|
33
|
-
Important limits:
|
|
20
|
+
This project is currently best suited for trusted or internal environments. Important limits:
|
|
34
21
|
|
|
35
22
|
- no per-tenant workspace isolation inside one instance
|
|
36
23
|
- no hard guarantee that upstream provider keys are inaccessible to agent logic
|
|
37
|
-
- bearer-token auth only by default; stronger identity propagation is still a
|
|
38
|
-
|
|
39
|
-
- operators remain responsible for host hardening, secret rotation, process
|
|
40
|
-
access controls, and reverse-proxy exposure strategy
|
|
24
|
+
- bearer-token auth only by default; stronger identity propagation is still a follow-up hardening area
|
|
25
|
+
- operators remain responsible for host hardening, secret rotation, process access controls, and reverse-proxy exposure strategy
|
|
41
26
|
|
|
42
27
|
## Reporting a Vulnerability
|
|
43
28
|
|
|
44
|
-
Please avoid posting active secrets, bearer tokens, or reproduction payloads
|
|
45
|
-
that contain private data in public issues.
|
|
29
|
+
Please avoid posting active secrets, bearer tokens, or reproduction payloads that contain private data in public issues.
|
|
46
30
|
|
|
47
31
|
Preferred disclosure order:
|
|
48
32
|
|
|
49
|
-
1. Use GitHub private vulnerability reporting if it is available for this
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
directly through GitHub before opening a public issue.
|
|
53
|
-
3. For low-risk hardening ideas that do not expose private data, a normal
|
|
54
|
-
GitHub issue is acceptable.
|
|
33
|
+
1. Use GitHub private vulnerability reporting if it is available for this repository.
|
|
34
|
+
2. If private reporting is unavailable, contact the repository maintainer directly through GitHub before opening a public issue.
|
|
35
|
+
3. For low-risk hardening ideas that do not expose private data, a normal GitHub issue is acceptable.
|
|
55
36
|
|
|
56
37
|
## Supported Branches
|
|
57
38
|
|
|
@@ -17,10 +17,8 @@ Open a GitHub issue when you can provide:
|
|
|
17
17
|
|
|
18
18
|
## Security Concerns
|
|
19
19
|
|
|
20
|
-
Do not post active secrets, bearer tokens, or sensitive workspace data in a
|
|
21
|
-
public issue. Use the disclosure guidance in [SECURITY.md](SECURITY.md).
|
|
20
|
+
Do not post active secrets, bearer tokens, or sensitive workspace data in a public issue. Use the disclosure guidance in [SECURITY.md](SECURITY.md).
|
|
22
21
|
|
|
23
22
|
## Commercial Or SLA Support
|
|
24
23
|
|
|
25
|
-
This repository does not currently advertise a separate SLA or managed support
|
|
26
|
-
channel. GitHub issues are the default public support path.
|
|
24
|
+
This repository does not currently advertise a separate SLA or managed support channel. GitHub issues are the default public support path.
|