Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions docs/remote-connect/feishu-bot-setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Feishu Bot Setup Guide

[中文](./feishu-bot-setup.zh-CN.md)

Use this guide to pair BitFun through a Feishu bot.

## Setup Steps

### Step 1

Open the Feishu Developer Platform and log in:

<https://open.feishu.cn/app?lang=en-US>

### Step 2

Create a custom app.

### Step 3

Add the bot feature:

Features - Bot - Add

### Step 4

Add permission scopes:

Permissions & Scopes - Add Scopes - Search for `im:` - Select all scopes that do not require approval - Add Scopes

### Step 5

Copy the app credentials:

Credentials & Basic Info - App ID and App Secret

### Step 6

Open BitFun and start the Feishu bot connection:

Remote Connect - IM Bot - Feishu Bot - Fill in App ID and App Secret - Connect

### Step 7

Return to the Feishu Developer Platform.

### Step 8

Configure event subscriptions:

Events & callbacks - Event configuration - Subscription mode - Persistent connection - Save

Then add message events:

Add Events - Search for `im.message` - Select all - Confirm

### Step 9

Configure callback subscriptions:

Events & callbacks - Callback configuration - Subscription mode - Persistent connection - Save

Then add card action callbacks:

Add callback - Search for `card.action.trigger` - Select it - Confirm

### Step 10

Publish the bot.

### Step 11

Open Feishu, search for the bot name, open the chat, enter any message, and send it.

### Step 12

Enter the 6-digit pairing code shown in BitFun Desktop, send it, and wait for the connection to succeed.
77 changes: 77 additions & 0 deletions docs/remote-connect/feishu-bot-setup.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# 飞书机器人配置指南

[English](./feishu-bot-setup.md)

适用于通过飞书机器人完成 BitFun 远程连接配对。

## 配置步骤

### 第一步

打开飞书开发者平台并登录:

<https://open.feishu.cn/app?lang=zh-CN>

### 第二步

创建企业自建应用。

### 第三步

添加机器人能力:

添加应用能力 - 机器人 - 添加

### 第四步

开通权限:

权限管理 - 开通权限 - 搜索 `im:` - 选择所有免审权限 - 确认开通权限

### 第五步

复制应用凭证:

凭证与基础信息 - App ID 和 App Secret

### 第六步

打开 BitFun 并启动飞书机器人连接:

远程连接 - IM 机器人 - 飞书机器人 - 填写 App ID 和 App Secret - 连接

### 第七步

回到飞书开发者平台。

### 第八步

配置事件订阅:

事件与回调 - 事件配置 - 订阅方式 - 使用长连接接收事件 - 保存

然后添加消息事件:

添加事件 - 搜索 `im.message` - 全选 - 确认添加

### 第九步

配置回调订阅:

事件与回调 - 回调配置 - 订阅方式 - 使用长连接接收事件 - 保存

然后添加卡片动作回调:

添加回调 - 搜索 `card.action.trigger` - 选中 - 确认添加

### 第十步

发布机器人。

### 第十一步

打开飞书应用,搜索机器人名称,点击机器人打开对话框,输入任意消息并发送。

### 第十二步

输入 BitFun Desktop 显示的 6 位配对码,发送后等待连接成功。
7 changes: 3 additions & 4 deletions src/crates/core/src/agentic/agents/claw_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,9 @@ impl ClawMode {
"SessionMessage".to_string(),
"SessionHistory".to_string(),
"Cron".to_string(),
// All control capabilities (desktop, browser, app, terminal, system)
// are unified under the ControlHub tool. Use ControlHub for
// screenshot, click, click_element, mouse_move, scroll, drag,
// locate, browser CDP automation, and BitFun self-UI control.
// Browser, terminal, and routing metadata live under ControlHub.
// Local desktop/system control is delegated to the ComputerUse
// agent/tool instead of being surfaced as a ControlHub domain.
"ControlHub".to_string(),
],
}
Expand Down
80 changes: 80 additions & 0 deletions src/crates/core/src/agentic/agents/computer_use_mode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//! Computer Use sub-agent
//!
//! Dedicated agent for perceiving and operating the user's local computer.

use super::Agent;
use async_trait::async_trait;

pub struct ComputerUseMode {
default_tools: Vec<String>,
}

impl Default for ComputerUseMode {
fn default() -> Self {
Self::new()
}
}

impl ComputerUseMode {
pub fn new() -> Self {
Self {
default_tools: vec![
"AskUserQuestion".to_string(),
"TodoWrite".to_string(),
"Skill".to_string(),
"Bash".to_string(),
"TerminalControl".to_string(),
"ControlHub".to_string(),
"ComputerUse".to_string(),
],
}
}
}

#[async_trait]
impl Agent for ComputerUseMode {
fn as_any(&self) -> &dyn std::any::Any {
self
}

fn id(&self) -> &str {
"ComputerUse"
}

fn name(&self) -> &str {
"Computer Use"
}

fn description(&self) -> &str {
"Dedicated desktop automation agent for perceiving the local environment and operating apps, browsers, and OS UI"
}

fn prompt_template_name(&self, _model_name: Option<&str>) -> &str {
"computer_use_mode"
}

fn default_tools(&self) -> Vec<String> {
self.default_tools.clone()
}

fn is_readonly(&self) -> bool {
false
}
}

#[cfg(test)]
mod tests {
use super::{Agent, ComputerUseMode};

#[test]
fn computer_use_mode_basics() {
let agent = ComputerUseMode::new();
assert_eq!(agent.id(), "ComputerUse");
assert_eq!(agent.name(), "Computer Use");
assert_eq!(agent.prompt_template_name(None), "computer_use_mode");
assert!(agent.default_tools().contains(&"ControlHub".to_string()));
assert!(agent.default_tools().contains(&"ComputerUse".to_string()));
assert!(!agent.default_tools().contains(&"Write".to_string()));
assert!(!agent.is_readonly());
}
}
2 changes: 1 addition & 1 deletion src/crates/core/src/agentic/agents/cowork_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl Agent for CoworkMode {
}

fn description(&self) -> &str {
"Collaborative mode: clarify first, track progress lightly, verify outcomes"
"Office and collaboration mode for documents, research, drafting, and structured multi-step work"
}

fn prompt_template_name(&self, _model_name: Option<&str>) -> &str {
Expand Down
2 changes: 2 additions & 0 deletions src/crates/core/src/agentic/agents/deep_research_agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ impl DeepResearchAgent {
// Terminal — run commands to gather data (e.g. git log, curl, jq)
"Bash".to_string(),
"TerminalControl".to_string(),
"ControlHub".to_string(),
// Task tracking
"TodoWrite".to_string(),
],
Expand Down Expand Up @@ -85,6 +86,7 @@ mod tests {
assert!(tools.contains(&"Write".to_string()));
assert!(tools.contains(&"Bash".to_string()));
assert!(tools.contains(&"TerminalControl".to_string()));
assert!(tools.contains(&"ControlHub".to_string()));
}

#[test]
Expand Down
2 changes: 2 additions & 0 deletions src/crates/core/src/agentic/agents/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod registry;
// Modes
mod agentic_mode;
mod claw_mode;
mod computer_use_mode;
mod cowork_mode;
mod debug_mode;
mod plan_mode;
Expand All @@ -26,6 +27,7 @@ pub use agentic_mode::AgenticMode;
use async_trait::async_trait;
pub use claw_mode::ClawMode;
pub use code_review_agent::CodeReviewAgent;
pub use computer_use_mode::ComputerUseMode;
pub use cowork_mode::CoworkMode;
pub use custom_subagents::{CustomSubagent, CustomSubagentKind};
pub use debug_mode::DebugMode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,9 +454,9 @@ Do not read from, modify, create, move, or delete files outside this workspace u
if self.context.supports_image_understanding == Some(false) {
result.push_str(
"\n\n# Computer use (text-only primary model)\n\n\
The configured **primary model does not accept image inputs**. When using **`ControlHub`** with **`domain: \"desktop\"`** (or **`domain: \"browser\"`**):\n\
The configured **primary model does not accept image inputs**. When using **`ComputerUse`** (or **`ControlHub`** with **`domain: \"browser\"`**):\n\
- **Do not** use **`screenshot`** (desktop) and **avoid** `domain:\"browser\" action:\"screenshot\"` — the JPEG bytes will be unreadable.\n\
- **ACTION PRIORITY:** 1) Terminal/CLI/system commands (`Bash` tool, or `ControlHub domain:\"system\" action:\"run_script\"`) 2) Keyboard shortcuts (**`key_chord`**, **`type_text`**) 3) UI control: **`click_element`** (AX) → **`locate`** → **`move_to_text`** (use **`move_to_text_match_index`** when multiple OCR hits listed) → **`mouse_move`** (**`use_screen_coordinates`: true** with coordinates from tool JSON) → **`click`**. For browser work prefer `snapshot` → click by `@e*` ref over screenshots.\n\
- **ACTION PRIORITY:** 1) Terminal/CLI/system commands (`Bash` tool, or `ComputerUse` `run_script`) 2) Keyboard shortcuts (**`key_chord`**, **`type_text`**) 3) UI control: **`click_element`** (AX) → **`locate`** → **`move_to_text`** (use **`move_to_text_match_index`** when multiple OCR hits listed) → **`mouse_move`** (**`use_screen_coordinates`: true** with coordinates from tool JSON) → **`click`**. For browser work prefer `snapshot` → click by `@e*` ref over screenshots.\n\
- **Never guess coordinates** — always use precise methods (AX, OCR, system coordinates from tool results, or browser snapshot refs).\n",
);
}
Expand Down
Loading
Loading