@core-pilot/sdk
v0.0.0-beta.8
Published
`@core-pilot/sdk` 是一个轻量级、框架无关的 JavaScript SDK,旨在帮助开发者快速将 AI 智能助手(Agent)能力集成到现有的 Web 应用中。
Downloads
801
Readme
@core-pilot/sdk
@core-pilot/sdk 是一个轻量级、框架无关的 JavaScript SDK,旨在帮助开发者快速将 AI 智能助手(Agent)能力集成到现有的 Web 应用中。
它提供了开箱即用的 UI 组件、标准化的通信协议抽象(Provider)、以及完善的事件交互机制(HITL),支持与后端 AI 引擎(如 CoreAgent、Dify 等)进行无缝对接。
✨ 核心特性
- ⚡️ 快速集成:通过简单的配置即可挂载完整的 AI 对话界面
- 🔌 多协议支持:内置 CoreAgent 协议支持,架构设计支持扩展 Dify 等其他 Provider
- 🔄 事件驱动架构:提供
subscribeEvent和triggerEvent接口,实现宿主应用与 Agent 之间的双向通信(Code Bridge) - 🔐 灵活鉴权:支持 Client/Server 双模式的 Token 管理
- 🎨 样式隔离:自带完整样式,支持自定义挂载点
- 📝 日志追踪:内置日志系统,支持调试模式和远程日志上报
- ♻️ 生命周期管理:完善的挂载、卸载、重载和销毁机制
📦 安装
# npm
npm install @core-pilot/sdk
# pnpm
pnpm add @core-pilot/sdk
# yarn
yarn add @core-pilot/sdk🚀 快速开始
基础示例
import { createCorePilot } from '@core-pilot/sdk';
import '@core-pilot/sdk/dist/index.css'; // 引入样式
// 1. 初始化 SDK 实例
const pilot = createCorePilot({
// 基础配置
appId: 'your-app-id',
provider: {
name: 'coreagent', // 目前支持 'coreagent' | 'dify'
extensions: {
user: 'default', // 可选:用户标识
}
},
// 鉴权配置
auth: {
mode: 'client', // 'client' | 'server'
token: 'your-api-secret-key',
},
// 挂载配置
mount: {
selector: '#agent-container', // 宿主应用中的 DOM 节点 ID
},
// 可选配置
debug: true, // 开启调试日志
});
// 2. 挂载 UI
pilot.mount();HTML 准备
在你的 HTML 中准备挂载点:
<div id="agent-container" style="width: 100%; height: 600px;"></div>📖 完整功能指南
1. 生命周期管理
SDK 提供了完整的生命周期管理方法,允许你在单页应用 (SPA) 中灵活控制 Agent 的显示与销毁。
挂载 UI
pilot.mount();将 Agent UI 渲染到指定的 DOM 节点。SDK 会在选择器指向的元素内部创建一个 [data-corepilot-host] 容器来挂载 Vue 应用。
卸载 UI
pilot.unmount();卸载 UI 组件并清除 DOM 内容,但保留实例配置。适用于需要临时隐藏 Agent 的场景。
重新加载
// 重新加载(可传入新配置,常用于切换租户或更新 Token)
pilot.reload({
auth: {
mode: 'client',
token: 'new-token'
},
provider: {
name: 'coreagent',
extensions: {
user: 'new-user-id'
}
}
});重载会先卸载现有 UI,更新配置,然后重新挂载。适用于:
- 切换用户/租户
- 更新 Token
- 修改 Provider 配置
销毁实例
pilot.destroy();彻底销毁实例,清理所有资源(清除日志缓冲区、取消订阅等)。通常在应用卸载或路由切换时调用。
2. 双向通信 (Code Bridge / HITL)
这是 SDK 的核心能力之一。通过事件机制,Agent 可以控制宿主应用(例如:Agent 请求打开某个文件),宿主应用也可以向 Agent 发送指令。
事件命名规范
所有的操作 action 分为以下三种类型,及其对应的命名定义:
| 类型 | 前缀 | 说明 | 示例 |
|------|------|------|------|
| 核心业务交互 | core_ | 通过 SDK 与后端进行交互 | core_submit_feedback |
| 内部组件交互 | inner_ | 当前卡片组件纯前端交互(上一步、下一步等) | inner_next_step |
| 自定义事件 | cust_ | 透传到 SDK 外部,供用户调用 | cust_open_file |
订阅 Agent 事件 (Agent → App)
当 Agent 需要执行本地操作(如打开 IDE 文件、跳转页面)时,会下发 cust_ 类型的自定义事件。
// 订阅事件
const handleAgentEvent = (event) => {
console.log('收到 Agent 事件:', event);
// 示例:处理打开文件请求
if (event.action === 'cust_open_file') {
const { filePath, line } = event.payload;
myEditor.open(filePath, line);
}
// 示例:处理跳转页面
if (event.action === 'cust_navigate') {
const { url } = event.payload;
window.location.href = url;
}
};
pilot.subscribeEvent(handleAgentEvent);
// 取消订阅
pilot.unsubscribeEvent(handleAgentEvent);注意:
subscribeEvent支持防重复订阅,多次订阅同一个回调函数只会保留一个。
触发 Agent 行为 (App → Agent)
宿主应用可以主动触发 Agent 的某些行为,或者获取 Agent 的内部数据。
支持的事件类型
| 事件类型 | 说明 | Payload 类型 |
|---------|------|-------------|
| get_suggestion_questions | 获取推荐问题 | ChatMessage |
| get_conversation_list | 获取会话列表 | ConversationRequest |
| get_message_history | 获取消息历史 | MessageHistoryRequest |
| submit_core_action | 提交核心业务场景 | HitlPayload |
| new_message | 打开新对话(重置消息历史) | 无需 payload |
| submit_message | 提交通过对话框输入的消息 | SubmitMessagePayload |
示例 1:获取推荐问题
// 基于当前消息获取下一轮推荐问题
const currentMessage = {
messageId: 'msg-123',
role: 'ai',
content: '已为您分析完成'
};
const questions = await pilot.triggerEvent({
action: 'get_suggestion_questions',
payload: currentMessage
});
console.log('推荐问题:', questions); // ['如何优化性能?', '下一步做什么?']示例 2:获取会话列表
const conversations = await pilot.triggerEvent({
action: 'get_conversation_list',
payload: {
limit: '20',
user: 'default',
last_id: '',
sort_by: '-created_at' // 最新创建的在前
}
});
console.log('会话列表:', conversations);
/*
{
limit: 20,
has_more: false,
data: [
{
id: 'conv-001',
name: '项目重构讨论',
status: 'normal',
created_at: '2025-12-18T10:00:00Z',
...
}
]
}
*/示例 3:获取消息历史
const history = await pilot.triggerEvent({
action: 'get_message_history',
payload: {
conversation_id: 'conv-001',
user: 'default',
first_id: '', // 从最新消息开始
limit: '50'
}
});
console.log('消息历史:', history);
// 返回格式化后的 ChatMessage[] 数组,并自动同步到内部 store示例 4:提交核心业务场景
// 模拟 Agent 执行某个核心操作(如代码审查)
await pilot.triggerEvent({
action: 'submit_core_action',
payload: {
hitlData: {
action: 'core_code_review',
payload: {
filePath: '/src/components/App.tsx',
lineStart: 10,
lineEnd: 50
}
},
text: '请帮我审查这段代码',
prevMessage: lastAiMessage, // 上一条 AI 消息
inputs: {
// 额外的输入参数
language: 'typescript'
}
}
});示例 5:打开新对话
// 重置消息历史,开始新对话
await pilot.triggerEvent({
action: 'new_message'
});示例 6:提交文本消息
// 模拟用户输入并提交消息
await pilot.triggerEvent({
action: 'submit_message',
payload: {
text: '你好,请帮我分析这个错误',
file: {
id: 'file-001',
name: 'error.log',
url: 'https://example.com/files/error.log',
thumbnail: 'https://example.com/files/error.log.thumb'
},
inputs: {
context: 'production'
}
}
});3. 鉴权配置 (Authentication)
SDK 支持两种鉴权模式,适应不同的安全需求。
Client Mode(客户端模式)
直接在前端传入 API Key,适用于开发环境或内网环境。
const pilot = createCorePilot({
appId: 'your-app-id',
provider: { name: 'coreagent' },
auth: {
mode: 'client',
token: 'sk-xxxxxxxxxxxxxxxxxxxxxxxx', // 直接传入 Token
},
mount: {
selector: '#agent-container'
}
});⚠️ 安全提示: Client Mode 会在前端暴露 API Key,仅用于开发测试或安全可控的内网环境。
Server Mode(服务端模式)
通过后端代理转发,前端不暴露 Key,推荐生产环境使用。
const pilot = createCorePilot({
appId: 'your-app-id',
provider: { name: 'coreagent' },
auth: {
mode: 'server',
// 不需要传入 token,SDK 会通过后端获取
},
mount: {
selector: '#agent-container'
}
});实现提示:
- 在 Server Mode 下,SDK 会调用
authManager.getToken()来获取 Token- 当前实现中,你需要在后端提供一个 Token 获取接口
- 可以参考
packages/sdk/packages/core/auth.ts中的 TODO 注释进行自定义实现
4. 调试与日志
SDK 内置了完善的日志系统,支持本地调试和远程日志上报。
开启调试模式
const pilot = createCorePilot({
appId: 'your-app-id',
provider: { name: 'coreagent' },
auth: { mode: 'client', token: 'sk-xxx' },
mount: { selector: '#agent-container' },
debug: true, // 开启调试日志
});开启后,SDK 会在控制台输出详细的运行日志:
- 初始化信息
- 挂载/卸载事件
- HITL 事件提交
- SSE 连接状态
- 错误信息
远程日志上报(可选)
const pilot = createCorePilot({
// ... 其他配置
debug: true,
eventTracker: {
url: 'https://monitor.example.com/log', // 日志上报地址
batchSize: 10, // 批量上报大小(默认 10)
flushInterval: 5000, // 上报间隔(毫秒,默认 5000)
}
});日志系统特性:
- 批量上报: 积累到指定数量后批量发送,减少网络请求
- 定时刷新: 定时发送未满批次的日志
- 销毁前刷新: 调用
destroy()时自动发送剩余日志
5. Provider 配置
SDK 支持多种 AI Provider,目前内置了 CoreAgent 协议。
CoreAgent Provider
const pilot = createCorePilot({
appId: 'your-app-id',
provider: {
name: 'coreagent',
extensions: {
user: 'user-001', // 用户标识,用于会话隔离
}
},
// ... 其他配置
});Dify Provider(架构支持,待实现)
const pilot = createCorePilot({
appId: 'your-app-id',
provider: {
name: 'dify',
extensions: {
// Dify 特有配置
}
},
// ... 其他配置
});扩展提示: 如需添加新的 Provider,可参考
packages/sdk/packages/protocols/coreagent.adapter.ts实现AgentAdapter接口。
📚 API 参考
CorePilotOptions
| 属性 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| appId | string | ✅ | - | Agent 应用 ID |
| provider | AgentProvider | ✅ | - | 协议提供商配置 |
| auth | AuthOptions | ✅ | - | 鉴权配置 |
| mount | MountOptions | ✅ | - | 挂载配置 |
| debug | boolean | ✅ | false | 是否开启调试模式 |
| eventTracker | EventTrackerOptions | ❌ | - | 远程日志上报配置 |
AgentProvider
type AgentProvider = {
name: 'coreagent' | 'dify';
extensions: Record<string, any>; // Provider 特有扩展配置
};AuthOptions
interface AuthOptions {
mode: 'client' | 'server';
token?: string; // client 模式下必填
}MountOptions
interface MountOptions {
selector: string; // CSS 选择器,如 '#app'
container?: HTMLElement; // 可选:限定查找范围
}EventTrackerOptions
interface EventTrackerOptions {
url: string; // 日志上报地址
batchSize?: number; // 批量上报大小(默认 10)
flushInterval?: number; // 上报间隔毫秒数(默认 5000)
}CorePilotInstance
实例方法:
| 方法 | 参数 | 返回值 | 说明 |
|------|------|--------|------|
| mount() | - | void | 挂载 UI 到 DOM |
| unmount() | - | void | 卸载 UI |
| reload(options?) | Partial<CorePilotOptions> | void | 重载实例(可更新配置) |
| destroy() | - | void | 销毁实例(清理所有资源) |
| triggerEvent(event) | TriggerEventPayload | Promise<any> | 主动触发 SDK 内部事件 |
| subscribeEvent(callback) | (event: any) => void | void | 订阅 cust_ 类型事件 |
| unsubscribeEvent(callback) | (event: any) => void | void | 取消订阅 |
TriggerEventPayload
interface TriggerEventPayload {
action:
| 'get_suggestion_questions'
| 'get_conversation_list'
| 'get_message_history'
| 'submit_core_action'
| 'new_message'
| 'submit_message';
payload?:
| ChatMessage
| ConversationRequest
| MessageHistoryRequest
| HitlPayload
| SubmitMessagePayload;
}ChatMessage
interface ChatMessage {
taskId?: string;
role: 'user' | 'ai';
messageId?: string;
conversationId?: string;
content?: string;
questions?: string[];
speed?: number;
showActions?: boolean;
feedback?: 'like' | 'dislike';
files?: Array<{
id: string;
extension: string;
name: string;
}>;
placement?: 'start' | 'end';
avatar?: string;
loading?: boolean;
maxWidth?: string;
isHistoryMessage?: boolean;
// ... 更多 UI 配置属性
}HitlPayload
interface HitlPayload {
hitlData?: {
action: string; // 如 'core_xxx', 'cust_xxx', 'inner_xxx'
payload: any;
};
text?: string; // 文本消息
prevMessage?: ChatMessage; // 上一条消息
inputs?: Record<string, any>; // 额外输入参数
}ConversationRequest
interface ConversationRequest {
limit: string; // 返回数量
user: string; // 用户标识
last_id: string; // 分页:最后一条会话 ID
sort_by: 'created_at' | 'updated_at' | '-created_at' | '-updated_at'; // 排序方式
}MessageHistoryRequest
interface MessageHistoryRequest {
conversation_id: string; // 会话 ID
user: string; // 用户标识
first_id: string; // 分页:第一条消息 ID
limit: string; // 返回数量
}SubmitMessagePayload
interface SubmitMessagePayload {
text: string; // 消息文本
file?: { // 可选:附带文件
id?: string;
name: string;
url: string;
thumbnail?: string;
};
inputs?: Record<string, any>; // 额外输入参数
}🏗️ 项目结构
packages/sdk/
├── packages/
│ ├── core/ # 核心模块
│ │ ├── index.ts # SDK 入口
│ │ ├── auth.ts # 鉴权管理
│ │ ├── hitl.ts # HITL 事件管理
│ │ ├── mount.ts # UI 挂载管理
│ │ └── logger.ts # 日志系统
│ ├── http/ # HTTP 通信
│ │ ├── axios.ts # HTTP 客户端
│ │ └── sse.ts # SSE 流式通信
│ ├── protocols/ # 协议适配器
│ │ ├── index.ts # 适配器工厂
│ │ └── coreagent.adapter.ts # CoreAgent 适配器
│ ├── store/ # 状态管理
│ │ └── index.ts # Zustand Store
│ ├── ui/ # UI 组件
│ │ └── vue/ # Vue 组件
│ │ └── CorePilotHost.tsx
│ └── types.ts # TypeScript 类型定义
├── examples/ # 示例项目
│ └── vueExample/ # Vue 示例
├── dist/ # 构建产物
├── vite.config.ts # 构建配置
└── README.md # 本文档🔧 高级用法
动态切换 Provider
// 初始化时使用 CoreAgent
const pilot = createCorePilot({
provider: { name: 'coreagent' },
// ...
});
// 运行时切换到 Dify(需要后续版本支持)
pilot.reload({
provider: { name: 'dify' },
});🐛 常见问题
1. 挂载点找不到
问题: 控制台报错 Mount point "#agent-container" not found
解决方案:
- 确保 DOM 已经渲染完成后再调用
pilot.mount() - 在 Vue 中使用
nextTick或onMounted - 在 React 中使用
useEffect
// Vue 3
import { nextTick } from 'vue';
nextTick(() => {
pilot.mount();
});
// React
useEffect(() => {
pilot.mount();
return () => pilot.unmount();
}, []);2. Token 鉴权失败
问题: 请求返回 401 Unauthorized
解决方案:
- 检查
auth.token是否正确 - 确认 Token 未过期
- 验证
appId与 Token 匹配
3. 事件回调未触发
问题: subscribeEvent 的回调函数没有执行
解决方案:
- 确认 Agent 下发的事件类型是
cust_前缀 - 检查回调函数是否正确订阅
- 使用
debug: true查看事件流
// 正确的订阅方式
const handleEvent = (event) => {
console.log('Event received:', event);
};
pilot.subscribeEvent(handleEvent);
// 取消订阅时使用同一个函数引用
pilot.unsubscribeEvent(handleEvent);📄 License
MPL-2.0 License
Happy Coding! 🚀
