fix(sms-bridge): use blocking prompt response - #37
Merged
Conversation
## Summary
- OpenCode's documented `POST /api/session/{sessionID}/prompt` is
blocking: it returns the completed assistant message, a JSON object
with `info` and `parts`. No `/wait` call or message-list retrieval
belongs in this flow, so both requests and their `wait` /
`message-list` operation tokens are removed from the bridge and from
the bounded error-code taxonomy.
- The assistant reply is now parsed directly from the completed prompt
response: the documented `info` object and `parts` list shape is
validated, and only `text` parts are preserved; non-text parts such
as tool state are ignored.
- The PII-safe bounded failure codes are preserved: an unusable prompt
result still fails with the static `opencode-response-invalid` code,
prompt-stage request failures still map to
`opencode-request-failed:prompt:<category>`, and no raw response
data, URLs, sessions, or provider detail are logged or persisted.
- Tests now prove exactly one prompt request per job with no `/wait`
or `/message` request, correct `info`/`parts` assistant-text
extraction with non-text parts ignored, safe rejection of invalid
prompt results (including the legacy admission-only shape), and that
`wait` / `message-list` codes are gone from the bounded taxonomy.
None — owner-authorized repair to align with the documented blocking
prompt contract; no driving issue supplied.
## Type of change
- [x] Bug fix
- [ ] Feature / enhancement
- [ ] Documentation
- [ ] Infrastructure (OpenTofu root or module)
- [ ] GitOps desired state (manifests, kustomize, charts, SOPS/KSOPS secrets)
- [x] Container image
- [ ] CI / reusable workflow
- [ ] Refactor / cleanup
- [ ] Breaking change
## Validation
- [ ] Required pull-request checks pass — pending at commit time; the
pull-request `buildah` workflow runs pre-commit (including Gitleaks),
changed-image detection, and the non-publishing bridge image build,
whose Containerfile step runs `python3 -m unittest discover -s /app -p
"test_*.py" -v`. The result will be recorded on the PR.
- [x] Generated or centrally distributed files were regenerated by
their owning automation, not hand-edited — none changed; only
`opencode-sms-bridge/server.py` and `opencode-sms-bridge/test_server.py`
were edited.
No local tests, container builds, OpenTofu, SOPS, state, or live-system
operations were run or claimed. CI is the validation authority.
## Impact and rollout
**Producer changed:** `makeitworkcloud/images/opencode-sms-bridge` is
the canonical bridge-image source. An approved merge automatically
publishes a new immutable GHCR image tag. This PR neither publishes nor
deploys anything itself.
**Consumer unchanged:** `kustomize-cluster` continues to select its
currently pinned image; this PR makes no GitOps or image-selection
change. After an approved merge and publication, a separate reviewed
GitOps PR and explicit confirmation are required before image
selection, Argo reconciliation, health verification, and a new
approved-source SMS test.
**Behavior boundary:** a text prompt now issues exactly one OpenCode
HTTP request (the blocking prompt POST) instead of three (prompt
admission, wait, message list). Worker rows can no longer persist
`opencode-request-failed:wait:*` or
`opencode-request-failed:message-list:*` detail codes — any such
composition now collapses to `opencode-request-failed:unknown:*`; all
other codes are unchanged.
**Rollback:** if a later selected image regresses, use the canonical
GitOps workflow to select a reviewed immutable image tag. Do not
overwrite image tags or alter live state manually.
## Safety and secrets
- [x] Contains no plaintext secrets, decrypted SOPS values, state
files, kubeconfigs, tokens, or private endpoints.
- [x] No local OpenTofu init/plan/apply/destroy/import/state operations
were run or claimed — plans come from pull-request checks.
- [x] Breaking or irreversible effects are described above with
rollback notes.
AI-assisted change: an OpenCode agent materially produced this change;
reviewers should verify the blocking prompt contract, the `info` /
`parts` extraction and its invalid-shape rejection, the narrowed
bounded taxonomy, and CI results before merge.
Image CI passedPre-commit validation passed. View the workflow run. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
POST /api/session/{sessionID}/promptis blocking: it returns the completed assistant message, a JSON object withinfoandparts. No/waitcall or message-list retrieval belongs in this flow, so both requests and theirwait/message-listoperation tokens are removed from the bridge and from the bounded error-code taxonomy.infoobject andpartslist shape is validated, and onlytextparts are preserved; non-text parts such as tool state are ignored.opencode-response-invalidcode, prompt-stage request failures still map toopencode-request-failed:prompt:<category>, and no raw response data, URLs, sessions, or provider detail are logged or persisted./waitor/messagerequest, correctinfo/partsassistant-text extraction with non-text parts ignored, safe rejection of invalid prompt results (including the legacy admission-only shape), and thatwait/message-listcodes are gone from the bounded taxonomy.None — owner-authorized repair to align with the documented blocking prompt contract; no driving issue supplied.
Type of change
Validation
buildahrun 33950842557 (job checks / detect / build) passed pre-commit (including Gitleaks), changed-image detection (opencode-sms-bridge), and the non-publishing bridge image build. The build's Containerfile stepRUN python3 -m unittest discover -s /app -p "test_*.py" -vran all 17 tests (Ran 17 tests in 0.088s — OK), including the single-blocking-request,info/partsextraction, invalid-prompt-result, and narrowed-taxonomy tests.Push to registrywas correctly skipped in PR mode.opencode-sms-bridge/server.pyandopencode-sms-bridge/test_server.pywere edited.No local tests, container builds, OpenTofu, SOPS, state, or live-system operations were run or claimed. CI is the validation authority.
Impact and rollout
Producer changed:
makeitworkcloud/images/opencode-sms-bridgeis the canonical bridge-image source. An approved merge automatically publishes a new immutable GHCR image tag. This PR neither publishes nor deploys anything itself.Consumer unchanged:
kustomize-clustercontinues to select its currently pinned image; this PR makes no GitOps or image-selection change. After an approved merge and publication, a separate reviewed GitOps PR and explicit confirmation are required before image selection, Argo reconciliation, health verification, and a new approved-source SMS test.Behavior boundary: a text prompt now issues exactly one OpenCode HTTP request (the blocking prompt POST) instead of three (prompt admission, wait, message list). Worker rows can no longer persist
opencode-request-failed:wait:*oropencode-request-failed:message-list:*detail codes — any such composition now collapses toopencode-request-failed:unknown:*; all other codes are unchanged.Rollback: if a later selected image regresses, use the canonical GitOps workflow to select a reviewed immutable image tag. Do not overwrite image tags or alter live state manually.
Safety and secrets
AI-assisted change: an OpenCode agent materially produced this change; reviewers should verify the blocking prompt contract, the
info/partsextraction and its invalid-shape rejection, the narrowed bounded taxonomy, and CI results before merge.