桌面应用部署

使用 Wails、Tauri 或 Electron 构建桌面应用

桌面应用部署

Aster 提供了完整的桌面应用支持,可以与 Wails、Tauri、Electron 等主流桌面框架集成。

🎯 支持的框架

框架语言通信方式特点
WailsGo直接函数调用最高性能,Go 原生
TauriRustHTTP + WebSocket轻量级,Rust 后端
ElectronNode.jsHTTP + WebSocket成熟生态,跨平台

📊 架构设计

graph TB
    subgraph Desktop[桌面应用]
        UI[前端 UI<br/>HTML/CSS/JS]
        Bridge[Framework Bridge]
    end

    subgraph Aster[Aster Core]
        App[Desktop App]
        Agent[Agent]
        Permission[Permission]
        Session[SQLite Session]
    end

    UI <-->|事件/消息| Bridge
    Bridge <-->|通信协议| App
    App --> Agent
    App --> Permission
    App --> Session

    style UI fill:#3b82f6
    style App fill:#10b981
    style Bridge fill:#f59e0b

🚀 快速开始

安装依赖

import "github.com/astercloud/aster/pkg/desktop"

创建桌面应用

import (
    "context"
    "github.com/astercloud/aster/pkg/desktop"
    "github.com/astercloud/aster/pkg/permission"
)

func main() {
    ctx := context.Background()

    // 创建 Permission Inspector
    inspector, _ := permission.NewInspector(
        permission.WithMode(permission.ModeSmartApprove),
    )

    // 创建桌面应用
    app, err := desktop.NewApp(&desktop.Config{
        Framework:  desktop.FrameworkWails, // 或 FrameworkTauri, FrameworkElectron
        Inspector:  inspector,
        DataDir:    "", // 使用默认路径
    })
    if err != nil {
        log.Fatal(err)
    }

    // 启动应用
    if err := app.Start(ctx); err != nil {
        log.Fatal(err)
    }
}

🔧 框架集成

Wails 集成

Wails 使用直接的 Go 函数绑定,性能最高:

package main

import (
    "context"
    "github.com/astercloud/aster/pkg/desktop"
    "github.com/wailsapp/wails/v2"
)

func main() {
    app, _ := desktop.NewApp(&desktop.Config{
        Framework: desktop.FrameworkWails,
    })

    // 获取 Wails 绑定
    bridge := app.Bridge().(*desktop.WailsBridge)

    // Wails 应用配置
    err := wails.Run(&options.App{
        Title:  "Aster Desktop",
        Width:  1024,
        Height: 768,
        Bind: []interface{}{
            bridge, // 绑定 Aster 方法
        },
    })
}

前端调用 (JavaScript):

// 发送消息
const response = await window.go.desktop.WailsBridge.SendMessage(agentId, message);

// 创建 Agent
const agentId = await window.go.desktop.WailsBridge.CreateAgent(config);

// 获取历史
const messages = await window.go.desktop.WailsBridge.GetHistory(agentId);

Tauri 集成

Tauri 使用 HTTP + WebSocket 通信:

package main

import (
    "context"
    "github.com/astercloud/aster/pkg/desktop"
)

func main() {
    app, _ := desktop.NewApp(&desktop.Config{
        Framework: desktop.FrameworkTauri,
        HTTPPort:  8765, // HTTP 端口
        WSPort:    8766, // WebSocket 端口
    })

    // 启动服务
    app.Start(context.Background())

    // Tauri 前端通过 HTTP/WS 连接
}

前端调用 (TypeScript):

// HTTP 请求
const response = await fetch('http://localhost:8765/api/agent/send', {
    method: 'POST',
    body: JSON.stringify({ agent_id: agentId, message: message })
});

// WebSocket 事件流
const ws = new WebSocket('ws://localhost:8766/ws');
ws.onmessage = (event) => {
    const data = JSON.parse(event.data);
    if (data.type === 'text_chunk') {
        appendText(data.delta);
    }
};

Electron 集成

Electron 与 Tauri 类似,使用 HTTP + WebSocket:

package main

import (
    "context"
    "github.com/astercloud/aster/pkg/desktop"
)

func main() {
    app, _ := desktop.NewApp(&desktop.Config{
        Framework: desktop.FrameworkElectron,
        HTTPPort:  8765,
        WSPort:    8766,
    })

    app.Start(context.Background())
}

Electron 主进程:

const { app, BrowserWindow } = require('electron');
const { spawn } = require('child_process');

let asterProcess;

app.whenReady().then(() => {
    // 启动 Aster 后端
    asterProcess = spawn('./aster-desktop');

    // 创建窗口
    const win = new BrowserWindow({
        width: 1024,
        height: 768,
        webPreferences: {
            nodeIntegration: true
        }
    });

    win.loadFile('index.html');
});

app.on('quit', () => {
    asterProcess.kill();
});

📡 API 接口

HTTP API

端点方法说明
/api/agent/createPOST创建 Agent
/api/agent/sendPOST发送消息
/api/agent/statusGET获取状态
/api/agent/historyGET获取历史
/api/agent/closePOST关闭 Agent
/api/permission/approvePOST审批权限请求

WebSocket 事件

interface WSEvent {
    type: 'text_chunk' | 'tool_start' | 'tool_end' | 'permission_required' | 'error';
    agent_id: string;
    data: any;
}

// 文本输出
{ type: 'text_chunk', agent_id: 'xxx', data: { delta: 'Hello' } }

// 工具开始
{ type: 'tool_start', agent_id: 'xxx', data: { tool: 'Read', args: {...} } }

// 工具结束
{ type: 'tool_end', agent_id: 'xxx', data: { tool: 'Read', result: '...' } }

// 权限请求
{ type: 'permission_required', agent_id: 'xxx', data: { request_id: 'xxx', tool: 'Bash', risk: 'high' } }

💾 数据存储

跨平台路径

import "github.com/astercloud/aster/pkg/config"

// 配置目录
configDir := config.ConfigDir()
// macOS: ~/Library/Application Support/aster/
// Linux: ~/.config/aster/
// Windows: %APPDATA%\aster\

// 数据库文件
dbPath := config.DatabaseFile("sessions.db")
// macOS: ~/Library/Application Support/aster/sessions.db

// 日志目录
logDir := config.LogDir()
// macOS: ~/Library/Logs/aster/

SQLite 会话

import "github.com/astercloud/aster/pkg/session/sqlite"

// 创建 SQLite 存储
dbPath := config.DatabaseFile("sessions.db")
store, _ := sqlite.New(dbPath)

// 在 Desktop App 中使用
app, _ := desktop.NewApp(&desktop.Config{
    SessionStore: store,
})

🔐 权限管理

集成 Permission 系统

import "github.com/astercloud/aster/pkg/permission"

inspector, _ := permission.NewInspector(
    permission.WithMode(permission.ModeSmartApprove),
    permission.WithPath(config.ConfigFile("permissions.json")),
)

app, _ := desktop.NewApp(&desktop.Config{
    Inspector: inspector,
})

前端权限 UI

// 监听权限请求
ws.onmessage = (event) => {
    const data = JSON.parse(event.data);
    if (data.type === 'permission_required') {
        showPermissionDialog(data.data);
    }
};

// 发送审批决定
async function approvePermission(requestId: string, approved: boolean) {
    await fetch('http://localhost:8765/api/permission/approve', {
        method: 'POST',
        body: JSON.stringify({
            request_id: requestId,
            approved: approved,
            remember: true // 记住决定
        })
    });
}

📦 打包分发

Wails 打包

# 构建 macOS 应用
wails build -platform darwin/universal

# 构建 Windows 应用
wails build -platform windows/amd64

# 构建 Linux 应用
wails build -platform linux/amd64

Tauri 打包

# 构建所有平台
npm run tauri build

# 指定平台
npm run tauri build -- --target x86_64-apple-darwin

Electron 打包

# 使用 electron-builder
npm run build

# 指定平台
npm run build -- --mac --win --linux

💡 最佳实践

1. 框架选择

场景推荐框架原因
Go 技术栈Wails原生集成,性能最佳
最小体积TauriRust 后端,体积小
丰富生态Electronnpm 生态,插件多

2. 性能优化

// 使用流式输出
app.OnStreamChunk(func(agentID, chunk string) {
    // 实时更新 UI
})

// 缓存会话数据
app.EnableSessionCache(100) // 缓存 100 条消息

3. 安全考虑

// 生产环境使用严格权限
inspector, _ := permission.NewInspector(
    permission.WithMode(permission.ModeSmartApprove),
)

// 限制工具访问
config := &desktop.Config{
    AllowedTools: []string{"Read", "Search", "Write"},
    // 不允许 Bash
}

📚 相关文档

🔗 示例代码

# 运行桌面示例
go run ./examples/desktop/

# 查看示例 README
cat examples/desktop/README.md