Skip to content

Improve IM bot setup and diagnostics / 优化 IM 机器人设置与诊断#4070

Merged
esengine merged 30 commits into
main-v2from
feature/bot-im-settings
Jun 12, 2026
Merged

Improve IM bot setup and diagnostics / 优化 IM 机器人设置与诊断#4070
esengine merged 30 commits into
main-v2from
feature/bot-im-settings

Conversation

@SivanCola

@SivanCola SivanCola commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • expose the IM bot entry in production builds and rename the sidebar entry to Bots/机器人
  • simplify the bot settings page around connected bots, inline advanced settings, and collapsed access-control editing
  • add per-connection access status, allowlist deep-linking, and safer mock identifiers
  • improve Feishu/WeChat bot diagnostics, inbound remote remembering, and WeChat iLink message-id handling
  • align Feishu/Lark registration QR links with SDK metadata and match the SDK domain-switch flow so Lark scans can complete through app registration
  • run saved IM connections as independent runtime adapter instances so Feishu, Lark, and WeChat can stay connected together
  • keep healthy IM adapter connections running when another saved connection fails to start, surfacing a degraded runtime status with the failed connection errors
  • auto-start and refresh the desktop IM runtime from saved bot connections after startup, settings changes, and credential updates
  • load desktop bot runtime, diagnostics, test-send actions, and CLI bot commands from the same user-level bot settings used by the Settings page, so project configs cannot disable saved IM bindings
  • migrate legacy project-local desktop bot bindings into user-level bot settings when the user-level bot config is empty or missing, preserving saved bindings across upgrades without automatically persisting unrelated project desktop preferences
  • fail fast when Feishu/Lark or WeChat runtime credentials are missing, avoiding false “running” status for broken connections
  • auto-add the installer user id to the relevant allowlist when Feishu/Lark or WeChat binding succeeds
  • harden remembered remotes with connection-aware scoping, distinct group-user caching, and serialized config persistence
  • sync the desktop frontend binding contract for the new runtime status method and stabilize the WeChat poll-health test on Windows
  • verify Feishu, Lark, and WeChat bot credentials survive process restart/reload from the Reasonix user credentials store

Verification

  • wails generate module from the desktop module
  • pnpm --dir desktop/frontend build
  • go test ./internal/bot ./internal/bot/feishu ./internal/bot/weixin ./internal/botruntime ./internal/cli
  • go test ./internal/bot/weixin ./internal/botruntime ./internal/cli ./internal/bot/...
  • go test ./internal/cli ./internal/botruntime ./internal/config
  • go test ./...
  • go test . from the desktop module
  • git diff --check
  • PROD_TEST_OPEN_DIST=0 ./prod_test darwin/arm64
  • Lark registration API smoke check: begin returned success, and the generated QR URL includes the SDK registration metadata
  • Browser smoke check for the bot sidebar entry, bot settings page, inline advanced settings, and collapsed access-control panel
  • GitHub CI on the latest PR head: linux/macOS/Windows tests, race, desktop, lint, coverage, govulncheck, and CodeQL all pass

@SivanCola SivanCola requested a review from esengine as a code owner June 11, 2026 17:47
@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development desktop Wails desktop app (desktop/**) tui Terminal UI / CLI (internal/cli, internal/control) labels Jun 11, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6814433f65

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/cli/bot.go Outdated
Comment thread internal/cli/bot.go Outdated
Comment thread internal/cli/bot.go Outdated
@SivanCola SivanCola marked this pull request as draft June 11, 2026 18:08
@github-actions github-actions Bot added the config Configuration & setup (internal/config) label Jun 12, 2026
@SivanCola SivanCola marked this pull request as ready for review June 12, 2026 05:44
…tings

# Conflicts:
#	desktop/frontend/src/components/SettingsPanel.tsx

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6951bca81f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/bot/feishu/feishu.go Outdated
Comment thread internal/botruntime/runtime.go

@esengine esengine left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the thorough work here — the independent per-connection runtime, the degraded-status handling, and the fixes from the earlier round (distinct group-user remembering + serialized config persistence, both with regression tests) all look good.

Before this goes in, the P1 from the latest Codex pass is a real blocker. I traced it end-to-end and it holds:

  • approvalCard(...) / askCard(...) are rendered with the session's chatType + userID, so in a group session the approve/deny/answer card is posted into the group.
  • In handleCardAction, firstNonEmpty(payload.Event.Action.Value["user_id"], ...) trusts the requester id baked into the card before the real click operator. So any group member who can see the card — including one not in the user allowlist — can click a button and the inbound is attributed to the original requester.
  • checkAllowlist then gates on that msg.UserID, passes, and /approve <id> resolves against the group session's pending approvals.

Net effect: in a group with tool_approval_mode = ask and a strict allowlist, an unauthorized member can approve a pending tool call as the requester. That defeats the approval gate, which is the entire point of the gate. The two card-action tests currently bless this (msg.UserID == "allowed-user" taken from the card value), so they'd need to flip with the fix.

Fix: gate the allowlist on the actual operator (Operator.OperatorID.* / Operator.*) and treat value["user_id"] as routing-only, rejecting when the operator isn't allowed. TestHandleCardActionAcceptsDirectOperatorID already shows the operator id is present on the event, so this is a small change.

Also still open from the same pass — the P2 on internal/botruntime/runtime.go: --channels lark and --channels feishu both collapse to PlatformFeishu, and AdapterBindings filters by provider only, so with both a Feishu and a Lark connection enabled the selector starts both (wrong-tenant credentials can come up). Lower priority than the P1, but worth folding in since the per-connection Domain / runtime id is already threaded through.

Happy to merge as soon as the operator-auth fix lands.

esengine added 2 commits June 12, 2026 06:36
Group approval/ask cards baked the requester id into value["user_id"]
and trusted it ahead of the real button presser, so any group member
who could see the card could click approve/deny/answer and have it
attributed to the allowlisted requester, defeating the approval gate.

Carry the actual operator id on InboundMessage and gate the allowlist
on it, keeping value["user_id"] as routing-only so the action still
resolves against the requester session.
--channels lark and --channels feishu both collapse to PlatformFeishu,
and AdapterBindings filtered by provider only, so a workspace with both
a Feishu and a Lark connection enabled started both adapters and could
bring up the wrong-tenant credentials.

Thread the explicitly requested feishu-family domains through to the
binding builder and skip connections whose domain was not requested;
nil (no channel given) keeps starting every enabled connection.
@esengine

Copy link
Copy Markdown
Owner

I pushed the two fixes on top of your branch so we can land this:

P1 — operator auth on Feishu cards (fa01784d). The card action now carries the real button presser as InboundMessage.OperatorID, and the allowlist gate checks the operator instead of the requester id baked into the card. value["user_id"] stays routing-only, so /approve|/deny|/answer still resolve against the requester's session — but a group member who isn't on the allowlist can no longer click the card and act as the requester. Added a gateway regression test (TestGatewayAllowlistGatesOnOperatorNotCardRequester) plus a feishu adapter test that proves the operator id is taken from operator.*, not from the card value.

P2 — Feishu/Lark domain isolation (713ee05b). --channels feishu / --channels lark now thread the requested domain through to AdapterBindings, which skips connections whose domain wasn't requested. nil (no --channels) keeps starting every enabled connection, so the desktop runtime and the default CLI path are unchanged. Covered by TestBotAdapterBindingsIsolateRequestedFeishuDomain.

go test ./internal/bot/... ./internal/botruntime/... ./internal/cli/... and the desktop module both pass locally. Thanks for the thorough work on the runtime split and the earlier round of fixes — merging once CI is green.

@esengine esengine left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Operator-auth fix and the Feishu/Lark domain isolation are in, and I synced main-v2 to clear the conflicts. Full CI is green on the merge head — cross-OS tests, race, desktop build, lint, govulncheck, and CodeQL all pass. The frontend merge keeps the prod bot exposure (dropping the dev-only isDevBuild gate is the intended behavior here) while preserving agentRunning and the allowlist deep-link. Thanks for the thorough runtime work — merging.

@esengine esengine merged commit 529ffce into main-v2 Jun 12, 2026
13 checks passed
@esengine esengine deleted the feature/bot-im-settings branch June 12, 2026 14:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

config Configuration & setup (internal/config) desktop Wails desktop app (desktop/**) tui Terminal UI / CLI (internal/cli, internal/control) v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants