Skip to content

fix(sms-bridge): use blocking prompt response - #37

Merged
xnoto merged 2 commits into
mainfrom
fix/sms-bridge-blocking-prompt-response
Sep 5, 2026
Merged

fix(sms-bridge): use blocking prompt response#37
xnoto merged 2 commits into
mainfrom
fix/sms-bridge-blocking-prompt-response

Conversation

@xnoto

@xnoto xnoto commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

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

  • Bug fix
  • Feature / enhancement
  • Documentation
  • Infrastructure (OpenTofu root or module)
  • GitOps desired state (manifests, kustomize, charts, SOPS/KSOPS secrets)
  • Container image
  • CI / reusable workflow
  • Refactor / cleanup
  • Breaking change

Validation

  • Required pull-request checks pass — buildah run 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 step RUN python3 -m unittest discover -s /app -p "test_*.py" -v ran all 17 tests (Ran 17 tests in 0.088s — OK), including the single-blocking-request, info/parts extraction, invalid-prompt-result, and narrowed-taxonomy tests. Push to registry was correctly skipped in PR mode.
  • 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

  • Contains no plaintext secrets, decrypted SOPS values, state files, kubeconfigs, tokens, or private endpoints.
  • No local OpenTofu init/plan/apply/destroy/import/state operations were run or claimed — plans come from pull-request checks.
  • 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.

## 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.
@xnoto
xnoto requested a review from a team as a code owner September 5, 2026 06:48
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Image CI passed

Pre-commit validation passed. View the workflow run.

@xnoto
xnoto merged commit 008a074 into main Sep 5, 2026
4 checks passed
@xnoto
xnoto deleted the fix/sms-bridge-blocking-prompt-response branch September 5, 2026 06:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant