refactor(storage): 统一消息存储到 Core 层
问题:Server 端只存储最终文本响应,工具调用的中间消息丢失。 解决方案: - Agent.chat() 返回 ChatResult,包含完整消息链 - Server SessionManager 简化为只管理会话元数据 - 消息 API 改为从 Core Storage 读取 - 移除 Server 端的消息存储和 addMessage 方法 影响范围: - core: Agent.chat() 返回类型变更 - server: SessionManager 接口变更,移除消息存储 - server: GET /sessions/:id/messages 从 Core 读取 - server: 移除 POST /sessions/:id/messages 端点
This commit is contained in:
@@ -6,7 +6,7 @@ import {
|
||||
type Tool as AITool,
|
||||
type LanguageModel,
|
||||
} from 'ai';
|
||||
import type { Tool, ToolResult, Message, AgentConfig, UserInput, ContentBlock } from '../types/index.js';
|
||||
import type { Tool, ToolResult, Message, AgentConfig, UserInput, ContentBlock, ChatResult } from '../types/index.js';
|
||||
import { buildZodSchema } from '../types/index.js';
|
||||
import { ToolRegistry } from '../tools/registry.js';
|
||||
import { SessionManager } from '../session/index.js';
|
||||
@@ -311,8 +311,9 @@ export class Agent {
|
||||
* 发送消息并处理响应(流式)
|
||||
* @param userMessage 用户消息文本或包含图片的 UserInput
|
||||
* @param onStream 流式输出回调
|
||||
* @returns ChatResult 包含最终文本和完整的响应消息链
|
||||
*/
|
||||
async chat(userMessage: string | UserInput, onStream?: (text: string) => void): Promise<string> {
|
||||
async chat(userMessage: string | UserInput, onStream?: (text: string) => void): Promise<ChatResult> {
|
||||
// 处理带图片的消息
|
||||
let processedMessage = userMessage;
|
||||
|
||||
@@ -331,7 +332,8 @@ export class Agent {
|
||||
processedMessage = visionResult;
|
||||
} else {
|
||||
// 失败,返回错误信息
|
||||
return '无法处理图片:当前模型不支持图片理解,且 Vision 服务未配置或调用失败。';
|
||||
const errorText = '无法处理图片:当前模型不支持图片理解,且 Vision 服务未配置或调用失败。';
|
||||
return { text: errorText, messages: [] };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -465,7 +467,10 @@ export class Agent {
|
||||
// 持久化会话
|
||||
await this.persistSession();
|
||||
|
||||
return fullResponse;
|
||||
return {
|
||||
text: fullResponse,
|
||||
messages: responseMessages,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,7 +19,7 @@ export { SessionManager } from './session/index.js';
|
||||
export type { SessionData, SessionSummary } from './session/types.js';
|
||||
|
||||
// Types
|
||||
export type { UserInput } from './types/index.js';
|
||||
export type { UserInput, ChatResult } from './types/index.js';
|
||||
|
||||
// Permission
|
||||
export { getPermissionManager } from './permission/index.js';
|
||||
|
||||
@@ -88,6 +88,14 @@ export interface ConversationContext {
|
||||
workingDirectory: string;
|
||||
}
|
||||
|
||||
// Chat 返回结果(包含完整的消息链)
|
||||
export interface ChatResult {
|
||||
/** 最终文本响应 */
|
||||
text: string;
|
||||
/** 完整的响应消息链(包含 tool-call 和 tool-result) */
|
||||
messages: unknown[];
|
||||
}
|
||||
|
||||
// 将自定义 Tool 转换为 Vercel AI SDK 的 zod schema
|
||||
export function buildZodSchema(parameters: Record<string, ToolParameter>): z.ZodObject<Record<string, z.ZodTypeAny>> {
|
||||
const schemaObj: Record<string, z.ZodTypeAny> = {};
|
||||
|
||||
@@ -391,6 +391,7 @@ describe('Agent - chat with images', () => {
|
||||
});
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result.text).toBeDefined();
|
||||
});
|
||||
|
||||
it('不支持 vision 时返回错误消息(Vision 未配置)', async () => {
|
||||
@@ -408,6 +409,6 @@ describe('Agent - chat with images', () => {
|
||||
],
|
||||
});
|
||||
|
||||
expect(result).toContain('无法处理图片');
|
||||
expect(result.text).toContain('无法处理图片');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user