agentremote

package module
v0.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 26, 2026 License: MIT Imports: 34 Imported by: 0

README

AgentRemote

AgentRemote securely brings agents to Beeper. You can connect agents like OpenClaw, OpenCode, Codex and more to Beeper with streaming, native interfaces for tool calls and approvals. You can run coding agents on your laptop and use your iPhone to manage them.

AgentRemote can run on the same device as your agent and can work behind a firewall. It connects to Beeper Cloud directly and creates an E2EE tunnel.

**This repository is still experimental. Expect everything to be broken for now. **

Install

Install the latest release:

curl -fsSL https://raw.githubusercontent.com/beeper/agentremote/main/install.sh | sh

Other supported install paths:

  • Download a release archive from GitHub Releases
  • Install via Homebrew: brew install --cask beeper/tap/agentremote

The installed CLI stores profile state under ~/.config/agentremote/.

Included bridges

Bridge What it connects
ai Talk to any model on Beeper
codex A local codex app-server runtime, requires Codex to be installed
opencode A remote OpenCode server or a bridge-managed local OpenCode process
openclaw Connect directly to OpenClaw Gateway, bring all your sessions to one app

Quick start

agentremote login
agentremote list
agentremote run codex

Useful commands:

  • agentremote up <bridge> starts a bridge in the background
  • agentremote status shows local and remote bridge state
  • agentremote logs <instance> --follow tails logs
  • agentremote stop <instance> stops a running instance

Instance state lives under ~/.config/agentremote/profiles/<profile>/instances/.

Docker

The CLI is also published as a multi-arch Linux container image:

docker run --rm -it \
  -v "$(pwd):/data" \
  ghcr.io/beeper/agentremote:latest help

The container sets HOME=/data, so mounted state is persisted under /data/.config/agentremote/. See docker/agentremote/README.md for usage details.

SDK

Custom bridges in this repo are built on sdk/, using:

  • bridgesdk.NewStandardConnectorConfig(...)
  • bridgesdk.NewConnectorBase(...)
  • sdk.Config, sdk.Agent, sdk.Conversation, and sdk.Turn

See bridges/dummybridge for a minimal bridge example.

Docs

Documentation

Index

Constants

View Source
const (
	ApprovalReasonAllowOnce     = "allow_once"
	ApprovalReasonAllowAlways   = "allow_always"
	ApprovalReasonAutoApproved  = "auto_approved"
	ApprovalReasonDeny          = "deny"
	ApprovalReasonTimeout       = "timeout"
	ApprovalReasonExpired       = "expired"
	ApprovalReasonCancelled     = "cancelled"
	ApprovalReasonDeliveryError = "delivery_error"
)

Approval decision reason constants.

View Source
const (
	ApprovalPromptStateRequested = "approval-requested"
	ApprovalPromptStateResponded = "approval-responded"

	ApprovalReactionKeyAllowOnce   = "approval.allow_once"
	ApprovalReactionKeyAllowAlways = "approval.allow_always"
	ApprovalReactionKeyDeny        = "approval.deny"

	ApprovalReactionAliasAllowOnce   = "👍"
	ApprovalReactionAliasAllowAlways = "♾️"
	ApprovalReactionAliasDeny        = "👎"

	RejectReasonOwnerOnly     = "only_owner"
	RejectReasonExpired       = "expired"
	RejectReasonInvalidOption = "invalid_option"
)
View Source
const AIRoomKindAgent = "agent"
View Source
const DefaultApprovalExpiry = 10 * time.Minute

DefaultApprovalExpiry is the fallback expiry duration when no TTL is specified.

Variables

View Source
var (
	ErrApprovalMissingID      = errors.New("missing approval id")
	ErrApprovalMissingRoom    = errors.New("missing room id")
	ErrApprovalOnlyOwner      = errors.New("only the owner can approve")
	ErrApprovalUnknown        = errors.New("unknown or expired approval id")
	ErrApprovalWrongRoom      = errors.New("approval id does not belong to this room")
	ErrApprovalExpired        = errors.New("approval expired")
	ErrApprovalAlreadyHandled = errors.New("approval already resolved")
)

Shared sentinel errors for approval resolution.

Functions

func ApplyAgentRemoteBridgeInfo added in v0.0.3

func ApplyAgentRemoteBridgeInfo(content *event.BridgeEventContent, protocolID string, roomType database.RoomType, aiKind string)

func ApprovalErrorToastText

func ApprovalErrorToastText(err error) string

ApprovalErrorToastText maps an approval error to a user-facing toast string.

func BuildApprovalPromptBody

func BuildApprovalPromptBody(presentation ApprovalPromptPresentation, options []ApprovalOption) string

func BuildApprovalResponseBody

func BuildApprovalResponseBody(presentation ApprovalPromptPresentation, decision ApprovalDecisionPayload) string

func BuildBotUserInfo

func BuildBotUserInfo(name string, identifiers ...string) *bridgev2.UserInfo

BuildBotUserInfo returns a UserInfo for an AI bot ghost with the given name and identifiers.

func BuildChatInfoWithFallback

func BuildChatInfoWithFallback(metaTitle, portalName, fallbackTitle, portalTopic string) *bridgev2.ChatInfo

func BuildContinuationMessage

func BuildContinuationMessage(
	portal networkid.PortalKey,
	body string,
	sender bridgev2.EventSender,
	idPrefix,
	logKey string,
	timestamp time.Time,
	streamOrder int64,
) *simplevent.PreConvertedMessage

BuildContinuationMessage constructs a ConvertedMessage for overflow continuation text, flagged with "com.beeper.continuation".

func BuildDMChatInfo

func BuildDMChatInfo(p DMChatInfoParams) *bridgev2.ChatInfo

BuildDMChatInfo creates a ChatInfo for a DM room between a human user and a bot ghost.

func BuildLoginDMChatInfo

func BuildLoginDMChatInfo(p LoginDMChatInfoParams) *bridgev2.ChatInfo

func BuildMediaFileFeatureMap

func BuildMediaFileFeatureMap(build func() *event.FileFeatures) event.FileFeatureMap

func BuildMetaTypes

func BuildMetaTypes(portal, message, userLogin, ghost func() any) database.MetaTypes

func BuildReactionEvent

func BuildReactionEvent(
	portal networkid.PortalKey,
	sender bridgev2.EventSender,
	targetMessage networkid.MessageID,
	emoji string,
	emojiID networkid.EmojiID,
	timestamp time.Time,
	streamOrder int64,
	logKey string,
	dbMeta *database.Reaction,
	extraContent map[string]any,
) *simplevent.Reaction

BuildReactionEvent creates a reaction add event with normalized emoji data.

func BuildReactionRemoveEvent

func BuildReactionRemoveEvent(
	portal networkid.PortalKey,
	sender bridgev2.EventSender,
	targetMessage networkid.MessageID,
	emojiID networkid.EmojiID,
	timestamp time.Time,
	streamOrder int64,
	logKey string,
) *simplevent.Reaction

BuildReactionRemoveEvent creates a reaction removal event with explicit timing.

func BuildRoomFeatures

func BuildRoomFeatures(p RoomFeaturesParams) *event.RoomFeatures

func BuildSystemNotice

func BuildSystemNotice(body string) *bridgev2.ConvertedMessage

BuildSystemNotice creates a ConvertedMessage containing a single MsgNotice part.

func CompleteLoginStep

func CompleteLoginStep(stepID string, login *bridgev2.UserLogin) *bridgev2.LoginStep

CompleteLoginStep builds the standard completion step for a loaded login.

func ComputeApprovalExpiry

func ComputeApprovalExpiry(ttlSeconds int) time.Time

ComputeApprovalExpiry returns the expiry time based on ttlSeconds, falling back to DefaultApprovalExpiry when ttlSeconds <= 0.

func CreateAndCompleteLogin

func CreateAndCompleteLogin(
	persistCtx context.Context,
	connectCtx context.Context,
	user *bridgev2.User,
	loginType string,
	remoteName string,
	metadata any,
	stepID string,
	load func(context.Context, *bridgev2.UserLogin) error,
) (*bridgev2.UserLogin, *bridgev2.LoginStep, error)

CreateAndCompleteLogin creates a user login and returns the standard completion step.

func DecisionToString

func DecisionToString(decision ApprovalDecisionPayload, once, always, deny string) string

DecisionToString maps an ApprovalDecisionPayload to one of three upstream string values (once/always/deny) based on the decision fields.

func DefaultBridgeInfoVersion

func DefaultBridgeInfoVersion() (info, capabilities int)

DefaultBridgeInfoVersion returns the shared bridge info/capability schema version pair.

func DefaultNetworkCapabilities

func DefaultNetworkCapabilities() *bridgev2.NetworkGeneralCapabilities

DefaultNetworkCapabilities returns the common baseline capabilities for bridge connectors.

func DownloadAndEncodeMedia

func DownloadAndEncodeMedia(ctx context.Context, login *bridgev2.UserLogin, mediaURL string, encFile *event.EncryptedFileInfo, maxMB int) (string, string, error)

DownloadAndEncodeMedia downloads media from a Matrix content URI, enforces an optional size limit, and returns the base64-encoded content.

func DownloadMediaBytes

func DownloadMediaBytes(ctx context.Context, login *bridgev2.UserLogin, mediaURL string, encFile *event.EncryptedFileInfo, maxBytes int64) ([]byte, string, error)

DownloadMediaBytes downloads media from a Matrix content URI and returns the raw bytes and detected MIME type.

func EnsureClientMap

func EnsureClientMap(mu *sync.Mutex, clients *map[networkid.UserLoginID]bridgev2.NetworkAPI)

EnsureClientMap initializes the connector client cache map when needed.

func EnsureLoginMetadata

func EnsureLoginMetadata[T any](login *bridgev2.UserLogin) *T

func EnsureMetadata

func EnsureMetadata[T any](holder *any) *T

EnsureMetadata type-asserts or initializes a metadata pointer from a holder. holder is the pointer to the Metadata field (e.g. &login.Metadata).

func EnsurePortalMetadata

func EnsurePortalMetadata[T any](portal *bridgev2.Portal) *T

func EnsureReactionContent

func EnsureReactionContent(msg *bridgev2.MatrixReaction) *event.ReactionEventContent

EnsureReactionContent lazily parses the reaction content from a MatrixReaction.

func EnsureSyntheticReactionSenderGhost

func EnsureSyntheticReactionSenderGhost(ctx context.Context, login *bridgev2.UserLogin, userID id.UserID) error

EnsureSyntheticReactionSenderGhost ensures the backing ghost row exists for the synthetic Matrix-side sender namespace (mxid:<user>) used for local Matrix reaction pre-handling.

func ExpandUserHome

func ExpandUserHome(path string) (string, error)

func HumanUserID

func HumanUserID(prefix string, loginID networkid.UserLoginID) networkid.UserID

func IsMatrixBotUser

func IsMatrixBotUser(ctx context.Context, bridge *bridgev2.Bridge, userID id.UserID) bool

IsMatrixBotUser returns true if the given user ID belongs to the bridge bot or a ghost.

func LoadConnectAndCompleteLogin

func LoadConnectAndCompleteLogin(
	persistCtx context.Context,
	connectCtx context.Context,
	login *bridgev2.UserLogin,
	stepID string,
	load func(context.Context, *bridgev2.UserLogin) error,
) (*bridgev2.LoginStep, error)

LoadConnectAndCompleteLogin reloads the typed client, reconnects it in the background, and returns the standard completion step.

func LoadOrCreateClient

func LoadOrCreateClient(
	mu *sync.Mutex,
	clients map[networkid.UserLoginID]bridgev2.NetworkAPI,
	loginID networkid.UserLoginID,
	reuse func(existing bridgev2.NetworkAPI) bool,
	create func() (bridgev2.NetworkAPI, error),
) (bridgev2.NetworkAPI, error)

LoadOrCreateClient returns a cached client if reusable, otherwise creates and caches a new one.

func LoadOrCreateTypedClient

func LoadOrCreateTypedClient[T bridgev2.NetworkAPI](
	mu *sync.Mutex,
	clients map[networkid.UserLoginID]bridgev2.NetworkAPI,
	login *bridgev2.UserLogin,
	reuse func(T, *bridgev2.UserLogin),
	create func() (T, error),
) (T, error)

LoadOrCreateTypedClient wraps LoadOrCreateClient with typed reuse/create callbacks.

func LoadUserLogin

func LoadUserLogin[C bridgev2.NetworkAPI](login *bridgev2.UserLogin, cfg LoadUserLoginConfig[C]) error

LoadUserLogin loads or creates a typed client using LoadOrCreateTypedClient. On failure it assigns a BrokenLoginClient and returns nil error, matching the convention used by all bridge connectors.

func LoggerFromContext

func LoggerFromContext(ctx context.Context, fallback *zerolog.Logger) *zerolog.Logger

LoggerFromContext returns the logger from the context if available, otherwise falls back to the provided logger.

func LoginErrorCode added in v0.0.3

func LoginErrorCode(parts ...string) string

func MakeUserLoginID

func MakeUserLoginID(prefix string, mxid id.UserID, ordinal int) networkid.UserLoginID

MakeUserLoginID creates a login ID in the format "prefix:escaped-mxid[:ordinal]".

func MatrixEventTimestamp

func MatrixEventTimestamp(evt *event.Event) time.Time

MatrixEventTimestamp returns the event's timestamp as a time.Time, falling back to time.Now() if the event is nil or has no timestamp.

func MatrixMessageID

func MatrixMessageID(eventID id.EventID) networkid.MessageID

func MatrixSenderID

func MatrixSenderID(userID id.UserID) networkid.UserID

MatrixSenderID returns the standard networkid.UserID for a Matrix user.

func MessageSendStatusError

func MessageSendStatusError(
	err error,
	message string,
	reason event.MessageStatusReason,
	statusForError func(error) event.MessageStatus,
	reasonForError func(error) event.MessageStatusReason,
) error

func NewEventID

func NewEventID(prefix string) id.EventID

NewEventID generates a unique Matrix-style event ID with the given prefix.

func NewLoginRespError added in v0.0.3

func NewLoginRespError(statusCode int, message string, parts ...string) bridgev2.RespError

func NewMessageID

func NewMessageID(prefix string) networkid.MessageID

NewMessageID generates a unique message ID in the format "prefix:uuid".

func NewTurnID

func NewTurnID() string

NewTurnID generates a new unique, sortable turn ID using a timestamp-based format.

func NextUserLoginID

func NextUserLoginID(user *bridgev2.User, prefix string) networkid.UserLoginID

NextUserLoginID finds the next available ordinal for a login ID with the given prefix.

func NormalizeAIRoomTypeV2

func NormalizeAIRoomTypeV2(roomType database.RoomType, aiKind string) string

func NormalizeAbsolutePath

func NormalizeAbsolutePath(path string) (string, error)

func NormalizeUIParts

func NormalizeUIParts(raw any) []map[string]any

NormalizeUIParts coerces a raw parts value (which may be []any or []map[string]any) into a typed []map[string]any slice.

func PreHandleApprovalReaction

func PreHandleApprovalReaction(msg *bridgev2.MatrixReaction) (bridgev2.MatrixReactionPreResponse, error)

PreHandleApprovalReaction implements the common PreHandleMatrixReaction logic shared by all bridges. The SenderID is derived from the Matrix sender.

func PrimeUserLoginCache

func PrimeUserLoginCache(ctx context.Context, br *bridgev2.Bridge)

PrimeUserLoginCache preloads all logins into bridgev2's in-memory user/login caches.

func RedactApprovalPromptPlaceholderReactions

func RedactApprovalPromptPlaceholderReactions(
	ctx context.Context,
	login *bridgev2.UserLogin,
	portal *bridgev2.Portal,
	sender bridgev2.EventSender,
	prompt ApprovalPromptRegistration,
	opts ApprovalPromptReactionCleanupOptions,
) error

RedactApprovalPromptPlaceholderReactions redacts only bridge-authored placeholder reactions on a known approval prompt message. User reactions are preserved.

func RedactEventAsSender

func RedactEventAsSender(
	ctx context.Context,
	login *bridgev2.UserLogin,
	portal *bridgev2.Portal,
	sender bridgev2.EventSender,
	targetEventID id.EventID,
) error

RedactEventAsSender redacts an event ID in a room using the intent resolved for sender.

func RemoveClientFromCache

func RemoveClientFromCache(
	mu *sync.Mutex,
	clients map[networkid.UserLoginID]bridgev2.NetworkAPI,
	loginID networkid.UserLoginID,
)

RemoveClientFromCache removes a client from the cache by login ID.

func SendAIRoomInfo

func SendAIRoomInfo(ctx context.Context, portal *bridgev2.Portal, aiKind string) bool

func SendEditViaPortal

func SendEditViaPortal(
	login *bridgev2.UserLogin,
	portal *bridgev2.Portal,
	sender bridgev2.EventSender,
	targetMessage networkid.MessageID,
	timestamp time.Time,
	streamOrder int64,
	logKey string,
	converted *bridgev2.ConvertedEdit,
) error

SendEditViaPortal queues a pre-built edit through bridgev2's remote event pipeline.

func SendMatrixMessageStatus

func SendMatrixMessageStatus(
	ctx context.Context,
	portal *bridgev2.Portal,
	evt *event.Event,
	status bridgev2.MessageStatus,
)

func SendViaPortal

SendViaPortal sends a pre-built message through bridgev2's QueueRemoteEvent pipeline. If MsgID is empty, a new one is generated using IDPrefix.

func SingleLoginFlow

func SingleLoginFlow(enabled bool, flow bridgev2.LoginFlow) []bridgev2.LoginFlow

func StopClients

func StopClients(mu *sync.Mutex, clients *map[networkid.UserLoginID]bridgev2.NetworkAPI)

StopClients disconnects all cached clients that expose Disconnect().

func UnsupportedMessageStatus

func UnsupportedMessageStatus(err error) error

func UpdateAndCompleteLogin

func UpdateAndCompleteLogin(
	persistCtx context.Context,
	connectCtx context.Context,
	login *bridgev2.UserLogin,
	remoteName string,
	metadata any,
	stepID string,
	load func(context.Context, *bridgev2.UserLogin) error,
) (*bridgev2.LoginStep, error)

UpdateAndCompleteLogin saves an existing login and returns the standard completion step.

func UpsertAssistantMessage

func UpsertAssistantMessage(ctx context.Context, p UpsertAssistantMessageParams)

UpsertAssistantMessage updates an existing message's metadata or inserts a new one. If NetworkMessageID is set, tries to find and update the existing row first. Falls back to inserting a new row keyed by InitialEventID.

func ValidateLoginState

func ValidateLoginState(user *bridgev2.User, br *bridgev2.Bridge) error

ValidateLoginState checks that the user and bridge are non-nil. This is the common preamble shared by all bridge LoginProcess implementations.

func ValidateSingleLoginFlow

func ValidateSingleLoginFlow(flowID, expectedFlowID string, enabled bool) error

func ValueSummary

func ValueSummary(value any) string

ValueSummary returns a human-readable summary of a value for approval detail display.

func WrapLoginRespError added in v0.0.3

func WrapLoginRespError(err error, statusCode int, parts ...string) bridgev2.RespError

Types

type Aborter

type Aborter interface {
	Abort(reason string)
}

Aborter is implemented by any value that can be aborted with a reason string. sdk.Turn satisfies this interface.

type ApprovalDecisionPayload

type ApprovalDecisionPayload struct {
	ApprovalID  string
	Approved    bool
	Always      bool
	Reason      string
	ReactionKey string
	ResolvedBy  ApprovalResolutionOrigin
}

ApprovalDecisionPayload is the standardized decision type for all approval flows.

type ApprovalDetail

type ApprovalDetail struct {
	Label string `json:"label"`
	Value string `json:"value"`
}

func AddOptionalDetail

func AddOptionalDetail(input map[string]any, details []ApprovalDetail, key, label string, ptr *string) (map[string]any, []ApprovalDetail)

AddOptionalDetail appends an approval detail from an optional string pointer. If the pointer is nil or empty, input and details are returned unchanged.

func AppendDetailsFromMap

func AppendDetailsFromMap(details []ApprovalDetail, labelPrefix string, values map[string]any, max int) []ApprovalDetail

AppendDetailsFromMap appends approval details from a string-keyed map, sorted by key, with a truncation notice if the map exceeds max entries.

type ApprovalFlow

type ApprovalFlow[D any] struct {
	// contains filtered or unexported fields
}

ApprovalFlow owns the full lifecycle of approval prompts and pending approvals. D is the bridge-specific pending data type.

func NewApprovalFlow

func NewApprovalFlow[D any](cfg ApprovalFlowConfig[D]) *ApprovalFlow[D]

NewApprovalFlow creates an ApprovalFlow from the given config. Call Close() when the flow is no longer needed to stop the reaper goroutine.

func (*ApprovalFlow[D]) Close

func (f *ApprovalFlow[D]) Close()

Close stops the reaper goroutine. Safe to call multiple times.

func (*ApprovalFlow[D]) Drop

func (f *ApprovalFlow[D]) Drop(approvalID string)

Drop removes a pending approval and its associated prompt from both stores.

func (*ApprovalFlow[D]) FindByData

func (f *ApprovalFlow[D]) FindByData(predicate func(data D) bool) string

FindByData iterates pending approvals and returns the id of the first one for which the predicate returns true. Returns "" if none match.

func (*ApprovalFlow[D]) FinishResolved

func (f *ApprovalFlow[D]) FinishResolved(approvalID string, decision ApprovalDecisionPayload)

FinishResolved finalizes a terminal approval by editing the approval prompt to its final state and cleaning up bridge-authored placeholder reactions.

func (*ApprovalFlow[D]) Get

func (f *ApprovalFlow[D]) Get(approvalID string) *Pending[D]

Get returns the pending approval for the given id, or nil if not found.

func (*ApprovalFlow[D]) HandleReaction

func (f *ApprovalFlow[D]) HandleReaction(ctx context.Context, msg *bridgev2.MatrixReaction) bool

HandleReaction checks whether a reaction targets a known approval prompt. If so, it validates room, resolves the approval (via channel or DeliverDecision), and redacts prompt reactions.

func (*ApprovalFlow[D]) HandleReactionRemove

func (f *ApprovalFlow[D]) HandleReactionRemove(ctx context.Context, msg *bridgev2.MatrixReactionRemove) bool

HandleReactionRemove rejects post-resolution approval reaction removals so the chosen terminal action stays immutable.

func (*ApprovalFlow[D]) PendingIDs

func (f *ApprovalFlow[D]) PendingIDs() []string

func (*ApprovalFlow[D]) Register

func (f *ApprovalFlow[D]) Register(approvalID string, ttl time.Duration, data D) (*Pending[D], bool)

Register adds a new pending approval with the given TTL and bridge-specific data. Returns the Pending and true if newly created, or the existing one and false if a non-expired approval with the same ID already exists.

func (*ApprovalFlow[D]) Resolve

func (f *ApprovalFlow[D]) Resolve(approvalID string, decision ApprovalDecisionPayload) error

Resolve programmatically delivers a decision to a pending approval's channel. Use this when a decision arrives from an external source (e.g. the upstream server or auto-approval) rather than a Matrix reaction. Unlike HandleReaction, Resolve does NOT drop the pending entry — the caller (typically Wait or an explicit Drop) is responsible for cleanup.

func (*ApprovalFlow[D]) ResolveExternal

func (f *ApprovalFlow[D]) ResolveExternal(ctx context.Context, approvalID string, decision ApprovalDecisionPayload)

ResolveExternal finalizes a remote allow/deny decision. The bridge declares whether the decision originated from the user or the agent/system and the shared approval flow manages the terminal Matrix reactions accordingly.

func (*ApprovalFlow[D]) SendPrompt

func (f *ApprovalFlow[D]) SendPrompt(ctx context.Context, portal *bridgev2.Portal, params SendPromptParams)

SendPrompt builds an approval prompt message, registers it in the prompt store, sends it via the configured sender, binds the prompt identifiers, and queues prefill reactions.

func (*ApprovalFlow[D]) SetData

func (f *ApprovalFlow[D]) SetData(approvalID string, updater func(D) D) bool

SetData updates the Data field on a pending approval under the lock. Returns false if the approval is not found.

func (*ApprovalFlow[D]) Wait

func (f *ApprovalFlow[D]) Wait(ctx context.Context, approvalID string) (ApprovalDecisionPayload, bool)

Wait blocks until a decision arrives via reaction, the approval expires, or ctx is cancelled. Only useful for channel-based flows (DeliverDecision is nil).

type ApprovalFlowConfig

type ApprovalFlowConfig[D any] struct {
	// Login returns the current UserLogin. Required.
	Login func() *bridgev2.UserLogin

	// Sender returns the EventSender to use for a given portal (e.g. the agent ghost).
	Sender func(portal *bridgev2.Portal) bridgev2.EventSender

	// BackgroundContext optionally returns a context detached from the request lifecycle.
	BackgroundContext func(ctx context.Context) context.Context

	// RoomIDFromData extracts the stored room ID from pending data for validation.
	// Return "" to skip the room check.
	RoomIDFromData func(data D) id.RoomID

	// DeliverDecision is called for non-channel flows when a valid reaction resolves
	// an approval. The flow has already validated owner, expiration, and room.
	// If nil, the flow is channel-based: decisions are delivered via an internal
	// channel and retrieved with Wait().
	DeliverDecision func(ctx context.Context, portal *bridgev2.Portal, pending *Pending[D], decision ApprovalDecisionPayload) error

	// SendNotice sends a system notice to a portal. Used for error toasts.
	SendNotice func(ctx context.Context, portal *bridgev2.Portal, msg string)

	// DBMetadata produces bridge-specific metadata for the approval prompt message.
	// If nil, a default *BaseMessageMetadata is used.
	DBMetadata func(prompt ApprovalPromptMessage) any

	IDPrefix    string
	LogKey      string
	SendTimeout time.Duration
}

ApprovalFlowConfig holds the bridge-specific callbacks for ApprovalFlow.

type ApprovalOption

type ApprovalOption struct {
	ID          string `json:"id"`
	Key         string `json:"key"`
	FallbackKey string `json:"fallback_key,omitempty"`
	Label       string `json:"label,omitempty"`
	Approved    bool   `json:"approved"`
	Always      bool   `json:"always,omitempty"`
	Reason      string `json:"reason,omitempty"`
}

func ApprovalPromptOptions

func ApprovalPromptOptions(allowAlways bool) []ApprovalOption

func DefaultApprovalOptions

func DefaultApprovalOptions() []ApprovalOption

type ApprovalPromptMessage

type ApprovalPromptMessage struct {
	Content       *event.MessageEventContent
	TopLevelExtra map[string]any
	Body          string
	UIMessage     map[string]any
	Presentation  ApprovalPromptPresentation
	Options       []ApprovalOption
}

type ApprovalPromptMessageParams

type ApprovalPromptMessageParams struct {
	ApprovalID        string
	ToolCallID        string
	ToolName          string
	TurnID            string
	Presentation      ApprovalPromptPresentation
	ReplyToEventID    id.EventID
	ThreadRootEventID id.EventID
	ExpiresAt         time.Time
	Options           []ApprovalOption
}

type ApprovalPromptPresentation

type ApprovalPromptPresentation struct {
	Title       string           `json:"title"`
	Details     []ApprovalDetail `json:"details,omitempty"`
	AllowAlways bool             `json:"allowAlways,omitempty"`
}

type ApprovalPromptReactionCleanupOptions

type ApprovalPromptReactionCleanupOptions struct {
	PreserveSenderID networkid.UserID
	PreserveKey      string
}

type ApprovalPromptReactionMatch

type ApprovalPromptReactionMatch struct {
	KnownPrompt            bool
	ShouldResolve          bool
	ApprovalID             string
	Decision               ApprovalDecisionPayload
	RejectReason           string
	Prompt                 ApprovalPromptRegistration
	MirrorDecisionReaction bool
	RedactResolvedReaction bool
}

type ApprovalPromptRegistration

type ApprovalPromptRegistration struct {
	ApprovalID              string
	RoomID                  id.RoomID
	OwnerMXID               id.UserID
	ToolCallID              string
	ToolName                string
	TurnID                  string
	PromptVersion           uint64
	Presentation            ApprovalPromptPresentation
	ExpiresAt               time.Time
	Options                 []ApprovalOption
	ReactionTargetMessageID networkid.MessageID
	PromptMessageID         networkid.MessageID
	PromptSenderID          networkid.UserID
}

type ApprovalReactionHandler

type ApprovalReactionHandler interface {
	HandleReaction(ctx context.Context, msg *bridgev2.MatrixReaction) bool
}

ApprovalReactionHandler is the interface used by BaseReactionHandler to dispatch reactions to the approval system without knowing the concrete type.

type ApprovalReactionRemoveHandler

type ApprovalReactionRemoveHandler interface {
	HandleReactionRemove(ctx context.Context, msg *bridgev2.MatrixReactionRemove) bool
}

ApprovalReactionRemoveHandler is an optional extension for handling reaction removals.

type ApprovalResolutionOrigin

type ApprovalResolutionOrigin string
const (
	ApprovalResolutionOriginUser  ApprovalResolutionOrigin = "user"
	ApprovalResolutionOriginAgent ApprovalResolutionOrigin = "agent"
)

func ApprovalResolutionOriginFromString

func ApprovalResolutionOriginFromString(value string) ApprovalResolutionOrigin

type ApprovalResponsePromptMessageParams

type ApprovalResponsePromptMessageParams struct {
	ApprovalID   string
	ToolCallID   string
	ToolName     string
	TurnID       string
	Presentation ApprovalPromptPresentation
	Options      []ApprovalOption
	Decision     ApprovalDecisionPayload
	ExpiresAt    time.Time
}

type AssistantMessageMetadata

type AssistantMessageMetadata struct {
	CompletionID       string `json:"completion_id,omitempty"`
	Model              string `json:"model,omitempty"`
	HasToolCalls       bool   `json:"has_tool_calls,omitempty"`
	Transcript         string `json:"transcript,omitempty"`
	FirstTokenAtMs     int64  `json:"first_token_at_ms,omitempty"`
	ThinkingTokenCount int    `json:"thinking_token_count,omitempty"`
}

AssistantMessageMetadata contains fields common to assistant messages across bridges. Embed this in each bridge's MessageMetadata alongside BaseMessageMetadata.

func (*AssistantMessageMetadata) CopyFromAssistant

func (a *AssistantMessageMetadata) CopyFromAssistant(src *AssistantMessageMetadata)

CopyFromAssistant copies non-zero assistant fields from src into the receiver.

type AssistantMetadataParams

type AssistantMetadataParams struct {
	Body              string
	FinishReason      string
	TurnID            string
	AgentID           string
	StartedAtMs       int64
	CompletedAtMs     int64
	ThinkingContent   string
	PromptTokens      int64
	CompletionTokens  int64
	ReasoningTokens   int64
	ToolCalls         []ToolCallMetadata
	GeneratedFiles    []GeneratedFileRef
	CanonicalTurnData map[string]any
}

AssistantMetadataParams holds the bridge-agnostic fields needed to populate an assistant message's BaseMessageMetadata. Each bridge extracts these from its own streamingState type and passes them here.

type BaseLoginProcess

type BaseLoginProcess struct {
	// contains filtered or unexported fields
}

BaseLoginProcess provides background context management for login flows. Embed this in bridge-specific login structs to get free Cancel() and BackgroundProcessContext() implementations.

func (*BaseLoginProcess) BackgroundProcessContext

func (p *BaseLoginProcess) BackgroundProcessContext() context.Context

BackgroundProcessContext returns a long-lived context for background operations. The context is lazily initialized on first call and reused for subsequent calls.

func (*BaseLoginProcess) Cancel

func (p *BaseLoginProcess) Cancel()

Cancel cancels the background context and clears all references.

type BaseMessageMetadata

type BaseMessageMetadata struct {
	Role               string             `json:"role,omitempty"`
	Body               string             `json:"body,omitempty"`
	FinishReason       string             `json:"finish_reason,omitempty"`
	PromptTokens       int64              `json:"prompt_tokens,omitempty"`
	CompletionTokens   int64              `json:"completion_tokens,omitempty"`
	ReasoningTokens    int64              `json:"reasoning_tokens,omitempty"`
	TurnID             string             `json:"turn_id,omitempty"`
	AgentID            string             `json:"agent_id,omitempty"`
	CanonicalTurnData  map[string]any     `json:"canonical_turn_data,omitempty"`
	StartedAtMs        int64              `json:"started_at_ms,omitempty"`
	CompletedAtMs      int64              `json:"completed_at_ms,omitempty"`
	ThinkingContent    string             `json:"thinking_content,omitempty"`
	ToolCalls          []ToolCallMetadata `json:"tool_calls,omitempty"`
	GeneratedFiles     []GeneratedFileRef `json:"generated_files,omitempty"`
	ExcludeFromHistory bool               `json:"exclude_from_history,omitempty"`
}

BaseMessageMetadata contains fields common to all bridge MessageMetadata structs. Embed this in each bridge's MessageMetadata to share CopyFrom logic.

func BuildAssistantBaseMetadata

func BuildAssistantBaseMetadata(p AssistantMetadataParams) BaseMessageMetadata

BuildAssistantBaseMetadata constructs a BaseMessageMetadata for an assistant message from the given params. This deduplicates the common field-population logic shared across bridge saveAssistantMessage implementations.

func (*BaseMessageMetadata) CopyFromBase

func (b *BaseMessageMetadata) CopyFromBase(src *BaseMessageMetadata)

CopyFromBase copies non-zero common fields from src into the receiver.

type BaseReactionHandler

type BaseReactionHandler struct {
	Target ReactionTarget
}

BaseReactionHandler is an embeddable mixin that implements the three reaction interface methods (PreHandleMatrixReaction, HandleMatrixReaction, HandleMatrixReactionRemove) for bridges whose reaction handling is limited to approval prompt reactions.

func (BaseReactionHandler) HandleMatrixReaction

func (h BaseReactionHandler) HandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (*database.Reaction, error)

func (BaseReactionHandler) HandleMatrixReactionRemove

func (h BaseReactionHandler) HandleMatrixReactionRemove(ctx context.Context, msg *bridgev2.MatrixReactionRemove) error

func (BaseReactionHandler) PreHandleMatrixReaction

type BaseStreamState

type BaseStreamState struct {
	StreamMu                  sync.Mutex
	StreamSessions            map[string]*turns.StreamSession
	StreamFallbackToDebounced atomic.Bool
	// contains filtered or unexported fields
}

BaseStreamState provides the common stream session fields and lifecycle methods shared across bridges that use turns.

func (*BaseStreamState) BeginStreamShutdown

func (s *BaseStreamState) BeginStreamShutdown()

func (*BaseStreamState) CloseAllSessions

func (s *BaseStreamState) CloseAllSessions()

CloseAllSessions ends every active stream session and clears the map.

func (*BaseStreamState) InitStreamState

func (s *BaseStreamState) InitStreamState()

InitStreamState initialises the StreamSessions map. Call this during client construction.

func (*BaseStreamState) IsStreamShuttingDown

func (s *BaseStreamState) IsStreamShuttingDown() bool

func (*BaseStreamState) ResetStreamShutdown

func (s *BaseStreamState) ResetStreamShutdown()

type BrokenLoginClient

type BrokenLoginClient struct {
	UserLogin *bridgev2.UserLogin
	Reason    string
	OnLogout  func(context.Context, *bridgev2.UserLogin)
}

BrokenLoginClient keeps invalid logins loadable/deletable.

func NewBrokenLoginClient

func NewBrokenLoginClient(login *bridgev2.UserLogin, reason string) *BrokenLoginClient

NewBrokenLoginClient creates a BrokenLoginClient for a login that cannot be fully initialized (e.g. missing credentials or invalid config).

func (*BrokenLoginClient) Connect

func (c *BrokenLoginClient) Connect(_ context.Context)

func (*BrokenLoginClient) Disconnect

func (c *BrokenLoginClient) Disconnect()

func (*BrokenLoginClient) GetCapabilities

func (c *BrokenLoginClient) GetCapabilities(_ context.Context, _ *bridgev2.Portal) *event.RoomFeatures

func (*BrokenLoginClient) GetChatInfo

func (*BrokenLoginClient) GetUserInfo

func (*BrokenLoginClient) HandleMatrixMessage

func (*BrokenLoginClient) IsLoggedIn

func (c *BrokenLoginClient) IsLoggedIn() bool

func (*BrokenLoginClient) IsThisUser

func (c *BrokenLoginClient) IsThisUser(_ context.Context, _ networkid.UserID) bool

func (*BrokenLoginClient) LogoutRemote

func (c *BrokenLoginClient) LogoutRemote(ctx context.Context)

type ClientBase

type ClientBase struct {
	BaseReactionHandler
	BaseStreamState

	HumanUserIDPrefix string
	MessageIDPrefix   string
	MessageLogKey     string
	// contains filtered or unexported fields
}

func (*ClientBase) BackgroundContext

func (c *ClientBase) BackgroundContext(ctx context.Context) context.Context

func (*ClientBase) GetUserLogin

func (c *ClientBase) GetUserLogin() *bridgev2.UserLogin

func (*ClientBase) HumanUserID

func (c *ClientBase) HumanUserID() networkid.UserID

func (*ClientBase) InitClientBase

func (c *ClientBase) InitClientBase(login *bridgev2.UserLogin, target ReactionTarget)

func (*ClientBase) IsLoggedIn

func (c *ClientBase) IsLoggedIn() bool

IsLoggedIn returns the current logged-in state.

func (*ClientBase) IsThisUser

func (c *ClientBase) IsThisUser(_ context.Context, userID networkid.UserID) bool

IsThisUser returns true if the given user ID matches the human user for this login.

func (*ClientBase) SendViaPortal

func (c *ClientBase) SendViaPortal(
	portal *bridgev2.Portal,
	sender bridgev2.EventSender,
	converted *bridgev2.ConvertedMessage,
) (id.EventID, networkid.MessageID, error)

func (*ClientBase) SendViaPortalWithOptions

func (c *ClientBase) SendViaPortalWithOptions(
	portal *bridgev2.Portal,
	sender bridgev2.EventSender,
	msgID networkid.MessageID,
	timestamp time.Time,
	streamOrder int64,
	converted *bridgev2.ConvertedMessage,
) (id.EventID, networkid.MessageID, error)

func (*ClientBase) SetLoggedIn

func (c *ClientBase) SetLoggedIn(v bool)

SetLoggedIn sets the logged-in state.

func (*ClientBase) SetUserLogin

func (c *ClientBase) SetUserLogin(login *bridgev2.UserLogin)

type ConnectorBase

type ConnectorBase struct {
	// contains filtered or unexported fields
}

func NewConnector

func NewConnector(spec ConnectorSpec) *ConnectorBase

func (*ConnectorBase) Bridge

func (c *ConnectorBase) Bridge() *bridgev2.Bridge

func (*ConnectorBase) CreateLogin

func (c *ConnectorBase) CreateLogin(ctx context.Context, user *bridgev2.User, flowID string) (bridgev2.LoginProcess, error)

func (*ConnectorBase) FillPortalBridgeInfo

func (c *ConnectorBase) FillPortalBridgeInfo(portal *bridgev2.Portal, content *event.BridgeEventContent)

func (*ConnectorBase) GetBridgeInfoVersion

func (c *ConnectorBase) GetBridgeInfoVersion() (info, capabilities int)

func (*ConnectorBase) GetCapabilities

func (c *ConnectorBase) GetCapabilities() *bridgev2.NetworkGeneralCapabilities

func (*ConnectorBase) GetConfig

func (c *ConnectorBase) GetConfig() (example string, data any, upgrader configupgrade.Upgrader)

func (*ConnectorBase) GetDBMetaTypes

func (c *ConnectorBase) GetDBMetaTypes() database.MetaTypes

func (*ConnectorBase) GetLoginFlows

func (c *ConnectorBase) GetLoginFlows() []bridgev2.LoginFlow

func (*ConnectorBase) GetName

func (c *ConnectorBase) GetName() bridgev2.BridgeName

func (*ConnectorBase) Init

func (c *ConnectorBase) Init(br *bridgev2.Bridge)

func (*ConnectorBase) LoadUserLogin

func (c *ConnectorBase) LoadUserLogin(ctx context.Context, login *bridgev2.UserLogin) error

func (*ConnectorBase) Start

func (c *ConnectorBase) Start(ctx context.Context) error

func (*ConnectorBase) Stop

func (c *ConnectorBase) Stop(ctx context.Context)

type ConnectorSpec

type ConnectorSpec struct {
	ProtocolID string
	AIRoomKind string

	Init  func(*bridgev2.Bridge)
	Start func(context.Context) error
	Stop  func(context.Context)

	Name        func() bridgev2.BridgeName
	Config      func() (example string, data any, upgrader configupgrade.Upgrader)
	DBMeta      func() database.MetaTypes
	LoadLogin   func(context.Context, *bridgev2.UserLogin) error
	LoginFlows  func() []bridgev2.LoginFlow
	CreateLogin func(context.Context, *bridgev2.User, string) (bridgev2.LoginProcess, error)

	Capabilities      func() *bridgev2.NetworkGeneralCapabilities
	BridgeInfoVersion func() (info, capabilities int)
	FillBridgeInfo    func(*bridgev2.Portal, *event.BridgeEventContent)
}

type DMChatInfoParams

type DMChatInfoParams struct {
	Title          string
	HumanUserID    networkid.UserID
	LoginID        networkid.UserLoginID
	BotUserID      networkid.UserID
	BotDisplayName string
	CanBackfill    bool
}

DMChatInfoParams holds the parameters for BuildDMChatInfo.

type EventTiming

type EventTiming struct {
	Timestamp   time.Time
	StreamOrder int64
}

EventTiming carries the explicit timestamp and stream order for a live event.

func NextEventTiming

func NextEventTiming(lastStreamOrder int64, timestamp time.Time) EventTiming

NextEventTiming allocates the next strictly increasing stream order for a sequence of related live events.

func ResolveEventTiming

func ResolveEventTiming(timestamp time.Time, streamOrder int64) EventTiming

ResolveEventTiming fills in missing live-event timing metadata using the shared backfill stream-order semantics.

type GeneratedFileRef

type GeneratedFileRef struct {
	URL      string `json:"url"`
	MimeType string `json:"mime_type"`
}

GeneratedFileRef stores a reference to a file generated by the assistant (e.g., image generation).

func GeneratedFileRefsFromParts

func GeneratedFileRefsFromParts(parts []citations.GeneratedFilePart) []GeneratedFileRef

GeneratedFileRefsFromParts converts citations.GeneratedFilePart values into GeneratedFileRef values suitable for message metadata storage.

type LoadUserLoginConfig

type LoadUserLoginConfig[C bridgev2.NetworkAPI] struct {
	Mu         *sync.Mutex
	Clients    map[networkid.UserLoginID]bridgev2.NetworkAPI
	ClientsRef *map[networkid.UserLoginID]bridgev2.NetworkAPI

	// BridgeName is used in error messages (e.g. "OpenCode").
	BridgeName string

	// MakeBroken returns a BrokenLoginClient for the given reason.
	// If nil, a default BrokenLoginClient is used.
	MakeBroken func(login *bridgev2.UserLogin, reason string) *BrokenLoginClient

	Update func(existing C, login *bridgev2.UserLogin)
	Create func(login *bridgev2.UserLogin) (C, error)

	// AfterLoad is called after a client is successfully loaded or created.
	// Optional — use for post-load setup like scheduling bootstrap.
	AfterLoad func(client C)
}

LoadUserLoginConfig configures the generic LoadUserLogin helper.

type LoginDMChatInfoParams

type LoginDMChatInfoParams struct {
	Title             string
	Login             *bridgev2.UserLogin
	HumanUserIDPrefix string
	BotUserID         networkid.UserID
	BotDisplayName    string
	CanBackfill       bool
}

type Pending

type Pending[D any] struct {
	ExpiresAt time.Time
	Data      D
	// contains filtered or unexported fields
}

Pending represents a single pending approval.

type ReactionContext

type ReactionContext struct {
	TargetMessageID networkid.MessageID
	Emoji           string
	TargetEventID   id.EventID
}

ReactionContext holds the extracted emoji plus the target message/event IDs.

func ExtractReactionContext

func ExtractReactionContext(msg *bridgev2.MatrixReaction) ReactionContext

ExtractReactionContext pulls the emoji and target identifiers from a MatrixReaction.

type ReactionTarget

type ReactionTarget interface {
	GetUserLogin() *bridgev2.UserLogin
	GetApprovalHandler() ApprovalReactionHandler
}

ReactionTarget provides the bridge-specific context that BaseReactionHandler needs to validate and route approval reactions.

type RemoteEdit

type RemoteEdit struct {
	Portal        networkid.PortalKey
	Sender        bridgev2.EventSender
	TargetMessage networkid.MessageID
	Timestamp     time.Time
	// StreamOrder overrides timestamp-based ordering when the caller has a stable upstream order.
	StreamOrder int64
	PreBuilt    *bridgev2.ConvertedEdit

	// LogKey is the zerolog field name used in AddLogContext (e.g. "ai_edit_target", "codex_edit_target").
	LogKey string
}

RemoteEdit is a bridge-agnostic RemoteEdit implementation backed by pre-built content.

func (*RemoteEdit) AddLogContext

func (e *RemoteEdit) AddLogContext(c zerolog.Context) zerolog.Context

func (*RemoteEdit) ConvertEdit

func (*RemoteEdit) GetPortalKey

func (e *RemoteEdit) GetPortalKey() networkid.PortalKey

func (*RemoteEdit) GetSender

func (e *RemoteEdit) GetSender() bridgev2.EventSender

func (*RemoteEdit) GetStreamOrder

func (e *RemoteEdit) GetStreamOrder() int64

func (*RemoteEdit) GetTargetMessage

func (e *RemoteEdit) GetTargetMessage() networkid.MessageID

func (*RemoteEdit) GetTimestamp

func (e *RemoteEdit) GetTimestamp() time.Time

func (*RemoteEdit) GetType

func (e *RemoteEdit) GetType() bridgev2.RemoteEventType

type RoomFeaturesParams

type RoomFeaturesParams struct {
	ID                  string
	File                event.FileFeatureMap
	MaxTextLength       int
	Reply               event.CapabilitySupportLevel
	Thread              event.CapabilitySupportLevel
	Edit                event.CapabilitySupportLevel
	Delete              event.CapabilitySupportLevel
	Reaction            event.CapabilitySupportLevel
	ReadReceipts        bool
	TypingNotifications bool
	DeleteChat          bool
}

type SendPromptParams

type SendPromptParams struct {
	ApprovalPromptMessageParams
	RoomID    id.RoomID
	OwnerMXID id.UserID
}

SendPromptParams holds the parameters for sending an approval prompt.

type SendViaPortalParams

type SendViaPortalParams struct {
	Login     *bridgev2.UserLogin
	Portal    *bridgev2.Portal
	Sender    bridgev2.EventSender
	IDPrefix  string // e.g. "ai", "codex", "opencode"
	LogKey    string // zerolog field name, e.g. "ai_msg_id"
	MsgID     networkid.MessageID
	Timestamp time.Time
	// StreamOrder is optional explicit ordering for events that share a timestamp.
	StreamOrder int64
	Converted   *bridgev2.ConvertedMessage
}

SendViaPortalParams holds the parameters for SendViaPortal.

type StreamTurnHost

type StreamTurnHost[S any] struct {
	// contains filtered or unexported fields
}

StreamTurnHost manages a map of stream states keyed by turn ID, providing thread-safe drain/abort and state cleanup helpers shared across bridges.

func NewStreamTurnHost

func NewStreamTurnHost[S any](cb StreamTurnHostCallbacks[S]) *StreamTurnHost[S]

NewStreamTurnHost creates a new StreamTurnHost.

func (*StreamTurnHost[S]) DeleteIfMatch

func (h *StreamTurnHost[S]) DeleteIfMatch(turnID string, state *S)

DeleteIfMatch removes the entry only if it still points to the given state.

func (*StreamTurnHost[S]) DeleteLocked

func (h *StreamTurnHost[S]) DeleteLocked(turnID string)

DeleteLocked removes a state entry. Must be called with the lock held.

func (*StreamTurnHost[S]) DrainAndAbort

func (h *StreamTurnHost[S]) DrainAndAbort(reason string)

DrainAndAbort collects all active turns, clears the map, and aborts each turn with the given reason. This is the standard disconnect cleanup path.

func (*StreamTurnHost[S]) GetLocked

func (h *StreamTurnHost[S]) GetLocked(turnID string) *S

GetLocked returns the state for turnID. Must be called with the lock held.

func (*StreamTurnHost[S]) IsActive

func (h *StreamTurnHost[S]) IsActive(turnID string) bool

IsActive reports whether a turn ID has an active stream state.

func (*StreamTurnHost[S]) Lock

func (h *StreamTurnHost[S]) Lock()

Lock acquires the host mutex.

func (*StreamTurnHost[S]) SetLocked

func (h *StreamTurnHost[S]) SetLocked(turnID string, state *S)

SetLocked stores state for turnID. Must be called with the lock held.

func (*StreamTurnHost[S]) Unlock

func (h *StreamTurnHost[S]) Unlock()

Unlock releases the host mutex.

type StreamTurnHostCallbacks

type StreamTurnHostCallbacks[S any] struct {
	// GetAborter returns the aborter (typically an *sdk.Turn) from the state, or nil.
	GetAborter func(state *S) Aborter
}

StreamTurnHostCallbacks defines the bridge-specific hooks for StreamTurnHost.

type ToolCallMetadata

type ToolCallMetadata struct {
	CallID        string         `json:"call_id"`
	ToolName      string         `json:"tool_name"`
	ToolType      string         `json:"tool_type"`
	Input         map[string]any `json:"input,omitempty"`
	Output        map[string]any `json:"output,omitempty"`
	Status        string         `json:"status"`
	ResultStatus  string         `json:"result_status,omitempty"`
	ErrorMessage  string         `json:"error_message,omitempty"`
	StartedAtMs   int64          `json:"started_at_ms,omitempty"`
	CompletedAtMs int64          `json:"completed_at_ms,omitempty"`

	// Event IDs for timeline events (if emitted as separate events)
	CallEventID   string `json:"call_event_id,omitempty"`
	ResultEventID string `json:"result_event_id,omitempty"`
}

ToolCallMetadata tracks a tool call within a message. Both bridges and the connector share this type for JSON-serialized database storage.

type TypedClientLoaderSpec

type TypedClientLoaderSpec[C bridgev2.NetworkAPI] struct {
	LoadUserLoginConfig[C]
	Accept func(*bridgev2.UserLogin) (ok bool, reason string)
}

type UpsertAssistantMessageParams

type UpsertAssistantMessageParams struct {
	Login            *bridgev2.UserLogin
	Portal           *bridgev2.Portal
	SenderID         networkid.UserID
	NetworkMessageID networkid.MessageID
	InitialEventID   id.EventID
	Metadata         any // must satisfy database.MetaMerger
	Logger           zerolog.Logger
}

UpsertAssistantMessageParams holds parameters for UpsertAssistantMessage.

Directories

Path Synopsis
bridges
ai
cmd
agentremote command
ai command
codex command
dummybridge command
generate-models command
openclaw command
opencode command
pkg
agents
Package agents provides the agent system for AI-powered assistants.
Package agents provides the agent system for AI-powered assistants.
agents/agentconfig
Package agentconfig provides shared agent configuration types used across the agents and tools packages to avoid import cycles.
Package agentconfig provides shared agent configuration types used across the agents and tools packages to avoid import cycles.
agents/tools
Package tools provides the tool system for AI agents, including tool registration, execution, and policy enforcement.
Package tools provides the tool system for AI agents, including tool registration, execution, and policy enforcement.
shared/citations
Package citations provides shared citation and document types and helper functions used by both the connector and bridge packages.
Package citations provides shared citation and document types and helper functions used by both the connector and bridge packages.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL