Documentation
¶
Overview ¶
Package imbot provides a shared IM bot framework for connecting messaging platforms (Telegram, 企业微信, 飞书, Discord, etc.) to an OK Agent via ACP.
Architecture:
User ←→ IM Platform ←→ imbot.Adapter ←→ imbot.Core ←→ (ACP/stdio) ←→ ok acp
Each IM platform implements Adapter; Core handles ACP session lifecycle, message buffering, and permission approval — shared across all platforms.
Package imbot WebSocket support — adds WebSocket long-connection alongside HTTP webhook for real-time bidirectional communication with an OK Agent.
Architecture:
WebSocket client ←→ ws.ServeWS ←→ BotCore ←→ ACP subprocess
Each connected WebSocket client can submit prompts and receive streaming responses in real-time, independently of the IM platform webhook path.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ServeWS ¶
func ServeWS(bc *BotCore, w http.ResponseWriter, r *http.Request)
ServeWS handles a WebSocket connection, bridging it to the BotCore.
Protocol:
Client → Server:
{"type":"submit","input":"hello"}
{"type":"cancel"}
{"type":"new_session"}
Server → Client:
{"kind":"text","text":"Hello!"}
{"kind":"tool","name":"bash","args":"ls -la"}
{"kind":"done"}
{"kind":"error","err":"..."}
Types ¶
type ACPClient ¶
type ACPClient struct {
// contains filtered or unexported fields
}
ACPClient manages one ACP connection (one ok acp subprocess).
func NewACPClient ¶
NewACPClient spawns an `ok acp` subprocess and returns a connected client. okBin is the path to the ok binary; extraArgs are passed after "acp".
func (*ACPClient) OnNotification ¶
func (ac *ACPClient) OnNotification(method string, h func(json.RawMessage))
OnNotification registers a handler for ACP notifications (e.g. session/update).
func (*ACPClient) StartReader ¶
StartReader begins reading ACP responses in a background goroutine. Must be called before any requests. When ctx is cancelled, the underlying subprocess is killed so the read loop exits.
type ACPFrame ¶
type ACPFrame struct {
JSONRPC string `json:"jsonrpc"`
ID json.RawMessage `json:"id,omitempty"`
Method string `json:"method,omitempty"`
Params json.RawMessage `json:"params,omitempty"`
Result json.RawMessage `json:"result,omitempty"`
Error *struct {
Code int `json:"code"`
Message string `json:"message"`
} `json:"error,omitempty"`
}
ACPFrame is a JSON-RPC 2.0 frame on the wire.
type Adapter ¶
type Adapter interface {
// SendMessage sends a text message to a user.
SendMessage(ctx context.Context, userID, text string) error
// SendTyping shows a typing indicator (optional).
SendTyping(ctx context.Context, userID string)
// PlatformName returns a human-readable name (e.g. "telegram", "企业微信").
PlatformName() string
}
Adapter is the interface each IM platform implements.
type BotCore ¶
type BotCore struct {
Adapter Adapter
Sessions *SessionManager
OKBin string
OKModel string
WorkDir string
// contains filtered or unexported fields
}
BotCore ties together IM adapters, ACP sessions, and message handling.
func NewBotCore ¶
func (*BotCore) EnableWebSocket ¶
func (bc *BotCore) EnableWebSocket() *Broadcaster
EnableWebSocket creates a Broadcaster and stores it on BotCore for WebSocket support. The bot should mount ServeWS on a route (e.g. "/ws"). Returns the Broadcaster so the bot can emit custom events if needed.
func (*BotCore) GetOrCreateSession ¶
GetOrCreateSession returns an existing session or creates a new ACP session.
func (*BotCore) SendPrompt ¶
SendPrompt sends a user message to an ACP session.
type Broadcaster ¶
type Broadcaster struct {
// contains filtered or unexported fields
}
Broadcaster fans out ACP events to all connected WebSocket subscribers.
func NewBroadcaster ¶
func NewBroadcaster() *Broadcaster
NewBroadcaster returns an empty Broadcaster ready for subscribers.
func (*Broadcaster) Emit ¶
func (b *Broadcaster) Emit(e *wsEvent)
Emit marshals the event and delivers it to every subscriber. Drops to a subscriber whose buffer is full rather than blocking.
func (*Broadcaster) Subscribe ¶
func (b *Broadcaster) Subscribe() (<-chan []byte, func())
Subscribe registers a new WebSocket client and returns its channel plus an unsubscribe func the handler must call (defer) when the client disconnects.
type Session ¶
type Session struct {
ID string
Client *ACPClient
UserID string // platform-specific user/chat identifier
UserName string
Buf strings.Builder
InTurn bool
}
Session represents one ACP session bound to an IM user/chat.
type SessionManager ¶
type SessionManager struct {
// contains filtered or unexported fields
}
SessionManager tracks all active sessions.
func NewSessionManager ¶
func NewSessionManager() *SessionManager
func (*SessionManager) Add ¶
func (sm *SessionManager) Add(userID string, s *Session)
func (*SessionManager) Get ¶
func (sm *SessionManager) Get(userID string) *Session
func (*SessionManager) GetByACP ¶
func (sm *SessionManager) GetByACP(sessionID string) *Session
func (*SessionManager) Remove ¶
func (sm *SessionManager) Remove(userID string)
func (*SessionManager) ShutdownAll ¶
func (sm *SessionManager) ShutdownAll()