FrostAgent ships a built-in OneBot v11 WebSocket server that acts as a reverse adapter. Instead of FrostAgent dialing out to your bot client, your OneBot-compatible client (go-cqhttp, Lagrange, NapCat, and so on) establishes a connection inward to FrostAgent’s WebSocket endpoint. Once connected, events flow from the client to FrostAgent, and FrostAgent sends back OneBot actions — including rich message chains with text, @-mentions, images, voice, and file segments.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/GuaiZai233/FrostAgent/llms.txt
Use this file to discover all available pages before exploring further.
How It Works
FrostAgent listens for incoming WebSocket connections and processes each OneBot event as it arrives. The flow from connection to reply is straightforward:Client connects
Your OneBot client opens a WebSocket connection to FrostAgent at
ws://<host>:1234/ws/frostagent. The listen address is controlled by WS_LISTEN_ADDR and defaults to 0.0.0.0:1234.Event received
FrostAgent’s
HandleWS handler reads the raw JSON frame and deserialises it into an OneBotEvent. Heartbeat meta-events (meta_event_type: "heartbeat") are silently discarded.Event dispatched
Each non-heartbeat event is handed off to
processEvent in its own goroutine so that one slow LLM call never blocks another incoming message.LLM called and reply sent
FrostAgent extracts user text, enriches it with any image descriptions (see Vision), builds a session-aware prompt, calls the LLM engine, and writes the resulting
OneBotAction back over the same WebSocket connection.Configuration
The adapter is driven entirely by environment variables. Set them in your.env file at the project root.
| Variable | Default | Description |
|---|---|---|
WS_LISTEN_ADDR | 0.0.0.0:1234 | Host and port for the OneBot WebSocket server. |
WS_ALLOWED_ORIGINS | (empty) | Comma-separated list of trusted browser Origins (e.g. https://bot.example.com). Non-browser clients that omit the Origin header are always permitted. |
ENABLE_AT_IN_GROUP_MSG | true | When true, FrostAgent prepends an at segment (@ mention) to plain-text group replies. |
.env snippet for the OneBot adapter:
Message Handling
HandleWS is the HTTP handler registered at /ws/frostagent. After upgrading the connection it reads frames in a loop and calls processEvent for each valid event:
- Group messages — processed only when the bot is @-mentioned.
IsMentionedBotwalks everyatsegment in the event and compares theqqfield against the bot’s ownself_id. Because different OneBot implementations encode the QQ number as a string, a float64, or ajson.Number, FrostAgent normalises all three variants before comparing. - Private messages — always processed; no mention check is required.
historyKey:
Supported Incoming Message Segments
extractUserText converts the raw OneBot message array into a plain-text string that is passed to the LLM. Every standard OneBot v11 segment type is handled:
| Segment type | Representation passed to LLM |
|---|---|
text | Literal text content |
at | [@<qq>] |
face | [表情:<id>] |
image | [图片] (image is separately described by the vision model) |
record | [语音] |
video | [视频] |
file | [文件:<name>] |
reply | [回复:<id>] |
location | [位置:<lat>,<lon> <title>] |
json / xml | [json:<data>] / [xml:<data>] |
| (unknown) | Raw JSON of the segment object |
When a message contains an
image segment, FrostAgent automatically calls the vision model and appends a Chinese-language description (【图片内容】: <description>) to the user text before sending it to the main LLM. See Vision for details.Outgoing Message Segments
When the LLM invokes thesend_message tool, BuildOneBotMessage translates the tool’s abstract message types into a concrete OneBot v11 segment chain:
send_message type | OneBot segment | Key field |
|---|---|---|
plain | text | data.text — the text content |
mention_user | at | data.qq — the target user’s QQ number |
quote | reply | data.id — the message ID to quote |
image | image | data.file — URL or file://<path> |
record | record | data.file — URL or file://<path> |
video | video | data.file — URL or file://<path> |
file | file | data.file — URL or file://<path> |
url field takes precedence. If only a local path is supplied, FrostAgent prefixes it with file:// automatically.
A send_message call can mix multiple types in a single array to build rich composite messages — for example, a quote followed by a mention_user followed by plain text.
Concurrency
ThewsConnection struct wraps gorilla/websocket.Conn with a sync.Mutex on all write operations:
go processEvent(...), so multiple messages can be processed concurrently. The write mutex ensures that concurrent goroutines never interleave their WebSocket frames on the shared connection.
Origin Security
WS_ALLOWED_ORIGINS controls which browser-originated WebSocket connections are accepted. The check logic follows these rules in order:
- No
Originheader — the connection is always allowed. Most OneBot client implementations (go-cqhttp, Lagrange, NapCat) do not send this header. Originhost matches the server’s own host — allowed.Origin(full URL or host only) is inWS_ALLOWED_ORIGINS— allowed.- Any other origin — rejected with an error log entry.