Fix contact patch schemas and live voice turn-taking - #76
Open
dimavrem22 wants to merge 22 commits into
Open
dimavrem22 wants to merge 22 commits into
dimavrem22 wants to merge 22 commits into
Conversation
dimavrem22
marked this pull request as ready for review
September 19, 2026 02:07
This comment has been minimized.
This comment has been minimized.
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.
Executive Summary
Fix contact-update schema drift, exact post-call SMS handling, and recurring live-test polling and voice timing failures without relaxing the assertions.
Description
The plugin exposes the intended optional contact-update fields through its actual MCP schema and gives recorded exact SMS bodies precedence over incidental speech-transcription variants. The live harness uses bounded, fully paginated email polling, observed greeting completion, and utterance-aware retry pacing. The hosted caller now uses short conversational turns with actual peer-response gating, rather than replaying a long request whose tail can be interrupted.
The specific fixes and evidence are listed below. Acoustic reliability is verified in live CI, not inferred from fixture-string tests.
Reason
Schema drift could turn profile-only contact edits into identifier updates, and post-call reconciliation could send a transcription variant instead of the recorded exact message. Independently, historical inbox scans and incomplete voice turn-taking caused recurring end-to-end failures.
Decisions
Testing
9538374; release version 0.2.13.uv lock --check --offlinepasses.Specific fixes
Runtime / product bugs
contact_id; omitted email/phone lists stay omitted and explicit empty arrays remain valid. Proof: actual MCP transport regressions for notes-only and empty-list updates.CI / test-harness fixes
Diagnostic improvement
Release metadata
0.2.12 → 0.2.13; aligninkbox_claude.__version__, which still reported0.2.10, and the MCP server version, which reported0.2.9, to0.2.13. Proof: all four values agree and offline lock validation passes.Test-integrity corrections
Caller scripts prescribed the implementation. Remove action/title/details/tool instructions from hosted speech and the initial call request. Remove tool names and schema identifiers from real-model contact CRUD and A2A requests. Voice mode and voicemail behavior remain normal runtime configuration; no expected answer or scenario solution is added to the product's instructions. The model must discover the correct tools from the installed plugin.
SMS assertions accepted extra prose and ignored unrelated duplicates. Inspect every fresh outbound SMS across the complete bounded inbox window. Require one row with the requested three words (case/punctuation normalization only), the sole intended recipient, a server timestamp at or after the persisted call end, zero sends before hangup, and unchanged duplicate-grace and host-completion proof. Proof: negative cases reject extra prose, merged/missing words, wrong/additional recipients, missing/in-call timestamps, unrelated duplicates, and pre-hangup sends.
A2A could match the caller's original token instead of the answer. Require the actual agent's final message for terminal results and agent-authored messages for progress. Proof: caller-only history fails; caller tokens and earlier agent messages cannot satisfy a wrong final answer. Existing protocol-state, clarification, delegation, cadence, and worker-result gates remain.
A greeting could satisfy requested readback. Require the full current marker in both the agent-owned spoken transcript and caller-owned received transcript. Proof: either missing readback leg fails even when caller intent and the saved action are otherwise present.
Identity answers could omit requested fields. Require the complete phone number, display name, and email; reject masked/truncated phone answers, fail missing named sender fixtures instead of skipping, require the requested SMS acknowledgement rather than arbitrary nonempty text, and require the requested number of tool names (all installed names for the full email listing, three for SMS). Caller requests contain no tool-selection or voicemail-schema hints. Proof: full-number regressions reject masking, truncation, extra digits, and unrelated numeric fragments; the complete offline suite passes.
Additional runtime drift exposed by natural requests
Optional call settings were required by the advertised MCP schema. Without caller-supplied schema hints, live calls overrode the configured voicemail setting. Replace shorthand call schema with explicit required
to_number/purposeonly; optional settings preserve configured defaults, while explicit overrides remain supported. Proof: the real MCP transport regression failed before the fix becauseoriginationwas required; it now validates minimal calls, explicit voicemail overrides, and required-purpose rejection. No caller configuration hints were restored.Identity tool omitted the requested display name. The SDK identity contains it, but the tool returned only handle/email/phone, leaving the model without the requested fact. Expose
display_namein the normal identity result. Proof: the regression failed with a missing field before the fix and now passes; strict live identity assertions remain.Speech evidence accepted merged or substituted words. Remove the historical homophone alias and concatenated-character matching from transcript/action evidence; require contiguous whole words with only case/punctuation normalization. Apply the same boundary rule to driver readback recognition so a partial or merged answer cannot stop retries or advance the conversation. Proof: negative merged/prefix/suffix/reordered/substituted-word cases and actual asynchronous staged-driver checks pass; both transcript legs, durable actions, and exact SMS gates remain required.
Preloaded host identity dropped the configured display name. The corrected identity tool alone did not repair answers based on preloaded session context: live replies contained the full phone/email/handle but omitted the name. Carry the configured display name from gateway startup through session construction into the normal host identity context. Proof: actual startup capture and host-options regressions both failed before the change and pass afterward; no test answer or scenario instruction is injected.