feat(mobile): add api.ask — the client half of swipe-to-ask (#321) - #330
Merged
Conversation
First increment of #321. The mobile app implements one of the four verbs: it calls only /auth/login, /memory/capture and the two /notifications endpoints, with NO reference to /memory/ask anywhere. A user can put memories in from their phone but cannot ask anything of them. This adds the transport only — `api.ask()` over the existing `request`, which means it inherits the #318 one-shot refresh-and-retry for free: a question asked more than JWT_ACCESS_TTL after sign-in re-authenticates transparently instead of being lost, exactly like capture now does. The contract worth stating at the seam, because getting it wrong is the obvious way to build this badly: A GROUNDED MISS IS NOT AN ERROR. When retrieval finds nothing above the §05.6 miss band the server still returns 200 with an honest answer, an empty `citations` array and a floored `confidence`. The UI must render that as "no memory about this", never as a failure — only a thrown ApiError is a real failure. The comment says so at the call site so the screen author does not have to infer it. NOT included — the UI and the gesture, which are the bulk of #321: - an ask surface (query input, answer, citations, loading + miss states) - the horizontal swipe that switches modes The axis matters and is recorded in #321: `app/index.tsx` already drives BOTH hold-to-talk and slide-up-to-type from a single VERTICAL Pan, so mode switching must be horizontal or it will fight capture. That is not theoretical — adb vertical swipes during testing repeatedly started voice recordings instead of opening the composer. type-check and lint green. No behaviour change: nothing calls `ask` yet. Refs #321 (does not close it). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 1, 2026
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.
First increment of #321 — transport only, no UI, no gesture.
Mobile implements one of the four verbs today: it calls
/auth/login,/memory/captureand the two/notificationsendpoints, with no reference to/memory/askanywhere. You can put memories in from your phone but cannot ask anything of them.api.ask()goes through the existingrequest, so it inherits the #318 one-shot refresh-and-retry for free: a question asked more thanJWT_ACCESS_TTLafter sign-in re-authenticates transparently instead of being lost, exactly as capture now does.The contract stated at the seam, because getting it wrong is the obvious way to build this badly: a grounded miss is not an error. When retrieval finds nothing above the §05.6 miss band, the server still returns 200 with an honest answer, empty
citationsand a flooredconfidence. The UI must render that as "no memory about this", never as a failure — only a thrownApiErroris a real failure. That's documented at the call site so the screen author doesn't have to infer it.Not included (the bulk of #321): the ask surface (query input, answer, citations, loading/miss states) and the horizontal swipe.
The axis matters:
app/index.tsxalready drives both hold-to-talk and slide-up-to-type from a single verticalPan, so mode switching must be horizontal or it fights capture. Not theoretical — adb vertical swipes during testing repeatedly started voice recordings instead of opening the composer.askyetRefs #321 (does not close it).
🤖 Generated with Claude Code