Poche
Your agent, on your device — offline, private, yours
A personal agent living entirely on the iPhone: streaming chat over Apple Foundation Models that creates reminders, events, notes, and tasks behind explicit confirmation cards. No API, no server, no account.
41
Swift files, ~2,930 lines
21/21
automated tests green
7
tools exposed to the model
0
network requests in the AI path
4,096
token context, actively managed
~3B
parameters, on the Neural Engine
Overview
Poche is a personal agent whose only generative engine is Apple Foundation Models — the ~3B-parameter Apple Intelligence model running on the device's Neural Engine. The founding rule: if a feature can't be done on-device, it isn't done. There is no cloud fallback, no degraded promise.
It's a streaming chat that acts: creating reminders and calendar events through EventKit, saving notes and tasks in SwiftData, and recalling your data through local semantic search (NLEmbedding). The model never causes a side effect — it proposes a tool call, and the app validates, displays a confirmation card, and executes only after the user confirms. No code path writes without traversing the confirmation layer.
The central engineering problem is the 4,096-token context window: system instructions, tool schemas, history, and the response all share it. Poche measures continuously, condenses the conversation at 70% through a separate @Generable summarization call, and recycles the session invisibly — the user never sees an error. A tripwire test registers a URLProtocol spy and fails if a single network request leaves during agent exercises.
Key Features
An agent that acts
Creates reminders, calendar events, notes, and tasks through EventKit and SwiftData — from natural conversation, in streaming.
Non-bypassable confirmation
The model proposes; the user disposes. Every write crosses a confirmation card with dates resolved and validated in Swift — no expert mode to disable it.
Context budget engine
Continuous token measurement, condensation at 70% via a separate @Generable call, and invisible session recycling — a local chat that never breaks.
Local semantic search
Notes, tasks, and conversation summaries indexed with NLEmbedding — long-term memory retrieved on demand, entirely on-device.
Zero network, proven
A tripwire test registers a URLProtocol spy and fails if a single request leaves the device while the agent's tools and search are exercised.
On-device dictation
SFSpeechRecognizer with on-device recognition required — if the device can't transcribe locally, the mic button doesn't exist. No server fallback.
How It Works
Stream the conversation
A LanguageModelSession streams responses with a first-token target under 400 ms, backed by versioned system instructions costing a measured ~230 tokens.
Propose, never execute
Tools validate arguments hostilely (dates resolved in Swift, titles truncated, bounds checked) and emit proposals to the ConfirmCenter — the only write path is the ActionExecutor, after user confirmation.
Manage the 4,096-token budget
A pessimistic estimator drives a discreet context gauge; at 70% the conversation is condensed by a separate structured call and the session recycled with the summary plus the last 3 turns.
Externalize long memory
Summaries persist in SwiftData and come back on demand through searchMyData — the agent remembers across sessions without ever growing the context.
Handle every model state
Available, device-not-eligible, Apple Intelligence off, model downloading — each gets its own screen and action, and guardrail refusals are calm UI states, never raw errors.
Tech Stack
Platform
Intelligence
Data & system
Highlights
- No code path writes without traversing the confirmation layer — verified by the tool-pattern test suite
- 21/21 tests green under Swift 6 strict concurrency, including the zero-network tripwire
- Tool outputs are capped (~200 tokens) because one tool returning 30 events kills a 4K session
- Date resolution happens in Swift, never in the model — displayed in clear text on every confirmation card
- TestFlight 1.0.0 uploaded to App Store Connect (ai.spboucher.poche)
- The whole agent — chat, tools, memory, dictation — fits in ~2,930 lines of Swift