AgentIdentity.java 1.69 KB
package com.xly.agent;

import java.util.Set;

/**
 * 单次 agent 调用的「按调用上下文」身份(架构 §5/§7 的 per-call context)。
 *
 * <p>由 {@code AgentChatController} 从前端请求解析(透传的 ERP 登录 token + 稳定身份),随
 * {@link com.xly.config.AgentFactory} 注入到**每请求新建**的工具实例里——因为 LangChain4j 流式
 * 工具执行发生在模型 HTTP 回调线程而非控制器工作线程,ThreadLocal 不可靠,只能把身份放进工具实例本身。
 *
 * <p>{@link #token} = 透传的用户 ERP 会话 token(可空 → 退回 dev-login)。{@link #grantedModuleIds}
 * = 该用户实际有权的表单/菜单 id 集合({@code null} = 管理员/全部),Read/Query/Write 共用此边界。
 * token 绝不进 prompt / LLM 可见文本。
 */
public final class AgentIdentity {

    private final String token;
    private final String userId;
    private final String brandsId;
    private final Set<String> grantedModuleIds; // null = 全部(管理员)

    public AgentIdentity(String token, String userId, String brandsId, Set<String> grantedModuleIds) {
        this.token = token;
        this.userId = userId;
        this.brandsId = brandsId;
        this.grantedModuleIds = grantedModuleIds;
    }

    /** 透传的用户 token;为空表示回退到 dev-login(本地开发)。 */
    public String token() {
        return token;
    }

    public String userId() {
        return userId;
    }

    public String brandsId() {
        return brandsId;
    }

    public boolean canAccessModule(String moduleId) {
        return grantedModuleIds == null || (moduleId != null && grantedModuleIds.contains(moduleId));
    }
}