Help us shape the future of Go! Take the 2026 Go Developer Survey

feishu

package
v0.4.45 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 48 Imported by: 0

README

Feishu / Lark runtime boundaries

The adapter owns SDK calls, platform identity and routing, native callback decoding, CardKit entities/sequences, and native message rendering. Feishu and Lark share this implementation; their domains and credentials remain instance specific.

Shared or business logic lives outside native rendering:

  • runtime/session/derive.HasUserInstruction classifies existing session history.
  • runtime/platform/common.KeyedExecutor bounds ingress work and preserves FIFO order within a chat. Lark uses 8 active jobs and 256 waiting jobs. Shutdown cancels active work and discards waiting work; jobs must honor cancellation.
  • runtime/cardcompat translates legacy delete-mode cards and form submissions. The renderer handles typed forms and checkboxes without knowing their commands. Existing command names and callback values remain compatible with downstream producers.
  • runtime/larkevent.ReceiptSummary formats the safe event receipt fields; subscription, parsing and event delivery remain native adapter responsibilities.

Delivery semantics

Ordinary IM Create/Reply uses one write boundary. A confirmed expired-token rejection can refresh credentials and retry. A lost response, transport failure, or ambiguous server result is an unknown write: it can already have committed, so neither retry nor another final-message fallback is safe. An unsuccessful Reply is not silently converted into a new parent-chat message. Read/update retries and CardKit entity creation have separate policies. Event-topic root creation retains its stable UUID and existing retry policy; it does not use an unkeyed retry.

Ingress dedup records successful admission to the process-local queue. Queue rejection leaves the event retryable. Admission is not durable processing: shutdown, restart or a failing handler can still lose accepted work. Callback acknowledgment does not promise exactly-once business execution.

Attachment buffering, interaction submission tracking, reaction identity and CardKit sequencing remain separate state with different lifetimes. This refactor does not merge them into a general workflow/state framework or add configuration.

Progress cards consume native outbound events and typed tool results directly. The unused prefixed-string progress payload protocol and its legacy entry inference have been removed. Tool-result formatting stays local until another platform needs the same behavior.

Each stream keeps one active progress-card handle. The obsolete body/progress card queue, eviction bookkeeping, and Markdown-only progress renderer have been removed; turn-end replacement and stale-message recall remain explicit.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New(cfg Config, deps Deps) (agentkit.Platform, error)

New registers platform/feishu: Feishu WebSocket / webhook.

Types

type Config

type Config struct {
	common.AgentRoutingConfig
	AppID                 string `json:"appId"`
	AppSecret             string `json:"appSecret"`
	Domain                string `json:"domain"`
	AllowFrom             string `json:"allowFrom"`
	AllowChat             string `json:"allowChat"`
	GroupReplyAll         bool   `json:"groupReplyAll"`
	ShareSessionInChannel bool   `json:"shareSessionInChannel"` // deprecated: use runner.config.sessionScope
	DMThreadMode          bool   `json:"dmThreadMode"`          // opt-in DM topics; runner sessionScope must be thread
	ThreadIsolation       bool   `json:"threadIsolation"`
	ReplyInThread         *bool  `json:"replyInThread"`
	ThreadNoMention       bool   `json:"threadNoMention"` // 话题被 @bot 激活后,话题内消息(含纯文字)免 @;需 threadIsolation
	ReactionEmoji         string `json:"reactionEmoji"`
	DoneEmoji             string `json:"doneEmoji"`
	CancelledEmoji        string `json:"cancelledEmoji"`
	ErrorEmoji            string `json:"errorEmoji"`
	// SteerEmoji 是入站消息被并入进行中 turn(steer)时替换到该消息上的 emoji。
	// 收到 turn/steer 事件后,平台把该消息原来的处理中 reaction(reactionEmoji)
	// 换成 SteerEmoji,让发消息的人立刻看到“这条已被当前回复接收”;turn/end 时
	// 再统一换成 done/cancelled/error。默认 "Typing","none" 关闭替换
	//(此时消息只保留处理中 reaction)。
	SteerEmoji                 string `json:"steerEmoji"`
	GroupOnly                  bool   `json:"groupOnly"`
	RespondToAtEveryoneAndHere bool   `json:"respondToAtEveryoneAndHere"`
	ReplyToTrigger             *bool  `json:"replyToTrigger"`
	// StopOnRecall 为 nil 时默认 true:用户撤回触发(或 steer 进)进行中
	// turn 的消息时,平台自动按 /stop 取消该 turn;显式 false 关闭。
	// 撤回与进行中 turn 无关的旧消息不影响执行。
	StopOnRecall              *bool             `json:"stopOnRecall"`
	ResolveMentions           bool              `json:"resolveMentions"`
	PeerBots                  map[string]string `json:"peerBots"`
	ShowThinking              *bool             `json:"showThinking"`
	ShowToolProgress          *bool             `json:"showToolProgress"`
	AsyncSubagentProgressCard *bool             `json:"asyncSubagentProgressCard"`
	EnableFeishuCard          *bool             `json:"enableFeishuCard"`
	EncryptKey                string            `json:"encryptKey"`
	Port                      string            `json:"port"`
	CallbackPath              string            `json:"callbackPath"`
	UnknownCardAction         string            `json:"unknownCardAction"` // forward (default) | ignore
	CardSubmissionTTL         string            `json:"cardSubmissionTTL"` // positive duration; default 24h
	// ForwardEventsToAgent 列出直转 agent 处理的自定义事件类型
	// (如 drive.file.created_v1)。事件序列化为一条 inbound 消息;
	// 默认按 event_id 分配独立 session;开启 dmThreadMode 后,仅用户身份事件
	// 创建 DM 根消息并使用话题 session,供后续用户回复续接。
	// 回复仍按事件上下文:带 chat_id 回群,只带 user_id 回 p2p,都无则
	// 无回复目标。妙记/会议等用户身份
	// 订阅事件(minutes.minute.generated_v1、vc.*)按 subscriber_ids[0]
	// 的 open_id 路由到该用户的 p2p 会话。事件类型需在 Lark 开发者后台
	// 同步订阅;用户身份事件还需用户 OAuth 授权后用 user_access_token
	// 调对应服务端订阅 API 注册(见 docs/guides/lark-user-events.zh.md)。
	// 停机期间未 ack 的事件由飞书重推补送,重启后仍会投递(不按进程
	// 启动时间丢弃),重复投递由 event_id 去重。
	ForwardEventsToAgent []string `json:"forwardEventsToAgent,omitempty"`
}

func (*Config) SetDefaults added in v0.3.48

func (c *Config) SetDefaults()

SetDefaults implements pluginkit.Defaulter. Emoji 字段保留 "none" 哨兵语义: 仅在为空时填默认值,"none" 由 newPlatform 映射为空串(禁用)。

func (*Config) Validate added in v0.3.48

func (c *Config) Validate() error

Validate implements pluginkit.Validator.

type Deps

type Deps struct {
	InboundPolicy       ingress.Policy        `json:"inboundPolicy,omitempty"`
	InteractionHandlers []interaction.Handler `json:"interactionHandlers,omitempty"`
	Commands            agentkit.Commands     `json:"commands,omitempty"`
	SessionStore        agentkit.SessionStore `json:"sessionStore,omitempty"`
	Workspace           workspace.Service     `json:"workspace,omitempty"`
	// EventHandlers 订阅自定义 Lark 事件的 handler 插件(cap/larkevent)。
	// 每个 handler 自行声明 EventTypes(),平台按事件类型聚合后注册
	// OnCustomizedEvent;同一事件类型可命中多个 handler。
	EventHandlers []caplarkevent.Handler `json:"eventHandlers,omitempty"`
}

type Platform

type Platform struct {
	common.InstanceIdentity
	// contains filtered or unexported fields
}

func (*Platform) AddDoneReaction

func (p *Platform) AddDoneReaction(rctx any)

AddDoneReaction adds a "done" emoji reaction so the user gets a push notification when the agent finishes a multi-round turn in quiet mode.

func (*Platform) BuildRichCard

func (p *Platform) BuildRichCard(status cardStatus, title string, steps []toolStep, markdown string, streaming bool, elapsed time.Duration) string

BuildRichCard implements core.RichCardSupporter. Feishu engine passes an elapsed duration via the preview handle; buildRichCard itself is the renderer and must be called with the duration from engine state.

func (*Platform) ClearUserProfileCache added in v0.3.52

func (p *Platform) ClearUserProfileCache() int

ClearUserProfileCache removes all cached Contact API profile entries for this leaf. Call after fixing app scopes or when stale empty profiles were cached.

func (*Platform) DeletePreviewMessage

func (p *Platform) DeletePreviewMessage(ctx context.Context, previewHandle any) error

DeletePreviewMessage removes a preview message so the caller can send a separate final message without leaving a stale interactive card behind.

func (*Platform) IsMessageRecalled

func (p *Platform) IsMessageRecalled(ctx context.Context, rctx any) (bool, error)

func (*Platform) PermissionCapability

func (p *Platform) PermissionCapability() permission.Capability

func (*Platform) PlatformID

func (p *Platform) PlatformID() string

func (*Platform) ReadChatHistory added in v0.1.22

func (p *Platform) ReadChatHistory(ctx context.Context, req chathistory.Request) (chathistory.Result, error)

ReadChatHistory lists messages from Feishu/Lark IM for the given delivery session.

func (*Platform) Receive

func (p *Platform) Receive(ctx context.Context) (agentkit.MessageEvent, error)

func (*Platform) ReconstructReplyCtx

func (p *Platform) ReconstructReplyCtx(sessionKey string) (any, error)

func (*Platform) RefreshCard

func (p *Platform) RefreshCard(ctx context.Context, sessionKey string, card *common.Card) error

func (*Platform) Reply

func (p *Platform) Reply(ctx context.Context, rctx any, content string) error

func (*Platform) ReplyCard

func (p *Platform) ReplyCard(ctx context.Context, rctx replyContext, card *common.Card) error

func (*Platform) Send

func (p *Platform) Send(ctx context.Context, event agentkit.OutboundEvent) error

func (*Platform) SendAudio

func (p *Platform) SendAudio(ctx context.Context, rctx any, audio []byte, format string) error

SendAudio uploads audio bytes to Feishu and sends a voice message. Implements core.AudioSender interface. Feishu audio messages require opus format; non-opus input is converted via ffmpeg.

func (*Platform) SendCard added in v0.4.44

func (p *Platform) SendCard(ctx context.Context, route agentkit.RouteRef, card *cap.Card) (cap.MessageRef, error)

SendCard posts a custom plugin card using the existing Lark/Feishu client.

func (*Platform) SendFile

func (p *Platform) SendFile(ctx context.Context, rctx any, file common.FileAttachment) error

func (*Platform) SendImage

func (p *Platform) SendImage(ctx context.Context, rctx any, img common.ImageAttachment) error

func (*Platform) SendPreviewStart

func (p *Platform) SendPreviewStart(ctx context.Context, rctx any, content string) (any, error)

SendPreviewStart sends a new card message and returns a handle for subsequent edits. Using card (interactive) type for both preview and final message so updates are in-place without needing to delete and resend.

func (*Platform) SetPreviewStatus

func (p *Platform) SetPreviewStatus(previewHandle any, status cardStatus)

SetPreviewStatus updates the card header color to reflect the agent's current state.

func (*Platform) SplitMarkdownByTables

func (p *Platform) SplitMarkdownByTables(md string, maxTables int) []string

SplitMarkdownByTables implements core.MarkdownTableSplitter.

func (*Platform) StartTyping

func (p *Platform) StartTyping(ctx context.Context, rctx any) (stop func())

StartTyping adds an emoji reaction to the user's message and returns a stop function that removes the reaction when processing is complete.

func (*Platform) UpdateMessage

func (p *Platform) UpdateMessage(ctx context.Context, previewHandle any, content string) error

UpdateMessage edits an existing card message identified by previewHandle. Uses the Patch API (HTTP PATCH) which is required for interactive card messages. 对外固定标准重试预算;需要其他预算的调用方走 updateMessageProfile。

Jump to

Keyboard shortcuts

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