Snag Control
Snag Control is a voice front end for agents you already run: an assistant, an ops agent, a coach. Ask them things, hand them jobs, see what is running, and approve or park what they want to do, on the phone, through Siri and AirPods, or on the car screen (CarPlay).
Snag Control is part of Pro (see Plans). On Free, the Control tab shows "Snag Control" and "Ask your agents things by name and approve what they want to do, here, on AirPods or in the car.", with the Pro offer. Asking by voice or Siri on Free answers "Snag Control is a Pro feature."
Snag has no agents built in. Each agent you connect tells Snag its name, what it can do and how private its answers are. Capture is unchanged: anything that is not for an agent or a command is a capture, and Snag says "Snagged."
The Control tab
From top to bottom:
| Part | What it does |
|---|---|
| Ask bar: "Ask an agent", "or say "Ask Snag" or its name" | Opens the ask sheet. See Ask on the phone below. |
| Voice commands chip | Opens Voice commands. Shows a count when a linked repo has changes to review. |
| Parked chip ("Parked", "Parked 2") | Opens Parked (below). |
| Agents, In flight, Waiting on you | Three segments. Waiting on you shows a count when something needs you. |
The Control tab's icon carries the same Waiting on you count. Pull down on the tab to check every agent now.
Agents
With no agents, the tab shows "No agents yet", an "Add an agent" button and "Try the demo agents" (see Try the demo agents below).
With agents, each row shows the agent's name, where it comes from and what it can do (for example "Nextcloud Talk: asks, jobs, approvals"), and its privacy level. The demo agents are labelled "Demo". Below the list:
- Ask Snag: picks which agent answers "Ask Snag" and unnamed questions ("Goes to Assistant"). It lists agents that answer questions. Until one is picked, the first agent that answers questions is used.
- Add an agent.
In flight
Jobs and questions sent and not answered yet, each with the agent, what was asked and "Started 16:10, from the phone" (or "from the car", "from Siri"). When the agent says what it is doing, the row shows that step, for example "Running the tests". Once the step is more than 2 minutes old the row adds its age: "(4 min ago)", then "(2 hr ago)" from an hour, and "(yesterday)" past a day.
Under "Done today": finished and failed items from today. A failed item shows its reason, or "Didn't finish.". A job the agent's server has lost shows "Ops lost that one."
With nothing running: "Nothing running. Ask an agent, or say "Sysadmin, look into ..." to hand over a job."
Waiting on you
Approvals waiting for a decision (held ones stay here), unread answers, and items that were never sent. With nothing waiting: "Nothing waiting on you."
- An approval shows as a card with the agent, its class and the action. See Approvals on the phone below.
- An answer shows "An answer, 16:10" and a "Read" button.
- An item that was never sent shows its reason (or "Not sent yet."), "Send again" and "Remove".
Add an agent
Control > Agents > Add an agent. The sheet says: "Once connected, an agent tells Snag its name, what it can do and how private its answers are."
| Option | Subtitle in the app | What it needs |
|---|---|---|
| Add an agent server | "Your own agent server, using the Snag agent API" | A Base URL and a Key, shown in that app's settings or set on your own server |
| Nextcloud Talk | "A Talk room per agent" | A connected Nextcloud account, a room token and a name |
| An A2A agent | "Paste its agent card URL." | Not available in this version |
Agents behind an OpenAI-compatible server (a local model server or an agent framework's API server) are added under Settings > Advanced instead. See Bring your own stack.
Add an agent server
- Open Control > Add an agent > Add an agent server.
- Enter the Base URL (for example
https://example.net/snag/v1/) and the Key. The key stays in this iPhone's Keychain. - Tap Connect.
Snag asks the address for its agents. The result:
| Shown | Meaning |
|---|---|
| "Connected." and "Ops can be asked from Snag now. Say the name first." | The server answered with its agents. |
| "Saved." and "Nothing answered yet. Check the address and the key; Snag tries again each time it opens." | Nothing came back. "Remove it" deletes the entry. |
| "That isn't a web address. It starts with https://" | The Base URL is not a web address. |
One server can describe several agents; all of them appear in Agents. The protocol is in Snag agent API.
Some servers ask to trust each phone before its approvals count. Until the server does, the agent's page shows "Waiting for the server to trust this phone.", and so does any approval card that needs Face ID or the code word.
Try the demo agents
"Try the demo agents": "Three made-up agents to practise on: a run coach, an ops bot and a project bot." It shows on the Add an agent server page, and under "No agents yet" in Agents.
- On Pro, or during the free trial, it adds the three as an agent server: "Demo agents added. Try "Coach, how did my run go?"" On the car or headphones Snag also says "Demo agents added. Ask Coach how your run went."
- They appear in Agents labelled "Demo" and take asks, jobs and approvals like any agent. Their data is made up. Nothing real is read or changed.
- On Free, it opens the Pro screen headed "The demo agents come with Pro."
- Once they are added, the Add an agent server page shows "Remove the demo agents" in its place. It removes all three: "Demo agents removed."
Nextcloud Talk
One Talk room per agent. Snag posts in the room as you and reads the agent's reply.
- Connect Nextcloud first, in Settings > Connections. Without it the form shows "Connect Nextcloud first" and an "Open Settings" button.
- Open Control > Add an agent > Nextcloud Talk.
- Enter the Room token (from the room's conversation settings) and Its name: the word you will say, for example "Ops".
- Pick a Privacy level (see Privacy levels below).
- Turn on It asks for approvals if the room carries numbered proposals that take "go N".
- Tap Connect. The result is "Connected." and "Say "Ops, ..." to ask it.".
A room token is letters and numbers only. Anything else shows "A room token is letters and numbers only, as shown in the room's settings."
An agent's page
Tap an agent in Agents.
| Section | Shows |
|---|---|
| Header | The name and where it comes from: "From Nextcloud Talk", "From example.net, Snag agent API", or "From ..., set in a linked repo" |
| Say | Example lines built from what it can do: "Ops, what's the latest?", "Ops, look into ... for tomorrow", "Anything need me?" |
| It can | "Answer questions", "Take on jobs" ("Runs on; Snag hears back later"), "Ask you to approve actions", and each action type it has asked to approve, with its class or "Blocked" |
| Privacy | Everyday, Personal or Private. Changing it here overrides what the agent said. |
| Approvals | "Approval rules", when the agent can ask for approvals. See Settings > Approvals below. |
| Needs Face ID for | Agent servers only. See Needs Face ID for below. |
| Ask (name) | Opens the ask sheet for this agent. |
| Disconnect | Removes the agent and its key. An agent from a linked repo shows "Ops comes from a linked repo. Remove it there, or unlink the repo in Voice commands." instead. Several agents from the same app go together: "This disconnects 3 agents from the same app." |
If the agent is no longer there: "This agent isn't connected now." and "Its backend may be down, or it was disconnected."
Privacy levels
Every agent has a level. The agent sets it; the agent's page can change it. An answer can also carry its own level, and the stricter one applies.
| Level | On the phone | By voice (hands-free, AirPods, car) | Through Siri ("Ask Snag") |
|---|---|---|---|
| Everyday | Shown | Spoken | Spoken |
| Personal | Shown, marked "Personal: not read aloud" | Snag asks "Say it out loud?" first | Not spoken: "Ops has your answer. It's personal. Open Snag to read it." |
| Private | Shown, marked "Private: not read aloud" | Snag asks "Say it out loud?" first | Not spoken: "Ops has your answer. It's private. Open Snag to read it." |
Only a clear yes ("yes", "yeah", "say it", "go ahead", "read it", "say it out loud") speaks the answer. Anything else, silence included, keeps it: Snag says "Parked." (in the car, "Kept for later.") and the answer waits in Parked. In the car the question names the agent: "Ops has it. It's private. Say it out loud?"
Ask on the phone
- Tap the ask bar, or "Ask (name)" on an agent's page.
- Type, or use the keyboard's mic to say it. Start with an agent's name, or the question goes to the Ask Snag agent ("Start with a name, or it goes to Assistant.").
- Tap send.
The answer shows in the sheet, never spoken. "Read it aloud" reads it; "Park" moves it to Parked. A link in the answer shows as "Open the full answer".
| Shown | Meaning |
|---|---|
| "Asking..." | Waiting for the answer. |
| "Ops is still on it. The answer will show in Waiting on you." | Slower than the agent's ask time. Snag keeps checking. |
| "Sent to Ops. It's in In flight." | The agent takes jobs only, so the words went as a job. |
| "Couldn't reach Ops." | The agent did not answer. |
Ask by voice
Control listens in any hands-free capture (Snag this, "Hey Siri, snag this", the Action button, AirPods) and on the car screen, once an agent or a command exists. The first thing said is checked in this order:
- A command whose phrase matches everything said.
- An agent's name, or a Control phrase (below).
- Anything else is a capture, as before.
Siri also takes "Ask Snag" (or "Ask Snag a question") with the question.
Naming an agent
| Said | Does |
|---|---|
| "Ops, how did the backup go?" | The name first, then a question: an ask. One short answer. |
| "Ops, look into the build for tomorrow" | The name first, not a question: a job. Snag says "Sent to ops." |
| "ask Ops to ...", "tell Ops to ...", "get Ops to ...", "have Ops ..." | A job. |
| "ask Ops how ...", "check with Ops about ..." | An ask. |
| "what did Ops say", "what did Ops find" | The latest answer from that agent. |
| "what's Ops doing", "check on Ops", "Ops status" | What that agent is doing. See What's it doing? below. |
A question starts with a question word (how, what, when, is, can, any ...) or ends with a question mark. An agent that only answers questions gets a job as a question, and the other way round. An agent that does neither says "Ops can't take that."
A leading "snag", "hey" or "ok" is ignored.
What's it doing?
Asked "what's Ops doing" (or "check on Ops", "Ops status"):
| Ops has | Snag says |
|---|---|
| A job running, with a step | The step: "It's running the tests." |
| A job running, no step | "It's working on it. No step yet." |
| Jobs running and something waiting on you | "Ops: one running, one waiting on you." |
| Nothing running, and the last job was lost | "Ops lost that one." |
| Nothing at all | "Ops has nothing running." |
With several jobs running, the newest one's step is read. "what did Ops say", before any answer, gives the same step line while a job runs.
A name mid-sentence
If an agent's name turns up anywhere else ("remind me to call Ops later"), Snag asks one short question: "Send to Ops?", or "Ops or Assistant?" for two. A clear answer (the name, or "yes" when there is one agent) sends it. Anything else, silence included, makes it a capture.
Control phrases
Said on their own:
| Said | Does |
|---|---|
| "anything need me", "anything waiting", "what's waiting" | The count ("Two things need you.") then the first item. |
| "next", "what else" | The next waiting item. "That's all." at the end. |
| "what are my agents doing", "status", "what's running" | "Two running, one waiting on you." or "Nothing running." |
| "approve", "hold", "deny" | Decides the item just read out. |
| "park it", "later" | Parks the item just read out. |
| "more", "go on" | The next part of a long answer. |
Spoken answers
Answers are read in short chunks, up to 25 words each. After a chunk Snag asks "More, or park it?". "more" reads the next chunk, twice at most; "park it" parks the rest. Acknowledgements are 8 words or fewer: "Sent.", "Parked.", "Held.".
Dispatch and In flight
A job ("Ops, look into ...") is sent and Snag says "Sent to ops.". It shows in In flight until the agent answers. A slow question also goes to In flight, with "Sent. I'll check back.".
Snag checks In flight every 60 seconds while it is open, each time it opens, and on pull to refresh. When an answer arrives it moves to Waiting on you. A finished job opens as a digest: "The short version", then "More", and a "Next step" when the agent raised an approval for the same job.
A Talk agent's own standalone lines that start "Done:" also arrive as answers in Waiting on you.
When the agent's server has lost a job, the job is marked failed and Snag says, when asked: "Ops lost that one." When a server answers that it has no agent by that name, Snag says the server's reason, parks the item and asks the server for its agents again.
Approvals
An agent asks to approve an action. The agent proposes a class for each action type; you set the rules.
| Class (as shown) | Meaning |
|---|---|
| Routine | Low risk, reversible. |
| Needs a confirm | Consequential, for example a deploy or sending something. |
| Irreversible | Can't be undone. |
Nothing is ever approved by silence. Silence, a mishear or an expired approval holds.
Approvals by voice
When an approval is read out (after "anything need me"):
| Class | Snag says | To approve |
|---|---|---|
| Routine | The action, then "Approve or hold?" | "approve" |
| Needs a confirm | The action, then "Say restart web to approve." | Repeat the confirm phrase. "not" or "don't" in the answer holds. |
| Needs Face ID (every irreversible action by default, see Needs Face ID for) | "That one needs Face ID. Approve it on the phone." | Not by voice: parked for the phone. |
| Needs your code word | "That one needs your code word." | Not by voice: parked. The code word is asked on the car screen only. |
| Anything else, while driving, when the rule or the agent does not allow it in the car | "That one waits until you've stopped." | Parked. |
An action whose phone rule is Face ID, or an irreversible one on a server whose "Needs Face ID for" is None, says "That needs Face ID. Parked for your phone." instead.
"hold" (or "wait", "not now", "no") holds: it stays in Waiting on you. "deny" denies it. "park it" parks it. After an approve Snag says "Approved." and the agent's outcome, or "Approved. I'll tell you when it's done.". An approval that has expired: "That one has expired. Held."
Snag counts as driving when CarPlay is connected or the phone is on the car's audio. Every ask, job and decision is recorded with where it came from and whether you were driving.
Approvals on the phone
The buttons on an approval card follow the rule for that agent and action type (Settings > Approvals > Rules per agent):
| Rule | Buttons | Then |
|---|---|---|
| One tap | "Approve", "Hold" | Approved at once. |
| Review, then tap | "Review", "Hold" | A sheet: the action, what goes out, "Send it" or "Hold". It also shows the car's confirm phrase: "In the car: "say restart web to approve"." |
| Face ID | "Review" (Face ID symbol), "Deny" | A sheet: what will happen, the target, when it expires, "Approve with Face ID" or "Deny". |
| Not through Snag | "Only in Ops's own app." and "Hold" | It can't be approved in Snag. |
Irreversible actions always go through the Face ID sheet, whatever the rule. A card whose server asks for more shows it: "Needs Face ID" or "Needs your code word". On the phone both are approved with Face ID.
Face ID alone, with no passcode, approves:
- anything the agent's server marks as needing Face ID or the code word;
- anything its "Needs Face ID for" covers (by default every irreversible action);
- any action type whose phone rule was set to Face ID.
Elsewhere, Face ID or the passcode works. Parked approvals show "Deny" where the list shows "Hold".
| Message | Meaning |
|---|---|
| "Face ID didn't work. Nothing was approved." | Face ID failed or was cancelled. |
| "Turn on Face ID on this iPhone to approve this. Nothing was approved." | The approval needs Face ID and it is not set up on this iPhone. |
| "Not approved. Face ID or the passcode didn't go through." | Face ID or the passcode failed, where either works. |
| "Set a passcode on this iPhone to approve this. Nothing was approved." | The iPhone has no passcode. |
| "Waiting for the server to trust this phone." | The server has not trusted this phone. Until it does, approvals that need Face ID or the code word don't go through. |
Needs Face ID for
On an agent server agent's page, "Needs Face ID for" sets which classes the app asks Face ID for, even when the server does not. It applies to every agent on that server.
| Option | Covers |
|---|---|
| None | Nothing: "Any approval method is accepted." |
| Destructive (the default) | Irreversible actions |
| Destructive and consequential | Irreversible and Needs a confirm |
| Everything | Every approval |
What it covers is approved on the phone with Face ID only. In the car and by voice it parks: "That one needs Face ID. Approve it on the phone." If the server asks for more than this setting, the server's requirement applies.
After a decision a short line shows at the bottom: "Approved.", "Held.", "Denied.", or the agent's own reply.
Park
"park it" on any item, "Park" on an answer, or anything that needs a screen, moves it to Parked. Parking never approves anything.
Parked
Control > Parked. "What needed a screen. Nothing here was approved by silence."
Parked holds: irreversible approvals from the car, approvals that need Face ID or the code word ("Needs Face ID", "Needs your code word"), Personal and Private answers that were not spoken, long answers with more to hear, anything parked by "park it", and anything that failed in the car. Each card shows the agent, when it was parked ("Ops, 18:51 in the car"), why, and one action:
| Item | Button |
|---|---|
| An approval | The approval buttons, with "Deny" in place of "Hold" |
| An Everyday answer | "Read" |
| A Personal or Private answer | "Show me" |
| Anything else | "Resume" |
Resume puts an approval back in Waiting on you and a job back in In flight. With nothing parked: "Nothing parked."
Settings > Approvals
Settings > Approvals has two rows: Code word and Rules per agent.
Rules per agent
"Each agent proposes a class for every action. You decide how each is approved."
An action type appears under its agent the first time that agent asks to approve one ("None yet. Each action type shows here the first time Ops asks you to approve one."). Tap one to set its rule:
| Section | Options |
|---|---|
| In the car | "By voice" ("Approve with "yes""), "Code word" ("After a readback"), "Passenger mode" ("Approve on the phone"), "Park for a screen" ("Always offered", always on) |
| On the phone | "One tap", "Review, then tap" (for Needs a confirm), "Face ID" |
| Not through Snag | "Only in Ops's own app": Snag can't approve this action type at all |
Defaults, until you change them:
| Agent proposes | In the car | On the phone |
|---|---|---|
| Routine | By voice | One tap |
| Needs a confirm | By voice | Review, then tap |
| Irreversible | Park for a screen | Face ID (fixed) |
New action types an agent adds later follow what it proposes; irreversible ones start as "park for a screen". Rules apply to approvals on the phone and on the car screen.
The Settings row shows a summary such as "3 agents, 1 action blocked".
Code word
"For irreversible actions in the car and on AirPods. Snag reads the action back first, then waits for this."
The code word is two words you don't use anywhere else. It is not a passcode: anyone in the car hears it.
To set it:
- Open Settings > Approvals > Code word.
- Tap Say a new one twice.
- Fill in Say it and Once more, with the keyboard's mic or by typing.
- Tap Save.
| Message | Meaning |
|---|---|
| "Two words, please. Like "blue heron"." | Not exactly two words. |
| "Those weren't the same. Say it twice again." | The two entries differ. |
The word is kept in this iPhone's Keychain. Settings shows it masked; "Show" reveals it. "Remove the code word" deletes it.
Using it:
- Turn on "Code word" in the car for an action type, under Rules per agent. Without a code word set, the sheet says "Set a code word in Settings › Approvals first."
- An agent server can also ask for the code word on an approval. Its card shows "Needs your code word". With no code word set, the car parks it: "That one needs your code word."
- On the car screen, Approve on that action asks "Your code word?". Snag listens once, on the device only.
- The right words, in order, approve it: "Approved." The wrong words or silence park it: "That's not it. Parked." There is no second try.
- Snag never says the word back, never shows it on the car screen and never sends it to the agent or its server.
- Face ID comes first: an approval that needs Face ID (by default every irreversible action, see Needs Face ID for) parks in the car, code word or not: "That one needs Face ID. Approve it on the phone."
- The agent has the last word: if its backend does not allow the action in the car, it parks ("Parked until you've stopped."). Agents on the Snag agent API never allow irreversible actions in the car.
See CarPlay for the whole car flow.
Passenger mode
While CarPlay is connected the phone shows "On the car screen" and nothing else to do. "I'm a passenger" ("Approve here, with Face ID") turns on passenger mode:
- The phone shows the app as usual, with a banner "I'm a passenger" / "Until CarPlay disconnects" and a "Stop" button.
- Approvals on the phone work as normal, Face ID included.
- On the car screen, Approve works by tap for anything but an irreversible action, which waits for Face ID on the phone.
- Private and Personal answers still ask "Say it out loud?". Passenger mode changes nothing there.
- It ends when CarPlay disconnects, or on Stop.
Finished jobs in the car
Settings > In the car > Speak finished jobs ("Only while Snag is on the car screen"). Off by default. When on, and Snag is on the car screen and not listening, Snag says "Ops's notes are ready." when a job finishes. The notes wait in Control.
Related
- Voice commands: phrases that run workflows.
- CarPlay: Control on the car screen.
- Bring your own stack: your own servers, endpoints and models.
- Snag agent API: for people building an agent Snag can talk to.
Next: Voice commands