@cicctencent/agent-server
v0.2.52
Published
Server-layer toolkit for agent-core — Agent initialization, SSE streaming, built-in tools, connectors, chat/settings/memory services with SPI extensibility.
Readme
@cicctencent/agent-server
Server-layer toolkit for @cicctencent/agent-core — Agent 初始化、SSE 流式推送、内置工具、沙箱、MCP 桥接、知识库、Chat/Settings/Memory/Security 服务,通过 SPI 接口实现可定制性。
框架无关:不依赖 Express/Fastify/Koa,通过 SSEResponse 接口适配任意 HTTP 框架。
架构
┌─────────────────────────────────────────────────┐
│ Layer 3: 应用层 (如 workai) │
│ 路由、认证、DB 模型、业务逻辑、doc-generator │
├─────────────────────────────────────────────────┤
│ Layer 2: @cicctencent/agent-server (本包) │
│ Agent 初始化、SSE、Chat、工具、沙箱、MCP 桥接 │
│ KB、安全审计、连接器框架,通过 SPI 自定义 │
├─────────────────────────────────────────────────┤
│ Layer 1: @cicctencent/agent-core │
│ 纯引擎:LLM 编排、工具执行、MCP、Memory、A2A │
└─────────────────────────────────────────────────┘快速开始
import { createAgentServer, createBuiltinTools, createSafetyAuditMiddleware } from '@cicctencent/agent-server';
import { createLLMProvider } from '@cicctencent/agent-core';
import express from 'express';
const app = express();
const server = createAgentServer({
llmProvider: createLLMProvider({
provider: 'openai',
model: 'gpt-4',
apiKey: process.env.OPENAI_API_KEY!,
}),
tools: createBuiltinTools(),
middleware: [createSafetyAuditMiddleware()],
});
// runAgentStream 接收 SSEResponse 接口,Express Response 天然兼容
app.post('/api/work/chat/stream', async (req, res) => {
await server.runAgentStream(res, {
content: req.body.content,
threadId: req.body.threadId,
});
});
app.listen(3000);框架无关
agent-server 不依赖任何 HTTP 框架。runAgentStream / reconnectAgentStream 接收 SSEResponse 接口:
interface SSEResponse {
write(data: string): void;
end(): void;
readonly writableEnded: boolean;
setHeader(name: string, value: string | number): void;
flushHeaders?(): void;
status?(code: number): void;
json?(data: any): void;
}Express Response、Fastify Reply(适配后)、原生 http.ServerResponse 均可适配。
SPI 自定义
agent-server 采用 SPI (Service Provider Interface) 设计模式,所有核心组件都可以替换。
设计原则
┌─────────────────────────────────────────────────────────────┐
│ agent-server SPI │
│ │
│ 核心:只定义接口(能力契约) │
│ ├── SSEResponseAdapter ← SSE 流式响应能力 │
│ ├── ChatStoreProvider ← 对话存储能力 │
│ ├── SettingsProvider ← 设置存储能力 │
│ └── AgentProfileProvider ← Agent Profile 能力 │
│ │
│ 可选:提供参考实现(开箱即用) │
│ ├── KoaSSEAdapter ← Koa/MidwayJS 参考 │
│ ├── ExpressSSEAdapter ← Express 参考 │
│ └── JsonFileStorage ← JSON 文件存储参考 │
│ │
│ 业务层:完全自主 │
│ ├── 直接使用参考实现 │
│ ├── 继承扩展 │
│ └── 完全自己实现 │
└─────────────────────────────────────────────────────────────┘快速示例
import {
createAgentServer,
KoaSSEAdapter,
type ChatStoreProvider,
type BaseThreadEntity,
type BaseMessageEntity,
} from '@cicctencent/agent-server';
// 1. 定义自定义实体(可以添加额外字段)
interface MyThread extends BaseThreadEntity {
userId: string; // 额外字段
applicationId: number; // 额外字段
}
// 2. 实现 ChatStoreProvider(使用任意存储技术)
class MyChatStore implements ChatStoreProvider<MyThread, MyMessage> {
async getThreads(userId?: string): Promise<MyThread[]> {
// 使用 TypeORM / Prisma / Mongoose / 任意存储
return this.database.query('SELECT * FROM threads WHERE userId = ?', userId);
}
// ... 实现其他方法
}
// 3. 创建 AgentServer,注入自定义实现
const server = createAgentServer({
llmProvider: myProvider,
chatStoreProvider: new MyChatStore(), // 替换默认实现
});
// 4. 在 MidwayJS/Koa 中使用 SSE 适配器
@Get('/chat/stream')
async chatStream(@Ctx() ctx: Context) {
const adapter = new KoaSSEAdapter(ctx);
await server.runAgentStream(adapter, { content: 'Hello' });
}组件级使用(不依赖工厂)
import {
KoaSSEAdapter,
writeSSE,
createBuiltinTools,
MemoryService,
} from '@cicctencent/agent-server';
// 只使用需要的组件,不使用 createAgentServer
const tools = createBuiltinTools();
const memoryService = new MemoryService('./data');
@Get('/stream')
async stream(@Ctx() ctx: Context) {
const adapter = new KoaSSEAdapter(ctx);
writeSSE(adapter, 'start', { message: 'Hello' });
}SPI 接口清单
| 接口 | 默认实现 | 用途 |
|------|---------|------|
| SettingsProvider<TSettings> | DefaultSettingsProvider | 设置持久化(泛型) |
| ChatStoreProvider<TThread, TMessage> | DefaultChatStoreProvider | 对话 CRUD + 历史重建(泛型) |
| PromptBuilderProvider | DefaultPromptBuilder | 系统提示词构建 |
| ModelConfigResolver | — | 模型配置解析 |
| MCPServiceProvider | — | MCP 服务器管理 |
| SkillServiceProvider | — | 技能 CRUD 管理 |
| ConnectorServiceProvider | — | 数据源连接器管理 |
| AgentProfileProvider<TProfile> | DefaultAgentProfileProvider | 多 Agent 配置管理(泛型) |
| SSEResponseAdapter | KoaSSEAdapter / ExpressSSEAdapter | SSE 流式响应适配 |
| KVStorageAdapter | JsonFileKVStorage | 键值存储抽象 |
| ListStorageAdapter<T> | JsonFileListStorage | 列表存储抽象 |
详细文档
完整的 SPI 使用指南请参考 src/spi/README.md,包含:
- 所有接口的详细定义
- TypeORM / Prisma / Mongoose 实现示例
- MidwayJS + TypeORM 完整模板
- 常见问题解答
模块清单
核心工厂
createAgentServer(options)— 创建 AgentServer 实例
默认 SPI 实现
DefaultSettingsProvider— JSON 文件设置存储DefaultChatStoreProvider— JSON 文件对话存储 + 历史重建DefaultAgentProfileProvider— JSON 文件 Agent Profile 管理DefaultPromptBuilder— 系统提示词构建器
服务
MemoryService/getMemoryService()— 长期记忆持久化getEnginePool()— AgentEngine 实例复用池getRunRegistry()— Agent 运行会话注册表getSecurityPolicy()/updateSecurityPolicy()— 安全策略管理assessToolRisk()/isLowRiskTool()— 工具风险评估createPermissionRequest()/findApprovedPermission()— 权限审批appendAuditLog()/listAuditLogs()— 审计日志createSafetyAuditMiddleware()— 安全审计中间件logEvent()/setLogTransport()— 可观测性saveArtifact()/resolveArtifactPath()/getMimeType()— Artifact 存储getWorkspaces()/createWorkspace()/ensureDefaultWorkspace()— 工作空间 CRUD
SSE
writeSSE()/initSSEResponse()— SSE 事件写入(框架无关)runAgentSSEStream()— Agent SSE 流式推送
内置工具
createBuiltinTools(options?)— 聚合所有内置工具(含 docgen)createFilesystemTools()— execute_command, read_terminal, write_file, read_file, search_code, edit_file, append_filecreateDiscoveryTools()— read_tool_doc, load_skill, read_tool_result, read_offloadcreateWebTools()— web_fetch, http_request, browser_navigatecreateMemoryTools()— save_memory, recall_memory, delete_memorycreateSandboxTools()— run_script, show_widget, save_artifactcreateCommunicationTools()— send_email, create_event, list_eventscreateAutomationTools()— create_automation, list_automations, delete_automationcreateGitTools()— git_status, git_diff, git_commit, git_logcreateDocgenTools(options?)— create_presentation, create_document, create_pdf, create_report
文档生成(docgen)
createBuiltinTools() / createDocgenTools() 支持 options.templatesDir 指定应用层主题模板根目录:
const tools = createBuiltinTools({
templatesDir: '/abs/path/to/your-app/data/doc-templates',
});主题解析优先级:options.templatesDir → 消费方数据目录 getProjectDataPath('doc-templates') → 代码内置 DEFAULT_THEME(始终可用)。也可在运行时通过 ToolContext.custom.templatesDir 按请求覆盖。
⚠️ 文档生成依赖
ctx.custom.sandbox与ctx.emitArtifact(由引擎注入),请确保运行时上下文携带这些字段。 完整的主题目录布局、Schema 与接入示例见仓库 docs/DOCGEN.md。
工具执行器
LocalShellExecutor— 基于 child_process 的 Shell 执行器LocalFileSystemExecutor— 基于 fs/promises 的文件系统执行器
沙箱
LocalSandbox— 进程级沙箱实例(隔离文件系统 + Shell + 脚本执行)LocalSandboxManager/getSandboxManager()— 沙箱生命周期管理器ProcessCodeSandbox— 结构化代码执行沙箱(stdout/stderr/files/charts)SandboxFileSystemExecutor— 沙箱内文件系统执行器(路径穿越防护)SandboxShellExecutor— 沙箱内 Shell 执行器(命令黑名单 + 环境变量过滤)
MCP 桥接
ApiBridgeClient— HTTP API → MCP 桥接客户端buildFromTemplate— 通用模板请求构建器(配置驱动)resolveBodyTemplate()—${param|default}模板解析importFromOpenAPI()— OpenAPI 3.x / Swagger 2.0 → MCP 工具定义- 类型:
RequestBuilderFn,AuthConfig,ResponseConfig,TemplateBuilderExtra
知识库
FileKnowledgeBase— 基于文件的知识库(文档分块 + embedding 存储)EmbeddingVectorIndex— 基于 Embedding 的向量索引parseDocument()— 文档解析与分块(Markdown/TXT/JSON)
连接器
registerAdapter()/getAdapter()— 数据源适配器注册表
存储
JsonStore/JsonListStore— 通用 JSON 文件存储McpServerStore— 目录型 MCP 服务器存储getToolResultStore()— 工具结果存储单例FileNoteStore— 工作空间笔记存储(agent.md)WorkspaceStore/getWorkspaceStore()— 工作空间存储AutomationStore/getAutomationStore()— 自动化任务存储AutomationRunStore/getAutomationRunStore()— 自动化执行记录存储
数据模型
AutomationEntity/AutomationRunEntity/AutomationStatus— 自动化任务类型
工具函数
getProjectDataPath()/ensureDataDir()— 数据目录管理expandEnvVars()— 环境变量展开setAppName()/getAppName()— 应用名设置ensureDefaultData()— 默认数据文件复制
AgentServer API
interface AgentServer {
agentSystem: AgentSystem;
registerTool(tool): void;
unregisterTool(name): void;
registerMiddleware(mw): void;
unregisterMiddleware(name): void;
runAgentStream(res: SSEResponse, params: RunAgentParams, signal?): Promise<void>;
reconnectAgentStream(res: SSEResponse, threadId): Promise<void>;
getEngineForProfile(profileId?, canDelegateOverride?): Promise<AgentEngine>;
abortAgent(threadId): boolean;
steerAgent(sessionId, message): boolean;
clearEnginePool(): void;
refreshLLMConfig(): void;
refreshAgentConfig(): void;
getRegisteredTools(): ToolInfo[];
getLoadedSkills(): SkillInfo[];
isAgentAvailable(): boolean;
checkRunStatus(threadId): RunStatus;
providers: { ... };
}RunAgentParams
interface RunAgentParams {
content: string | ContentPart[]; // 用户输入
threadId?: string; // 对话线程 ID(不传则不持久化)
agentProfileId?: number; // Agent Profile ID
traceId?: string; // 追踪 ID
tenant?: TenantContext; // 多租户上下文
allowedSpecialistIds?: number[]; // 允许委派的 Specialist ID 列表
customContext?: Record<string, unknown>; // 自定义上下文
testMode?: boolean; // 测试模式:禁用委派,不持久化
}getEngineForProfile(profileId?, canDelegateOverride?)
获取指定 Profile 的 AgentEngine 实例(带缓存)。
profileId— Agent Profile ID,不传使用默认canDelegateOverride— 强制覆盖委派策略(false= 禁用委派,用于测试模式)- 返回带
delegate_task工具的引擎(如果canDelegate为true) - 测试模式使用独立缓存 key(
_nodelegate),不污染正常引擎缓存
REST A2A 自定义 Action
远程 REST A2A Agent 支持自定义 action 后缀,通过 restA2AConfig 配置:
restA2AConfig: {
capabilityId: 'data_query_assistant',
streamAction: 'stream', // 流式端点后缀,默认 'stream'
invokeAction: 'run', // 同步端点后缀,默认 'invoke'
fallbackToSync: false, // 流式失败时不回退到同步
}URL 构建规则:
- 用户配置的
remoteUrl如果已带 action 后缀(如.../data_query_assistant:stream),系统会自动剥离旧后缀,再拼接配置的 action - 如果 URL 不含
/capabilities/路径,系统会自动补全/api/v1/a2a/capabilities/{capabilityId}前缀
Optional Dependencies
以下依赖为可选(optionalDependencies),仅在用到对应功能时需要安装:
| 依赖 | 用途 |
|------|------|
| jsonpath-plus | MCP api-bridge 响应提取 |
| @apidevtools/swagger-parser | OpenAPI 导入 |
| fast-glob | search_code 工具 |
| turndown / html-to-text | web_fetch 工具 HTML 转换 |
| cheerio / axios / socks-proxy-agent | web_fetch / http_request 工具 |
| simple-git | git 工具 |
未安装时对应工具会在运行时报错,不影响其他功能。
构建
cd packages/agent-server
npm run build