# ACP-WS 使用指南

## 简介

ACP-WS 是一个基于 WebSocket 的智能体通信库，提供了智能体身份管理（AgentCP）和 WebSocket 通信（AgentWS）功能。通过 AgentManager 统一管理这些功能，使用更加便捷。

## 快速开始

### 1. 初始化 AgentManager

```typescript
// 获取 AgentManager 单例
const manager = AgentManager.getInstance();

// 初始化 AgentCP（身份管理）
const apiUrl = "https://your-api-url";
const seedPassword = "your-seed-password"; // 可选
const acp = await manager.initACP(apiUrl, seedPassword);
```

### 2. 身份管理

```typescript
// 创建新的智能体身份
const aid = await acp.createAid("your-aid");

// 如果本地只有一个账户，可以直接加载当前账户
const currentAid = await acp.loadCurrentAid();
if (!currentAid) {
    throw new Error("没有可用的身份");
}

// 或者加载指定的身份
const loaded = await acp.loadAid(aid);
if (!loaded) {
    throw new Error("加载身份失败");
}

// 或者导入已有的身份
const identity = {
    aid: "your-aid",
    privateKey: "your-private-key",
    certPem: "your-cert-pem"
};
await acp.importAid(identity, seedPassword);

// 如果没有身份，可以加载访客身份
const guestAid = await acp.loadGuestAid();

// 获取当前可用的身份列表
const aidList = await acp.loadAidList();

// 获取当前身份的证书信息
const certInfo = await acp.getCertInfo(aid);
```

### 3. 上线并建立连接

```typescript
// 获取连接配置
const config = await acp.online();

// 初始化 WebSocket 连接
const aws = await manager.initAWS(aid, config);

// 启动 WebSocket 连接
await aws.startWebSocket();

// 快速连接到指定智能体（推荐方式）
aws.connectTo("target-aid", 
    (sessionInfo) => {
        console.log("会话创建成功:", sessionInfo.sessionId);
        console.log("邀请码:", sessionInfo.identifyingCode);
    },
    (inviteStatus) => {
        console.log("邀请状态:", inviteStatus);
    }
);
```

### 4. 消息通信

```typescript
// 注册状态变更监听
aws.onStatusChange((status) => {
    console.log(`连接状态: ${status}`);
    // status: 'connecting' | 'connected' | 'disconnected' | 'reconnecting' | 'error'
});

// 注册消息接收监听
aws.onMessage((message) => {
    console.log(`收到消息类型: ${message.type}`); // 'success' | 'error'
    console.log(`消息内容: ${message.content}`);
});

// 发送消息到当前会话
aws.send("Hello, Agent!");

// 发送消息到指定智能体
aws.sendTo("specific-agent-id", "Hello, specific agent!");

// 断开连接
aws.disconnect();
```

## 高级用法

### 手动会话管理

如果需要更精细的控制，可以手动管理会话和邀请：

```typescript
// 手动创建会话
aws.createSession((sessionRes) => {
    console.log("会话ID:", sessionRes.sessionId);
    console.log("邀请码:", sessionRes.identifyingCode);
    
    // 手动邀请智能体
    aws.invite(
        "target-agent-id", 
        sessionRes.sessionId, 
        sessionRes.identifyingCode,
        (inviteStatus) => {
            if (inviteStatus === 'success') {
                console.log("邀请成功，可以开始通信");
            } else {
                console.log("邀请失败");
            }
        }
    );
});
```

### React 组件中使用

```typescript
import React, { useEffect, useState } from 'react';
import { AgentManager } from './agent-manager';

const ChatComponent: React.FC = () => {
    const [aws, setAws] = useState<any>(null);
    const [messages, setMessages] = useState<string[]>([]);
    const [connectionStatus, setConnectionStatus] = useState<string>('disconnected');

    useEffect(() => {
        const initAgent = async () => {
            try {
                const manager = AgentManager.getInstance();
                const acp = await manager.initACP("https://api.example.com");
                
                // 加载或创建身份
                let aid = await acp.loadCurrentAid();
                if (!aid) {
                    aid = await acp.loadGuestAid();
                }
                
                // 获取连接配置并初始化WebSocket
                const config = await acp.online();
                const agentWS = await manager.initAWS(aid, config);
                
                // 注册事件监听器
                agentWS.onStatusChange((status) => {
                    setConnectionStatus(status);
                });
                
                agentWS.onMessage((message) => {
                    setMessages(prev => [...prev, message.content]);
                });
                
                // 启动连接
                await agentWS.startWebSocket();
                setAws(agentWS);
                
            } catch (error) {
                console.error("初始化失败:", error);
            }
        };

        initAgent();

        // 清理函数
        return () => {
            if (aws) {
                aws.disconnect();
            }
        };
    }, []);

    const sendMessage = (text: string) => {
        if (aws && connectionStatus === 'connected') {
            aws.send(text);
        }
    };

    const connectToAgent = (targetAid: string) => {
        if (aws) {
            aws.connectTo(targetAid);
        }
    };

    return (
        <div>
            <div>状态: {connectionStatus}</div>
            <div>
                {messages.map((msg, index) => (
                    <div key={index}>{msg}</div>
                ))}
            </div>
            {/* 发送消息和连接的UI组件 */}
        </div>
    );
};
```

## API 参考

### AgentWS 类

#### 方法

- `startWebSocket(): Promise<void>` - 启动WebSocket连接
- `connectTo(receiver, onSessionCreated?, onInviteStatus?): void` - 快捷连接到指定智能体
- `createSession(callback): void` - 创建会话
- `invite(receiver, sessionId, identifyingCode, callback?): void` - 邀请智能体加入会话
- `send(message): void` - 发送消息到当前会话
- `sendTo(receiver, message): void` - 发送消息到指定智能体
- `onStatusChange(callback): void` - 注册状态变更监听器
- `onMessage(callback): void` - 注册消息接收监听器
- `disconnect(): void` - 断开连接

#### 状态类型

```typescript
type ConnectionStatus = 'connecting' | 'connected' | 'disconnected' | 'reconnecting' | 'error';
type InviteStatus = 'success' | 'error';
```

#### 消息类型

```typescript
type ACPMessageResponse = {
    type: 'success' | 'error';
    content: string;
}

type ACPMessageSessionResponse = {
    identifyingCode: string;
    sessionId: string;
}
```

### WSClient 类

底层WebSocket客户端，提供更精细的控制：

- `connectToServer(wsServer, aid, signature): Promise<void>` - 连接到WebSocket服务器
- `createSession(callback): void` - 创建会话（自动清理监听器）
- `invite(receiver, sessionId, identifyingCode, callback?): void` - 发送邀请
- `onStatusChange(callback): () => void` - 注册状态监听器，返回清理函数
- `onMessage(callback): () => void` - 注册消息监听器，返回清理函数
- `send(message): void` - 发送消息
- `sendTo(receiver, message): void` - 发送消息到指定接收者
- `disconnect(): void` - 断开连接并清理所有监听器

## 错误处理

所有关键操作都有适当的错误处理：

- 身份验证失败
- 连接超时
- 消息发送失败
- WebSocket 连接断开
- 参数验证错误

建议使用 try-catch 包装关键操作：

```typescript
try {
    await aws.startWebSocket();
} catch (error) {
    console.error(`WebSocket 连接失败: ${error.message}`);
    // 实现重连逻辑
}
```

### 常见错误处理

```typescript
// 连接错误处理
aws.onStatusChange((status) => {
    switch (status) {
        case 'error':
            console.error("连接出错，尝试重连...");
            // 实现重连逻辑
            break;
        case 'disconnected':
            console.warn("连接断开");
            break;
        case 'connected':
            console.log("连接成功");
            break;
    }
});

// 消息错误处理
aws.onMessage((message) => {
    if (message.type === 'error') {
        console.error("收到错误消息:", message.content);
        // 处理错误情况
    } else {
        // 处理正常消息
        console.log("收到消息:", message.content);
    }
});
```

## 最佳实践

### 1. 资源管理
- 始终使用 AgentManager 来管理实例，避免直接创建 AgentCP 或 AgentWS 实例
- 在应用退出时调用 `disconnect()` 清理资源
- 在React组件中使用useEffect的清理函数来清理WebSocket连接

### 2. 事件处理
- 在初始化 WebSocket 连接后再注册事件监听器
- 使用 WSClient 时记得调用返回的清理函数防止内存泄漏
- 避免在回调函数中执行耗时操作，以免阻塞消息处理

### 3. 异步操作
- 使用 async/await 处理异步操作
- 实现适当的重连机制和错误恢复策略
- 对关键操作添加超时控制

### 4. 安全性
- 妥善保管 seedPassword 和私钥信息
- 验证消息来源和内容的合法性
- 使用HTTPS/WSS协议进行通信

### 5. 性能优化
- 合理使用 `connectTo` 而不是手动管理会话
- 避免频繁创建和销毁连接
- 对大量消息的场景考虑消息批处理

### 6. 调试和监控
- 启用适当的日志记录
- 监控连接状态和消息传输
- 实现健康检查机制

## 故障排除

### 常见问题

1. **连接失败**: 检查网络连接、服务器地址和身份验证信息
2. **消息发送失败**: 确认WebSocket连接状态和会话状态
3. **监听器未清理**: 使用WSClient时记得调用返回的清理函数
4. **重复监听器**: createSession和invite方法已自动处理重复注册问题

### 调试技巧

```typescript
// 启用详细日志
aws.onStatusChange((status) => {
    console.log(`[${new Date().toISOString()}] 状态变更: ${status}`);
});

// 监控消息传输
aws.onMessage((message) => {
    console.log(`[${new Date().toISOString()}] 收到消息:`, message);
});

// 检查当前连接状态
const currentStatus = aws.msgClient.getCurrentStatus();
console.log("当前连接状态:", currentStatus);
```