UseSkillTool.java 1.84 KB
package com.xly.tool;

import com.xly.service.LedgerService;
import com.xly.service.SkillService;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;

import java.util.Map;

/**
 * useSkill 工具 —— 把某项技能(业务流程的权威步骤文本)载入上下文。
 *
 * <p>返回技能全文(本轮立即可用),同时落 {@code skill_active} 事件:投影层把激活技能的全文
 * 钉在「进行中的流程」卡上(见 EventProjectionService),跨轮续办不丢步骤;提议 executed/cancelled
 * 或新技能激活时摘下。
 *
 * <p>由 {@code AgentFactory} 按请求新建:携带会话 id 用于落账。
 */
public class UseSkillTool {

    private final SkillService skills;
    private final LedgerService ledger;
    private final String convId;

    public UseSkillTool(SkillService skills, LedgerService ledger, String convId) {
        this.skills = skills;
        this.ledger = ledger;
        this.convId = convId;
    }

    @Tool("载入一项技能(业务流程的权威步骤说明),返回完整步骤文本。凡要 新建/报价/问价/修改/作废/审核 等"
            + "会改动数据的业务,或不确定流程怎么走,先用它载入对应技能再动手。技能名见 system prompt 的技能清单。")
    public String useSkill(@P("技能名,如 新建报价 / 修改记录 / 单据状态操作 / 新建单据 / 查询数据") String skillName) {
        SkillService.Skill s = skills.find(skillName);
        if (s == null) {
            StringBuilder sb = new StringBuilder("没有叫「").append(skillName).append("」的技能。可用技能:\n");
            sb.append(skills.indexLines());
            return sb.toString();
        }
        ledger.append(convId, "skill_active", Map.of("name", s.name(), "text", s.body()));
        return s.body();
    }
}