Sophon

Concepts

Sophon has a small vocabulary. Internalising these eight nouns now makes the rest of the docs read smoothly.

The mental model

   ┌─────────┐   SSE     ┌──────────────┐    WS+REST   ┌──────────┐
   │  iOS    │ ◀─────────│              │ ◀──────────▶ │  Bridge  │
   │  app    │           │ Sophon Cloud │              │          │
   │  (you)  │ ─────────▶│ api.sophon   │              │ (the     │
   └─────────┘  /v1/me   └──────────────┘  /v1/bridge  │  relay)  │
                                                       └────┬─────┘
                                                            │ stdio,
                                                            │ HTTP, WS
                                                       ┌────▼─────┐
                                                       │  Agent   │
                                                       │ (your    │
                                                       │  code)   │
                                                       └──────────┘

The phone never talks to your agent directly. It talks to Sophon Cloud. The cloud talks to the bridge you paired. The bridge talks to your agent.

Agent

The actual program doing the work. A Claude wrapper, a Python script, a shell pipeline, your own LLM call — it's whatever generates the reply. Lives on your machine. Sophon never sees it; we only see what your bridge forwards.

Bridge / Connector

The small relay that translates your agent into SAP. We use the two words almost interchangeably. OpenClaw (npx @sophonai/openclaw) is our reference bridge — it wraps a local OpenClaw gateway. If you want to bring something else, you write a custom connector against the protocol.

A bridge has exactly one job: hold a WebSocket open to Sophon Cloud, listen for session.message updates, and POST back the agent's reply.

Installation

One paired bridge on your account, identified by an ID like inst_q9w8e7r6t5y4u3i2. Each pairing creates one installation. You can have many — work Mac, home Mac, a VPS in Frankfurt, all under the same Google account. They show up as separate connections in iOS, distinguished by name and emoji.

When you "uninstall" or rotate a token, you're acting on the installation.

Session

A chat thread inside one installation. Visible in the iOS chat list. A session has an ID like ses_a1b2c3d4e5f6g7h8, a title, and a state (active, archived, or soft-deleted). Sessions are scoped to one installation — you can't move a chat from your work-Mac OpenClaw to your home-Mac OpenClaw.

Interaction

One user-message-then-agent-reply cycle inside a session. Each one has an interaction_id like int_p0o9i8u7y6t5r4e3. Every event the bridge emits during the cycle (message deltas, tool calls, approvals) carries that ID, so the iOS client can route deltas to the right bubble.

Interactions are how we resume after a network blip. If your phone drops mid-stream, it reconnects, the server replays the missing events on the same interaction_id, the bubble continues filling in.

Message

What you see in a bubble. Each has a message_id, a role (user or agent), and a text body. Messages stream as deltas during an interaction and finalise on message_end.

A user message also carries optional attachments (images, files). An agent message carries optional usage metadata (input/output tokens, model, estimated cost).

Tool call (Task)

One tool invocation by the agent. Identified by a task_id (often the underlying provider's call id, e.g. Anthropic's call_…). Lifecycle:

created  →  progress*  →  completed | failed | cancelled

iOS renders running tasks as a card in the bubble — collapsible, shows args + result. Multiple tasks in one interaction collapse into a "Ran 3 commands" row above the input.

Approval

Human-in-the-loop pause. The agent says "may I run this?", iOS shows an action sheet, you tap Allow / Allow always / Deny. The decision flows back to the bridge, which unblocks the agent.

Each approval has an approval_id, a severity, a command preview, and an expires_at (default 5 minutes). You can grant allow-always scoped to a session, a tool name, or a domain; later requests matching the same scope auto-resolve.


How they compose

A typical chat looks like this:

Installation:  inst_…       (one paired OpenClaw on your Mac)
  └ Session:   ses_…        ("Refactor the Sophon iOS adapter")
      ├ Interaction int_a   ("rewrite the tool-rendering")
      │   ├ Message msg_a   (user, "rewrite ToolGroupView")
      │   └ Message msg_b   (agent, streamed reply, finalises)
      │       ├ Task task_1 (read_file ToolGroupView.swift)
      │       └ Task task_2 (write_file ToolGroupView.swift)
      │           └ Approval apr_1 (severity=high, allow-once)
      └ Interaction int_b   ("now run the tests")
          └ …

A reasonable place to read next:

  • Quickstart — pair OpenClaw and watch this hierarchy materialise in iOS.
  • Protocol overview — the wire-level perspective on the same model.
  • Glossary — alphabetical lookup if you forget what one of these meant.