@inline-openclaw/inline
v0.0.54
Published
OpenClaw channel plugin for interacting with an OpenClaw agent via **Inline**.
Readme
@inline-openclaw/inline
OpenClaw channel plugin for interacting with an OpenClaw agent via Inline.
Status: beta (solid foundation; expect iteration).
Quick setup guide: docs/openclaw-setup.md.
Create bot/token guide: docs/create-inline-bot.md.
Supports:
- Inline DMs (
ChatType=direct) - Inline chats as conversations (
ChatType=group) - Message replies: OpenClaw
replyToIdis mapped to InlinereplyToMsgId(message id). - Inline reply threads: tools can create and reply in real Inline reply-thread chats.
- Inline media upload/send for images, videos, and documents from
mediaUrlpayloads. - Native-style file upload action via
upload-file. - Native-style file download action via
download-file. - Inline message forwarding via
forward/forwardMessagesmessage tool actions. - Inline compose indicators via
typing,stop-typing, upload-state actions, andrecording-voice. - Emoji reactions via message tool actions (
react,reactions). - Reaction events on bot-authored messages are surfaced back to the agent as inbound context.
Reply-thread behavior:
- Small/new parent-chat conversations stay in the parent chat by default.
replyThreadMode: "auto"also creates a child reply thread when the triggering parent-chat message explicitly asks OpenClaw to reply in a thread.replyThreadMode: "thread"opts a parent chat into automatic reply-thread delivery oncereplyThreadAutoCreateMinMessagesis reached; each triggering parent-chat message gets its own child reply thread.replyThreadMode: "main"keeps automatic replies in the parent chat, while explicitthread-createandthread-replytools remain available.thread-createcreates a top-level Inline thread when called with participants orspaceId, and creates a real Inline reply thread when called with a parent chat target or anchor.thread-replysends into the child reply-thread chat id returned by reply-thread creation.- Inbound reply-thread messages use the parent chat as the base conversation target and the child reply-thread chat id as
MessageThreadId. - Bot-participated reply threads and followed fresh Inline threads can continue without an explicit bot mention by default, matching Slack-style thread behavior.
Install
Requires OpenClaw 2026.6.11 or newer.
Compatibility
| Plugin version | OpenClaw host | Inline realtime SDK | Status | Notes |
| --- | --- | --- | --- | --- |
| 0.0.54 | >=2026.6.11 | 0.0.13 | Current | Keeps recovered WebSocket and best-effort cursor warnings out of healthy channel status. |
| 0.0.53 | >=2026.6.11 | 0.0.13 | Stable | Clears recovered Inline WebSocket errors from channel status after reconnect. |
| 0.0.52 | >=2026.6.11 | 0.0.13 | Stable | Patch release for the SDK protocol dependency. |
| 0.0.51 | >=2026.6.11 | 0.0.12 | Stable | Added follow-mode mention gating for eligible reply/fresh Inline threads. |
| 0.0.50 | >=2026.6.11 | 0.0.11 | Stable | Supported line for current stable OpenClaw. Uses focused plugin SDK entrypoints and canonical ClawHub install metadata. |
From npm:
openclaw plugins install @inline-openclaw/inlineIf the plugin is already installed, update in place:
openclaw config set plugins.installs.inline.spec '"@inline-openclaw/inline@latest"'
openclaw plugins update inline
openclaw gateway restart
openclaw plugins list
openclaw channels status
openclaw message send --channel inline --target chat:123 --message "Inline smoke test" --dry-runAfter updating, verify that openclaw plugins list shows inline, openclaw channels status reports Inline configured/running, and openclaw plugins inspect inline --json reports the expected package version.
From a local checkout (dev):
cd /path/to/inline/openclaw
bun run build
npm pack --ignore-scripts --pack-destination /tmp
openclaw plugins install --force npm-pack:/tmp/inline-openclaw-inline-<version>.tgzConfigure
Channel config lives under channels.inline (supports account settings, block streaming/chunking, and group tool policy).
Plugin id is inline (for plugins.entries.*).
If you enable explicitly, use:
plugins:
entries:
inline:
enabled: trueMinimal setup (token field only):
channels:
inline:
enabled: true
token: "<INLINE_BOT_TOKEN>"You can also leave token unset and provide INLINE_TOKEN in the gateway environment.
INLINE_BOT_TOKEN is accepted as a compatibility alias.
baseUrl defaults to https://api.inline.chat.
dmPolicy defaults to pairing (recommended starting point).
defaultTo is optional and gives outbound sends a fallback target when no explicit target is supplied.
requireMention defaults to false for groups (set true to require explicit mentions).
Who can talk to the bot?
Use these settings together:
| Area | Setting | Meaning |
| --- | --- | --- |
| DMs | dmPolicy: "pairing" | Users can request access; allowlisted users are accepted. This is the default. |
| DMs | dmPolicy: "allowlist" + allowFrom | Only listed Inline user ids can DM the bot. |
| DMs | dmPolicy: "open" + allowFrom: ["*"] | Any Inline user can DM the bot. Use only for public/demo bots. |
| DMs | dmPolicy: "disabled" | DM messages are ignored. |
| Groups | groupPolicy: "allowlist" + groups | Only listed group chat ids can reach the bot. Setup defaults groups["*"].requireMention to true for broad mention-only access. |
| Groups | groupPolicy: "open" | Any group chat can reach the bot. Pair with requireMention: true unless the bot should answer ambient messages. |
| Groups | groupPolicy: "disabled" | Group messages are ignored. |
| Group senders | groupAllowFrom or groups.<chat>.allowFrom | Optional sender allowlist inside allowed groups. Per-group entries override the account-wide list for that group. Leave empty to allow any sender in an allowed group. |
Accepted Inline user ids: 123, user:123, inline:123, or inline:user:123.
Accepted group ids: 123, chat:123, inline:123, or *.
Example:
channels:
inline:
enabled: true
baseUrl: "https://api.inline.chat"
token: "<INLINE_BOT_TOKEN>"
defaultTo: "chat:123" # optional fallback for outbound sends without --target
# DMs:
dmPolicy: "pairing" # pairing|allowlist|open|disabled
allowFrom:
- "inline:123" # or "user:123" or just "123"
# Native exec/plugin approvals:
execApprovals:
enabled: "auto" # auto|true|false
approvers:
- "user:123" # Inline user ids only; chat ids are not approvers
target: "dm" # dm|channel|both
# Group threads/chats:
groupPolicy: "allowlist" # allowlist|open|disabled
groupAllowFrom:
- "inline:123" # or "user:123" or just "123"
requireMention: true # optional: default is false
replyToBotWithoutMention: true # if true, replies to bot messages can bypass mention requirement
replyThreadMode: "auto" # auto|thread|main; thread auto-routes long parent-chat replies into per-message reply threads
replyThreadAutoCreateMinMessages: 50 # optional, default 50; avoids creating reply threads for small/new chats
replyThreadRequireExplicitMention: false # optional, default false; bot-participated reply threads continue without @mention
replyThreadParentHistoryLimit: 10 # optional, default 10; set 0 to disable parent-chat context before the anchor
# Inbound context history (used to build richer thread context for the agent):
historyLimit: 50 # group chats
dmHistoryLimit: 6 # direct messages
# Streaming + chunking:
mediaMaxMb: 20
debounceMs: 1200 # optional: coalesce rapid same-sender Inline messages; global alternative: messages.inbound.byChannel.inline
voiceTranscriptWaitMs: 8000 # wait for Inline's voice auto-transcript edit before falling back to audio STT; set 0 to disable
blockStreaming: true
streamViaEditMessage: true # optional: paragraph-level text streaming via send+edit fallback; off by default
chunkMode: "newline" # length|newline
blockStreamingCoalesce:
minChars: 600
idleMs: 700
maxChars: 2200
# Group-level tool policy (for agent tool access in group sessions):
groups:
"88":
requireMention: false
replyThreadRequireExplicitMention: true
replyThreadParentHistoryLimit: 2
allowFrom:
- "42"
tools:
allow: ["message", "web.search"]
toolsBySender:
"42":
allow: ["message"]Per-account override:
channels:
inline:
accounts:
work:
token: "<INLINE_BOT_TOKEN>"
defaultTo: "user:123"
replyThreadMode: "main"Reply behavior summary:
replyToIdis always an Inline message id.- Inline reply threads are separate and use OpenClaw
threadId. - Use
replyThreadMode: "main"if you only want automatic parent-chat replies to stay in the parent chat. - Use
replyThreadMode: "thread"plusreplyThreadAutoCreateMinMessageswhen parent-chat bot turns should move into child reply threads anchored to the triggering parent messages. - In an Inline group, authorized users can run
/threadreplyto choose the chat's mode with buttons, or/threadreply thread|main|auto|inherit|status. - Bot-participated reply threads and followed fresh Inline threads continue without
@botby default. Reply threads also use persisted recent participation state as a fallback. SetreplyThreadRequireExplicitMention: trueif a chat should require@boton every reply-thread message. replyThreadParentHistoryLimitdefaults to10, so reply-thread turns include nearby parent-chat context before the anchor. Set it to0only when a chat should stay strictly thread-local.
If you set dmPolicy: "open", set allowFrom: ["*"].
Native Exec Approvals
Inline supports the same native approval flow as bundled chat providers. Configure channels.inline.execApprovals.approvers with Inline user ids, or leave it unset and use numeric IDs in commands.ownerAllowFrom. Accepted approver ids are 123, user:123, inline:123, or inline:user:123; chat:<id> entries are ignored because group chats are not approvers.
execApprovals.target defaults to dm. Use channel or both only for trusted chats because approval messages include command details. Inline approval buttons send /approve ... callbacks, and OpenClaw clears the buttons after resolution or expiry.
Outbound Target Semantics
For message send/plugin outbound sends:
- Use
openclaw message send --channel inline --target chat:<id> --message "...". - If
channels.inline.defaultTois set, OpenClaw uses it when no explicit target is supplied. Named accounts can override it withchannels.inline.accounts.<account>.defaultTo. - Some OpenClaw CLI help text lists only built-in channel ids, but installed plugin channel ids such as
inlineare accepted. chat:<id>targets a chat id.user:<id>targets a user id (DM peer).inline:user:<id>andinline:chat:<id>are accepted and normalized.- User directory IDs and
channels resolve --kind useroutputs are returned asuser:<id>to keep DM targets explicit. - Bare numeric ids are disambiguated against Inline directory data:
- matches chat only -> sent as chat id
- matches user only -> sent as user id
- matches both -> rejected (use explicit
chat:oruser:) - matches neither -> treated as chat id (legacy behavior)
Message Tool RPC Actions
The plugin exposes Inline RPC-backed actions through OpenClaw's message tool.
Most Inline RPC-backed actions use a numeric chat id via to, chatId, or channelId.
Direct DM sends can also target user:<id>.
- Sending:
send,sendAttachment,upload-file,forward,forwardMessages - Replying:
reply,thread-reply - Reactions:
react,reactions - Reading/searching/translating:
read,get-messages,getMessages,download-file,bot-commands,botCommands,peer-bot-commands,peerBotCommands,search,translate,translateMessages - Editing:
edit - Channels/threads:
channel-info,channel-edit,renameGroup,channel-list,channel-create,channel-delete,channel-move,thread-list,thread-create - Participants:
addParticipant,removeParticipant,kick,leaveGroup,member-info,invite-to-space,inviteToSpace - Message lifecycle:
delete,unsend,delete-attachment,deleteMessageAttachment - Message pins:
pin,unpin,list-pins - Space permissions:
permissions
Inline reply-thread semantics:
readsupports latest reads plusbefore/offsetIdfor older history,afterfor newer history, andmessageId/anchorIdfor around-window reads. In reply-thread turns it defaults to the current reply-thread chat whento/chatId/threadIdis omitted.get-messages/getMessagesfetches exact message ids from a target chat/user/reply thread and returns the same media-aware payloads asread/search.download-filedownloads Inline message media or URL-preview images to a local temp path. PassmediaUrl/urldirectly, or passmessageIdwith optionalmediaId/attachmentId; inside an Inline turn it defaults to the current chat/thread and current message.peer-bot-commands/bot-commandsreads Inline bot commands available in a target chat/user/reply thread. In reply-thread turns it can inspect inherited parent-chat bot commands.channel-editcan rename (title/name/threadName), updateemoji, and change space-thread visibility withisPublicorvisibility: "public"|"private". Private visibility changes requireparticipant/participants.upload-fileis the native OpenClaw alias forsendAttachment; usefilePath,path,media,mediaUrl, orurlfor the file/media source.- Inline
buttonsrows supportcallback_datafor callbacks andcopy_text/copyTextfor client-side copy buttons. JSONcallback_datacan includecallbackToastortoastfor an immediate short acknowledgement when pressed. thread-replyexpectsthreadIdto be the child reply-thread chat id, whiletostays the parent chat id.- If
threadIdis missing,thread-replycan use the current reply-thread context or a saved route fromthread-createwhen called with the parent chat target plusparentMessageId. thread-createcreates a top-level Inline thread when called without a parent target. Useparticipant/participantsfor a private thread, orspaceIdwithisPublic: truefor a public space thread. IfspaceIdis present and no participants are supplied, Inline defaultsthread-createto a public space thread.thread-createcreates a real reply thread from a parent chat whento/chatId/channelIdis supplied, or when an explicitreplyToId/messageIdanchor can be paired with the current channel context.forward/forwardMessagesforwards one or more sourcemessageId/messageIdsto a destinationto/chatId/userId. The source can befrom/source/fromChatId/fromUserId; when omitted in an Inline conversation, it defaults to the current chat.delete-attachmentremoves a URL-preview attachment from a message authored by the current bot/user. Useattachments[].idfromreadorsearchasattachmentId.pin/unpinusemessageIdand default to the current Inline chat/thread when no target is passed;list-pinsalso defaults to the current chat/thread.invite-to-spaceinvites one user per call into a space usinguserId/user/participant,email, orphoneNumber; passrole: "admin"for admin invites or omit it for a member invite.- In
replyThreadMode: "auto", explicit user requests such as "reply in a thread" create and answer in a child reply thread automatically; thethread-createandthread-replymessage-tool actions remain available for manual tool use. - Automatic thread creation falls back to parent-chat delivery if the reply thread cannot be created.
- Existing route state is reused only for the same parent-message anchor. New parent-chat messages get separate reply threads; messages already inside a reply thread stay in that thread and do not create nested threads.
- Inline current-message media is attached like native channels. Reply-thread anchor media is summarized as context and is not promoted to current-message media on every child-thread turn.
You can gate action groups from config:
channels:
inline:
reactionNotifications: own # off | own | all | allowlist
reactionAllowlist:
- "inline:123"
actions:
send: true
reply: true
reactions: true
read: true
search: true
translate: true
edit: true
channels: true
participants: true
delete: true
pins: true
permissions: trueNamed accounts can override the same reactionNotifications mode and reactionAllowlist.
Extra Agent Tools
The plugin also registers dedicated tools outside the message action surface.
inline_parent_context fetches more parent-chat history for the current Inline reply-thread session when the automatic context window is not enough.
- Defaults to the current reply thread when invoked from one
- Optional inputs:
threadId,parentChatId,parentMessageId,beforeMessageId,afterMessageId,messageId/aroundMessageId,mode,limit,beforeLimit,afterLimit,includeAnchor,accountId - Supports
latest,older,newer, andaroundhistory windows; the reply-thread default is anaroundwindow anchored to the parent/root message - Returned messages are ordered oldest to newest and include media/entity summaries
inline_members handles space-member discovery:
- Optional input:
spaceId/space; when omitted inside an Inline space chat or reply thread, the plugin infers the current space - Optional filters:
query,userId,limit,accountId - Returned members include explicit DM targets like
user:123
inline_nudge sends an Inline nudge to a chat or user target.
inline_forward forwards existing Inline message ids between chats or users.
inline_bot_presence updates the bot's on-screen body state in Inline without sending a chat message. Use action: "get" to inspect the current avatar/state for a chat or user target.
inline_update_profile updates the authenticated bot's Inline display name and/or profile photo. Use it only for explicit profile-setup requests.
inline_bot_avatar installs, replaces, or clears the bot's on-screen avatar. Set/install uses a local or remote .zip avatar package; clearing uses action: "clear" or clear: true. It is for avatar setup/removal, not mood or presence changes.
The plugin also registers inline_bot_commands for Inline bot command management (v1):
action: "get"-> callsgetMyCommandsaction: "set"-> callssetMyCommandswith Inline Bot APIcommands[]action: "delete"-> callsdeleteMyCommands- Limits follow Inline Bot API: max
100commands,commandmax32,descriptionmax256, charset^[a-z0-9_]+$
Bot command sync:
- On
gateway_start, the plugin registers default bot commands for each enabled/configured Inline account. - Default commands include the same user-facing command set as bundled chat providers (for example:
/status,/model,/exec,/usage, etc.). - Inline also registers
/threadreplyto manage this group's reply-thread mode from chat. - The plugin uses OpenClaw's command, skill command, and plugin command registries when available.
- If Inline rejects the full 100-command menu as
BOT_COMMANDS_TOO_MUCH, startup sync retries with a smaller command set and logs how many entries were omitted. - Disable startup sync globally with
commands.native: false, or per-channel withchannels.inline.commands.native: false. Disabled startup sync clears existing Inline bot commands for the affected account. - Disable skill command inclusion with
commands.nativeSkills: false, or per-channel withchannels.inline.commands.nativeSkills: false.
Multi-account:
channels:
inline:
accounts:
default:
baseUrl: "https://api.inline.chat"
token: "<BOT_TOKEN_A>"
work:
baseUrl: "https://api.inline.chat"
token: "<BOT_TOKEN_B>"Quick Troubleshooting
plugin not found: inline/plugins.entries.inline: plugin not found: inline- Ensure the plugin is installed and discovered (
openclaw plugins list).
- Ensure the plugin is installed and discovered (
doctor --fixsuggests Inline changes even though channel is healthy- Keep the plugin entry id as
inline, then re-runopenclaw plugins listandopenclaw channels status.
- Keep the plugin entry id as
Inline: SETUP / no token- Ensure
channels.inline.token,INLINE_TOKEN, orINLINE_BOT_TOKENis set and plugin is updated (openclaw plugins update inline). - If using
dmPolicy: "open", ensureallowFrom: ["*"].
- Ensure
