@lark-apaas/nestjs-capability
v0.1.2
Published
NestJS capability module for FullStack
Readme
@lark-apaas/nestjs-capability
用于加载和执行能力(插件实例)的 NestJS 模块。
安装
npm install @lark-apaas/nestjs-capability概述
本模块提供以下功能:
- 从
server/capabilities/目录加载能力配置 - 加载并实例化关联的插件
- 多种调用方式(Node 调用、Debug 调用、前端调用)
- 流式调用支持(SSE)
- 模板参数解析
快速开始
模块注册
// app.module.ts
import { CapabilityModule } from '@lark-apaas/nestjs-capability';
import * as path from 'path';
@Module({
imports: [
CapabilityModule.forRoot({
capabilitiesDir: path.join(__dirname, '../capabilities'),
}),
],
})
export class AppModule {}Node 调用
import { Injectable } from '@nestjs/common';
import { CapabilityService } from '@lark-apaas/nestjs-capability';
@Injectable()
export class TaskService {
constructor(private readonly capabilityService: CapabilityService) {}
async onTaskCreated(task: Task) {
const result = await this.capabilityService
.load('create_feishu_group_for_task')
.call('run', {
group_name: `任务群 - ${task.name}`,
creator_id: task.creatorId,
});
return result;
}
}流式调用
用于 LLM 对话等流式输出场景:
@Injectable()
export class ChatService {
constructor(private readonly capabilityService: CapabilityService) {}
async *chat(message: string): AsyncIterable<{ content: string }> {
const stream = this.capabilityService
.load('ai_chat')
.callStream('chat', { message });
for await (const chunk of stream) {
yield chunk as { content: string };
}
}
}普通调用会自动聚合流式结果:
// 即使是流式 action,call() 也会返回聚合后的完整结果
const result = await this.capabilityService
.load('ai_chat')
.call('chat', { message: 'hello' });上下文覆盖
// 覆盖 userContext
const result = await this.capabilityService
.load('notify_task_created')
.call('run', inputParams, {
userContext: {
userId: 'custom-user-id',
tenantId: 'custom-tenant-id',
appId: 'custom-app-id',
},
});
// 设置调试模式(插件可据此返回更详细的错误信息)
const debugResult = await this.capabilityService
.load('ai_chat')
.call('chat', inputParams, {
isDebug: true,
});能力配置
能力配置是位于 server/capabilities/ 目录下的 JSON 文件:
{
"id": "create_feishu_group_for_task",
"pluginID": "@official-components/feishu-group-create",
"pluginVersion": "1.0.5",
"name": "任务创建时自动创建飞书群组",
"description": "在任务创建时,根据任务名称自动生成飞书群组",
"paramsSchema": {
"type": "object",
"properties": {
"group_name": { "type": "string" }
}
},
"formValue": {
"group_name": "{{input.group_name}}",
"members": ["123"]
},
"createdAt": 1764234360374,
"updatedAt": 1764234360374
}模板语法
formValue 字段支持模板占位符:
{{input.xxx}}- 引用用户输入参数{{input.user.name}}- 支持嵌套路径
HTTP API
前端调用
POST /api/capability/:capability_id
请求体:
{
"action": "run",
"params": {
"group_name": "项目A群"
}
}
响应:
{
"code": 0,
"message": "success",
"data": { ... }
}前端流式调用
POST /api/capability/:capability_id/stream
请求体:
{
"action": "chat",
"params": {
"message": "hello"
}
}
响应(SSE 格式):
data: {"content":"Hello"}
data: {"content":" World"}
data: [DONE]Debug 调用(仅开发环境)
POST /__innerapi__/capability/debug/:capability_id
请求体(所有字段可选):
{
"action": "run", // 可选,默认使用插件第一个 action
"params": { // 可选,用户输入参数
"group_name": "测试群"
},
"capability": { // 可选,完整的 capability 配置(优先使用)
"id": "test",
"pluginID": "@test/plugin",
"pluginVersion": "1.0.0",
"name": "测试",
"formValue": {}
}
}
响应:
{
"code": 0,
"message": "success",
"data": { ... },
"debug": {
"capabilityConfig": { ... },
"resolvedParams": { ... },
"duration": 123,
"pluginID": "@xxx/plugin",
"action": "run"
}
}Debug 流式调用(仅开发环境)
POST /__innerapi__/capability/debug/:capability_id/stream
请求体(所有字段可选):
{
"action": "chat",
"params": { "message": "hello" },
"capability": { ... }
}
响应(SSE 格式):
data: {"content":"Hello"}
data: {"content":" World"}
data: [DONE]列出所有能力(仅开发环境)
GET /__innerapi__/capability/list
响应:
{
"code": 0,
"message": "success",
"data": [
{
"id": "create_feishu_group_for_task",
"name": "任务创建时自动创建飞书群组",
"pluginID": "@official-components/feishu-group-create",
"pluginVersion": "1.0.5"
}
]
}服务
CapabilityService
用于加载和执行能力的核心服务。
interface CapabilityService {
// 列出所有已加载的能力
listCapabilities(): CapabilityConfig[];
// 获取指定能力
getCapability(capabilityId: string): CapabilityConfig | null;
// 加载能力并返回执行器
load(capabilityId: string): CapabilityExecutor;
// 使用传入的配置加载能力执行器(用于 debug 场景)
loadWithConfig(config: CapabilityConfig): CapabilityExecutor;
// 设置自定义能力目录
setCapabilitiesDir(dir: string): void;
}
interface CapabilityExecutor {
// 调用能力(流式 action 会自动聚合结果)
call(
actionName: string,
input: unknown,
context?: Partial<PluginActionContext>
): Promise<unknown>;
// 流式调用能力(返回 AsyncIterable)
callStream(
actionName: string,
input: unknown,
context?: Partial<PluginActionContext>
): AsyncIterable<unknown>;
// 检查 action 是否为流式
isStream(actionName: string): Promise<boolean>;
}PluginLoaderService
用于加载和缓存插件实例的服务。
interface PluginLoaderService {
// 加载插件并创建实例(带缓存)
loadPlugin(pluginID: string): PluginInstance;
// 检查插件是否已安装
isPluginInstalled(pluginID: string): boolean;
// 清除插件缓存
clearCache(pluginID?: string): void;
}TemplateEngineService
用于解析 formValue 模板的服务。
interface TemplateEngineService {
resolve(
template: Record<string, unknown>,
input: Record<string, unknown>
): Record<string, unknown>;
}接口定义
CapabilityConfig
interface CapabilityConfig {
id: string; // 能力唯一标识
pluginID: string; // 关联的插件 ID
pluginVersion: string; // 关联的插件版本
name: string; // 能力名称
description: string; // 能力描述
paramsSchema: JSONSchema; // 输入参数 JSON Schema
formValue: Record<string, unknown>; // 参数映射模板
createdAt: number; // 创建时间戳
updatedAt: number; // 更新时间戳
}PluginInstance
interface PluginInstance {
// 执行 action(必需)
run(actionName: string, context: PluginActionContext, input: unknown): Promise<unknown>;
// 流式执行 action(可选)
runStream?(actionName: string, context: PluginActionContext, input: unknown): AsyncIterable<unknown>;
// 检查是否为流式 action(可选)
isStreamAction?(actionName: string): boolean;
// 聚合流式结果(可选,默认返回 chunks 数组)
aggregate?(actionName: string, chunks: unknown[]): unknown;
// Action 相关
hasAction(actionName: string): boolean;
listActions(): string[];
getActionSchema(actionName: string): ActionSchema | null;
getInputSchema(actionName: string, config?: unknown): ZodSchema | undefined;
getOutputSchema(actionName: string, input: unknown, config?: unknown): ZodSchema | undefined;
}PluginActionContext
interface PluginActionContext {
logger: Logger; // 日志记录器
httpClient: PlatformHttpClient; // HTTP 客户端(平台鉴权)
userContext: {
userId: string; // 用户 ID
tenantId: string; // 租户 ID
appId: string; // 应用 ID
};
isDebug: boolean; // 是否为调试模式
}isDebug 说明:
DebugController调用时isDebug = trueWebhookController或其他调用时isDebug = false- 插件可据此返回更详细的错误信息、调试日志等
错误类型
| 错误 | 描述 |
|------|------|
| CapabilityNotFoundError | 指定 ID 的能力不存在 |
| PluginNotFoundError | 插件未安装 |
| PluginLoadError | 插件加载或初始化失败 |
| ActionNotFoundError | 插件中不存在指定的 Action |
模块配置
interface CapabilityModuleOptions {
// 能力配置目录路径(默认:server/capabilities)
capabilitiesDir?: string;
}依赖
@lark-apaas/nestjs-common- 提供 RequestContextService 和 PLATFORM_HTTP_CLIENT@nestjs/common- NestJS 框架
许可证
MIT
