001/* 002 * Copyright (c) 2023-2026, Agents-Flex (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.agentsflex.core.model.chat; 017 018import com.agentsflex.core.model.client.ChatRequestSpec; 019import com.agentsflex.core.prompt.Prompt; 020 021/** 022 * 聊天上下文管理器,用于在当前线程中保存聊天相关的上下文信息。 023 * <p> 024 * 供日志、监控、拦截器等模块使用。 025 * <p> 026 * 支持同步和流式调用,通过 {@link ChatContextScope} 实现自动清理。 027 */ 028public final class ChatContextHolder { 029 030 private static final ThreadLocal<ChatContext> CONTEXT_HOLDER = new ThreadLocal<>(); 031 032 private ChatContextHolder() { 033 // 工具类,禁止实例化 034 } 035 036 037 /** 038 * 开始一次聊天上下文,并设置传输层请求信息。 039 * 适用于远程 LLM 模型(如 HTTP/gRPC/WebSocket)。 040 * 041 * @param config 聊天配置 042 * @param options 聊天选项 043 * @param prompt 用户提示 044 * @param request 请求信息构建起 045 * @return 可用于 try-with-resources 的作用域对象 046 */ 047 public static ChatContextScope beginChat( 048 Prompt prompt, 049 ChatOptions options, 050 ChatRequestSpec request, 051 ChatConfig config) { 052 053 ChatContext ctx = new ChatContext(); 054 ctx.prompt = prompt; 055 ctx.options = options; 056 ctx.requestSpec = request; 057 ctx.config = config; 058 059 CONTEXT_HOLDER.set(ctx); 060 061 return new ChatContextScope(ctx); 062 } 063 064 /** 065 * 获取当前线程的聊天上下文(可能为 null)。 066 * 067 * @return 聊天上下文,若未设置则返回 null 068 */ 069 public static ChatContext currentContext() { 070 return CONTEXT_HOLDER.get(); 071 } 072 073 /** 074 * 手动清除当前线程的上下文。 075 * <p> 076 * 通常由 {@link ChatContextScope} 自动调用,无需手动调用。 077 */ 078 public static void clear() { 079 CONTEXT_HOLDER.remove(); 080 } 081 082 083 /** 084 * 用于 try-with-resources 的作用域对象,确保上下文自动清理。 085 */ 086 public static class ChatContextScope implements AutoCloseable { 087 088 ChatContext context; 089 090 public ChatContextScope(ChatContext context) { 091 this.context = context; 092 } 093 094 @Override 095 public void close() { 096 clear(); 097 } 098 } 099}