Rich Interactions: extensible structured-interaction framework (identity intake = first kind)#176
Merged
Merged
Conversation
…raction framework Brent's design directive: identity intake must be the FIRST INSTANCE of a general pattern, not a bespoke feature. This reshapes the seam shipped in 1.19.0 (zero external consumers) into 'Rich Interactions': - Generic wire envelope: interaction_required / interaction_invalid events + the single submit_interaction resume verb (interactionId echo guards stale submits). Per-kind precision lives in spec/interactions/<kind> schemas and the per-kind raise tools — so adding a kind (date picker, choice chips, file upload, address, CSAT, payment, e-sign) needs NO new events and NO client-library release. - Capability negotiation is a per-kind supports list; the server picks rich card vs conversational fallback PER KIND. - Server extension recipe: the InteractionKind trait (raise-tool schema + server-side validator + conversational-degradation directive) + InteractionRegistry; the park/bridge/resume machinery is kind-agnostic. - identity_intake (capability identity_form) ships as the first kind through the framework, behavior unchanged: validated form on the widget, field-by-field validated conversational collection on SMS/voice, same canonical payload either way, session identity attach on the OTP contact keys. Design record: docs/Architecture/Rich Interactions.md (names the pattern, documents the extension recipe end-to-end, lists candidate kinds, and notes the OTP/tool-approval overlays as prior instances to retrofit). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FczKhti6h4s6yhYXG6V86o
🦋 Changeset detectedLatest commit: ae7cf79 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
This was referenced Jul 3, 2026
brentrager
added a commit
that referenced
this pull request
Jul 5, 2026
…I) (#183) pr-kind-deploy-smoke.yml checked out SmooAI/smooth-operator-core with no `ref`, so when core@main advanced (multimodal `Message.images` field), this repo's main stopped compiling against it and `cargo build --locked` failed the lock check — turning EVERY open PR red for reasons unrelated to its own diff. Why pin: the cross-repo path-dep means a moving core@main is an uncontrolled input to this repo's CI. Pinning to a known-good SHA makes core adoption a deliberate, reviewable bump instead of a silent break. Interim until core publishes to crates.io and the cross-repo checkout goes away. - runtime.rs / runner.rs: add `images: vec![]` to the replayed-history EngineMessage constructions (text-only, no attachments). - Fix stale test literals missing new struct fields: suggested_replies.rs (`identity_intake` → `interactions`, folded in #176) and serve_smoke.rs (ServerConfig + TurnRequest new fields). - Regenerate Cargo.lock against core@main (`cargo update -p smooai-smooth-operator-core`) so `--locked` passes. - Pin the CI core checkout to 3c7b21dbde4f31519b2eab3d5343f154119fe655. Gates: cargo fmt --check, cargo clippy (no errors), cargo test --workspace (69 test binaries, 0 failed), and `cargo build --locked` all green against the pinned core. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Merged
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.
Why
Design directive from Brent: identity intake (shipped in 1.19.0, zero external consumers yet) must be the first instance of a general pattern, not a bespoke feature. Future kinds — date/appointment picker, choice chips, file upload, address, rating/CSAT, payment handoff, e-sign — must be cheap to add.
The pattern (
docs/Architecture/Rich Interactions.md)interaction_required { interactionId, kind, spec, reason }/interaction_invalid { errors }+ ONE resume verbsubmit_interaction { interactionId, kind?, values | declined }. Justified in the ADR: with a generic wire, a new kind is server-side only — no new events, no client-library release (old clients simply don't declare the capability and get the fallback). Per-kind precision lives inspec/interactions/<kind>.schema.json+ the per-kind raise tools.supports: ["identity_form", …]at session create; the server picks rich vs conversational fallback per kind.InteractionKindtrait — raise-tool schema (tool_schema/parse_request), server-side validator (validate→ canonical payload or per-field errors), conversational degradation (fallback_directive) — registered in anInteractionRegistry. All park/bridge/resume machinery is kind-agnostic (one implementation).identity_intake through the framework (unchanged behavior)
Validated inline form on capable clients; field-by-field validated conversational collection on text channels; identical canonical payload either way; session identity attach on the OTP contact keys.
interactionIdecho means a stale card can never resolve a newer park.Supersedes 1.19.0's typed
identity_intake_*events (removed — same release train, no consumers).Tests
tests/interactions.rs: rich park/mismatch/invalid-stays-parked/valid-resume/decline, conversational directive + required-ness stash + re-ask, capability recording incl. unknown-capability forward-compat, no-pending error) — fmt + clippy cleanspec/interactions/)🤖 Generated with Claude Code
https://claude.ai/code/session_01FczKhti6h4s6yhYXG6V86o