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 { 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): ToolInputResult { 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 { 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): 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 { return this.service.getEntitySchema( { permissions: context.permissions, isSuperAdmin: context.isSuperAdmin }, input.entityKey, ); } }