- A2uiSubmissionsService/DataSource/BusinessContextService 等构造参数 由 import type 改为值导入,确保 Nest 能解析依赖 - 验证:dev 模式后端正常启动,相关 243 个测试通过
91 lines
3.4 KiB
TypeScript
91 lines
3.4 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
||
import type { AgentToolContext, ToolDef, ToolInputResult } from '../agent-tools/agent-tool.types';
|
||
import { rejectUnknownKeys, optionalString } from '../agent-tools/tools/tool-input';
|
||
import { BusinessContextService } from './business-context.service';
|
||
|
||
interface GetBusinessContextInput {
|
||
workflowKey?: string;
|
||
}
|
||
|
||
/**
|
||
* 让 Agent 获取当前角色可见的业务流程、实体字典与依赖规则。
|
||
*/
|
||
@Injectable()
|
||
export class GetBusinessContextTool implements ToolDef<GetBusinessContextInput> {
|
||
readonly name = 'get_business_context';
|
||
readonly skillKey = 'assistant';
|
||
readonly requiredPermission = 'ai:chat:use';
|
||
readonly description =
|
||
'获取当前账号可见的业务流程(学生教学/住宿计费/教室租赁)、实体字典、阶段依赖与下一步建议。写入或导入前先调用本工具确认前置数据要求。';
|
||
readonly inputSchema = {
|
||
type: 'object',
|
||
properties: {
|
||
workflowKey: {
|
||
type: 'string',
|
||
description: '可选:聚焦某个闭环(student_teaching / dormitory_billing / classroom_rental)',
|
||
maxLength: 50,
|
||
},
|
||
},
|
||
additionalProperties: false,
|
||
};
|
||
|
||
constructor(private readonly service: BusinessContextService) {}
|
||
|
||
validate(input: Record<string, unknown>): ToolInputResult<GetBusinessContextInput> {
|
||
const invalid = rejectUnknownKeys(input, ['workflowKey']);
|
||
if (invalid) return invalid;
|
||
const workflowKey = optionalString(input.workflowKey, 'workflowKey', 50);
|
||
if (!workflowKey.ok) return workflowKey;
|
||
return { ok: true, value: { workflowKey: workflowKey.value } };
|
||
}
|
||
|
||
async execute(input: GetBusinessContextInput, context: AgentToolContext): Promise<unknown> {
|
||
return this.service.getBusinessContext(
|
||
{ permissions: context.permissions, isSuperAdmin: context.isSuperAdmin },
|
||
input.workflowKey,
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 让 Agent 获取指定业务实体的字段字典与关系,用于生成准确表单。
|
||
*/
|
||
@Injectable()
|
||
export class GetEntitySchemaTool implements ToolDef<{ entityKey: string }> {
|
||
readonly name = 'get_entity_schema';
|
||
readonly skillKey = 'assistant';
|
||
readonly requiredPermission = 'ai:chat:use';
|
||
readonly description =
|
||
'获取指定业务实体(student/class/room/occupancy/expense/bill/deposit/classroom/organization/rental 等)的字段字典、枚举来源与关系,render_form 前可按需调用以生成正确字段。';
|
||
readonly inputSchema = {
|
||
type: 'object',
|
||
properties: {
|
||
entityKey: { type: 'string', minLength: 1, maxLength: 50 },
|
||
},
|
||
required: ['entityKey'],
|
||
additionalProperties: false,
|
||
};
|
||
|
||
constructor(private readonly service: BusinessContextService) {}
|
||
|
||
validate(input: Record<string, unknown>): ToolInputResult<{ entityKey: string }> {
|
||
const invalid = rejectUnknownKeys(input, ['entityKey']);
|
||
if (invalid) return invalid;
|
||
if (typeof input.entityKey !== 'string' || !input.entityKey.trim()) {
|
||
return { ok: false, error: 'entityKey 必须是字符串' };
|
||
}
|
||
const entityKey = input.entityKey.trim();
|
||
if (entityKey.length > 50) {
|
||
return { ok: false, error: 'entityKey 长度不能超过 50' };
|
||
}
|
||
return { ok: true, value: { entityKey } };
|
||
}
|
||
|
||
async execute(input: { entityKey: string }, context: AgentToolContext): Promise<unknown> {
|
||
return this.service.getEntitySchema(
|
||
{ permissions: context.permissions, isSuperAdmin: context.isSuperAdmin },
|
||
input.entityKey,
|
||
);
|
||
}
|
||
}
|