mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:30:42 +00:00
docs(concepts): typography hygiene + Related CardGroups across 3 pages
docs/concepts/presence.md: replaced 8 curly quote and non-breaking hyphen characters (U+201C/U+201D/U+2019/U+2011) with ASCII equivalents so grep, copy-paste, and Mintlify search hit the right tokens. Converted the 2-bullet Related list into a CardGroup adding cross-links to gateway architecture and gateway protocol since presence is produced by both surfaces. docs/concepts/markdown-formatting.md: replaced 5 typography characters (en-dash and curly quotes) with ASCII equivalents and converted the 2-bullet Related list into a CardGroup pointing at streaming/chunking and system prompt. docs/concepts/typing-indicators.md: replaced 4 typography characters with ASCII equivalents and converted the 2-bullet Related list into a CardGroup with the same Presence and Streaming cross-links. Verified /concepts/streaming, /concepts/system-prompt, /concepts/architecture, and /gateway/protocol targets all exist.
This commit is contained in:
@@ -39,14 +39,14 @@ stay consistent across channels.
|
||||
Input Markdown:
|
||||
|
||||
```markdown
|
||||
Hello **world** — see [docs](https://docs.openclaw.ai).
|
||||
Hello **world** - see [docs](https://docs.openclaw.ai).
|
||||
```
|
||||
|
||||
IR (schematic):
|
||||
|
||||
```json
|
||||
{
|
||||
"text": "Hello world — see docs.",
|
||||
"text": "Hello world - see docs.",
|
||||
"styles": [{ "start": 6, "end": 11, "style": "bold" }],
|
||||
"links": [{ "start": 19, "end": 23, "href": "https://docs.openclaw.ai" }]
|
||||
}
|
||||
@@ -129,5 +129,11 @@ SPOILER style ranges. Other channels treat them as plain text.
|
||||
|
||||
## Related
|
||||
|
||||
- [Streaming and chunking](/concepts/streaming)
|
||||
- [System prompt](/concepts/system-prompt)
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Streaming and chunking" href="/concepts/streaming" icon="bars-staggered">
|
||||
Outbound streaming behavior, chunk boundaries, and channel-specific delivery.
|
||||
</Card>
|
||||
<Card title="System prompt" href="/concepts/system-prompt" icon="message-lines">
|
||||
What the model sees before the conversation, including injected workspace files.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -7,12 +7,12 @@ read_when:
|
||||
title: "Presence"
|
||||
---
|
||||
|
||||
OpenClaw “presence” is a lightweight, best‑effort view of:
|
||||
OpenClaw "presence" is a lightweight, best-effort view of:
|
||||
|
||||
- the **Gateway** itself, and
|
||||
- **clients connected to the Gateway** (mac app, WebChat, CLI, etc.)
|
||||
|
||||
Presence is used primarily to render the macOS app’s **Instances** tab and to
|
||||
Presence is used primarily to render the macOS app's **Instances** tab and to
|
||||
provide quick operator visibility.
|
||||
|
||||
## Presence fields (what shows up)
|
||||
@@ -20,12 +20,12 @@ provide quick operator visibility.
|
||||
Presence entries are structured objects with fields like:
|
||||
|
||||
- `instanceId` (optional but strongly recommended): stable client identity (usually `connect.client.instanceId`)
|
||||
- `host`: human‑friendly host name
|
||||
- `ip`: best‑effort IP address
|
||||
- `host`: human-friendly host name
|
||||
- `ip`: best-effort IP address
|
||||
- `version`: client version string
|
||||
- `deviceFamily` / `modelIdentifier`: hardware hints
|
||||
- `mode`: `ui`, `webchat`, `cli`, `backend`, `probe`, `test`, `node`, ...
|
||||
- `lastInputSeconds`: “seconds since last user input” (if known)
|
||||
- `lastInputSeconds`: "seconds since last user input" (if known)
|
||||
- `reason`: `self`, `connect`, `node-connected`, `periodic`, ...
|
||||
- `ts`: last update timestamp (ms since epoch)
|
||||
|
||||
@@ -35,7 +35,7 @@ Presence entries are produced by multiple sources and **merged**.
|
||||
|
||||
### 1) Gateway self entry
|
||||
|
||||
The Gateway always seeds a “self” entry at startup so UIs show the gateway host
|
||||
The Gateway always seeds a "self" entry at startup so UIs show the gateway host
|
||||
even before any clients connect.
|
||||
|
||||
### 2) WebSocket connect
|
||||
@@ -45,7 +45,7 @@ Gateway upserts a presence entry for that connection.
|
||||
|
||||
#### Why one-off CLI commands do not show up
|
||||
|
||||
The CLI often connects for short, one‑off commands. To avoid spamming the
|
||||
The CLI often connects for short, one-off commands. To avoid spamming the
|
||||
Instances list, `client.mode === "cli"` is **not** turned into a presence entry.
|
||||
|
||||
### 3) `system-event` beacons
|
||||
@@ -60,11 +60,11 @@ upserts a presence entry for that node (same flow as other WS clients).
|
||||
|
||||
## Merge + dedupe rules (why `instanceId` matters)
|
||||
|
||||
Presence entries are stored in a single in‑memory map:
|
||||
Presence entries are stored in a single in-memory map:
|
||||
|
||||
- Entries are keyed by a **presence key**.
|
||||
- The best key is a stable `instanceId` (from `connect.client.instanceId`) that survives restarts.
|
||||
- Keys are case‑insensitive.
|
||||
- Keys are case-insensitive.
|
||||
|
||||
If a client reconnects without a stable `instanceId`, it may show up as a
|
||||
**duplicate** row.
|
||||
@@ -81,7 +81,7 @@ This keeps the list fresh and avoids unbounded memory growth.
|
||||
## Remote/tunnel caveat (loopback IPs)
|
||||
|
||||
When a client connects over an SSH tunnel / local port forward, the Gateway may
|
||||
see the remote address as `127.0.0.1`. To avoid overwriting a good client‑reported
|
||||
see the remote address as `127.0.0.1`. To avoid overwriting a good client-reported
|
||||
IP, loopback remote addresses are ignored.
|
||||
|
||||
## Consumers
|
||||
@@ -97,9 +97,21 @@ indicator (Active/Idle/Stale) based on the age of the last update.
|
||||
- If you see duplicates:
|
||||
- confirm clients send a stable `client.instanceId` in the handshake
|
||||
- confirm periodic beacons use the same `instanceId`
|
||||
- check whether the connection‑derived entry is missing `instanceId` (duplicates are expected)
|
||||
- check whether the connection-derived entry is missing `instanceId` (duplicates are expected)
|
||||
|
||||
## Related
|
||||
|
||||
- [Typing indicators](/concepts/typing-indicators)
|
||||
- [Streaming and chunking](/concepts/streaming)
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Typing indicators" href="/concepts/typing-indicators" icon="ellipsis">
|
||||
When typing indicators are sent and how to tune them.
|
||||
</Card>
|
||||
<Card title="Streaming and chunking" href="/concepts/streaming" icon="bars-staggered">
|
||||
Outbound streaming, chunking, and per-channel formatting.
|
||||
</Card>
|
||||
<Card title="Gateway architecture" href="/concepts/architecture" icon="diagram-project">
|
||||
Gateway components and the WebSocket protocol that drives presence updates.
|
||||
</Card>
|
||||
<Card title="Gateway protocol" href="/gateway/protocol" icon="plug">
|
||||
The wire protocol for `connect`, `system-event`, and `system-presence`.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -23,15 +23,15 @@ When `agents.defaults.typingMode` is **unset**, OpenClaw keeps the legacy behavi
|
||||
|
||||
Set `agents.defaults.typingMode` to one of:
|
||||
|
||||
- `never` — no typing indicator, ever.
|
||||
- `instant` — start typing **as soon as the model loop begins**, even if the run
|
||||
- `never` - no typing indicator, ever.
|
||||
- `instant` - start typing **as soon as the model loop begins**, even if the run
|
||||
later returns only the silent reply token.
|
||||
- `thinking` — start typing on the **first reasoning delta** (requires
|
||||
- `thinking` - start typing on the **first reasoning delta** (requires
|
||||
`reasoningLevel: "stream"` for the run).
|
||||
- `message` — start typing on the **first non-silent text delta** (ignores
|
||||
- `message` - start typing on the **first non-silent text delta** (ignores
|
||||
the `NO_REPLY` silent token).
|
||||
|
||||
Order of “how early it fires”:
|
||||
Order of "how early it fires":
|
||||
`never` → `message` → `thinking` → `instant`
|
||||
|
||||
## Configuration
|
||||
@@ -58,11 +58,11 @@ You can override mode or cadence per session:
|
||||
|
||||
## Notes
|
||||
|
||||
- `message` mode won’t show typing for silent-only replies when the whole
|
||||
- `message` mode won't show typing for silent-only replies when the whole
|
||||
payload is the exact silent token (for example `NO_REPLY` / `no_reply`,
|
||||
matched case-insensitively).
|
||||
- `thinking` only fires if the run streams reasoning (`reasoningLevel: "stream"`).
|
||||
If the model doesn’t emit reasoning deltas, typing won’t start.
|
||||
If the model doesn't emit reasoning deltas, typing won't start.
|
||||
- Heartbeat typing is a liveness signal for the resolved delivery target. It
|
||||
starts at heartbeat run start instead of following `message` or `thinking`
|
||||
stream timing. Set `typingMode: "never"` to disable it.
|
||||
@@ -74,5 +74,11 @@ You can override mode or cadence per session:
|
||||
|
||||
## Related
|
||||
|
||||
- [Presence](/concepts/presence)
|
||||
- [Streaming and chunking](/concepts/streaming)
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Presence" href="/concepts/presence" icon="signal">
|
||||
How the Gateway tracks connected clients and surfaces them in the macOS Instances tab.
|
||||
</Card>
|
||||
<Card title="Streaming and chunking" href="/concepts/streaming" icon="bars-staggered">
|
||||
Outbound streaming behavior, chunk boundaries, and channel-specific delivery.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
Reference in New Issue
Block a user