@lobehub/lobehub 2.0.0-next.49 → 2.0.0-next.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.50](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.49...v2.0.0-next.50)
6
+
7
+ <sup>Released on **2025-11-13**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Fix oidc accountId mismatch.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Fix oidc accountId mismatch, closes [#10058](https://github.com/lobehub/lobe-chat/issues/10058) ([0692ba7](https://github.com/lobehub/lobe-chat/commit/0692ba7))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
5
30
  ## [Version 2.0.0-next.49](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.48...v2.0.0-next.49)
6
31
 
7
32
  <sup>Released on **2025-11-13**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "fixes": [
5
+ "Fix oidc accountId mismatch."
6
+ ]
7
+ },
8
+ "date": "2025-11-13",
9
+ "version": "2.0.0-next.50"
10
+ },
2
11
  {
3
12
  "children": {
4
13
  "features": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.0.0-next.49",
3
+ "version": "2.0.0-next.50",
4
4
  "description": "LobeHub - an open-source,comprehensive AI Agent framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -2,23 +2,23 @@ import type { ContextProcessor, PipelineContext, ProcessorOptions } from '../typ
2
2
  import { ProcessorError } from '../types';
3
3
 
4
4
  /**
5
- * 基础处理器抽象类
6
- * 提供通用的处理器功能和错误处理
5
+ * Base processor abstract class
6
+ * Provides common processor functionality and error handling
7
7
  */
8
8
  export abstract class BaseProcessor implements ContextProcessor {
9
9
  abstract readonly name: string;
10
10
 
11
- // 为了兼容现有子类构造函数签名,保留参数但不做任何处理
11
+ // Keep parameters for compatibility with existing subclass constructor signatures, but do no processing
12
12
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
13
13
  constructor(_options: ProcessorOptions = {}) {}
14
14
 
15
15
  /**
16
- * 核心处理方法 - 子类需要实现
16
+ * Core processing method - subclasses need to implement
17
17
  */
18
18
  protected abstract doProcess(context: PipelineContext): Promise<PipelineContext>;
19
19
 
20
20
  /**
21
- * 公共处理入口,包含错误处理和日志
21
+ * Public processing entry point, includes error handling and logging
22
22
  */
23
23
  async process(context: PipelineContext): Promise<PipelineContext> {
24
24
  try {
@@ -29,32 +29,32 @@ export abstract class BaseProcessor implements ContextProcessor {
29
29
  } catch (error) {
30
30
  throw new ProcessorError(
31
31
  this.name,
32
- `处理失败: ${error}`,
32
+ `Processing failed: ${error}`,
33
33
  error instanceof Error ? error : new Error(String(error)),
34
34
  );
35
35
  }
36
36
  }
37
37
 
38
38
  /**
39
- * 验证输入上下文
39
+ * Validate input context
40
40
  */
41
41
  protected validateInput(context: PipelineContext): void {
42
42
  if (!context || !Array.isArray(context.messages)) {
43
- throw new Error('无效的上下文');
43
+ throw new Error('Invalid context');
44
44
  }
45
45
  }
46
46
 
47
47
  /**
48
- * 验证输出上下文
48
+ * Validate output context
49
49
  */
50
50
  protected validateOutput(context: PipelineContext): void {
51
51
  if (!context || !Array.isArray(context.messages)) {
52
- throw new Error('无效的输出上下文');
52
+ throw new Error('Invalid output context');
53
53
  }
54
54
  }
55
55
 
56
56
  /**
57
- * 安全地克隆上下文
57
+ * Safely clone context
58
58
  */
59
59
  protected cloneContext(context: PipelineContext): PipelineContext {
60
60
  return {
@@ -65,7 +65,7 @@ export abstract class BaseProcessor implements ContextProcessor {
65
65
  }
66
66
 
67
67
  /**
68
- * 中止管道处理
68
+ * Abort pipeline processing
69
69
  */
70
70
  protected abort(context: PipelineContext, reason: string): PipelineContext {
71
71
  return {
@@ -76,7 +76,7 @@ export abstract class BaseProcessor implements ContextProcessor {
76
76
  }
77
77
 
78
78
  /**
79
- * 检查消息是否为空
79
+ * Check if message is empty
80
80
  */
81
81
  protected isEmptyMessage(message: string | undefined | null): boolean {
82
82
  return !message || message.trim().length === 0;
@@ -2,10 +2,10 @@ import type { PipelineContext } from '../types';
2
2
  import { BaseProcessor } from './BaseProcessor';
3
3
 
4
4
  /**
5
- * 极简 Provider:约束为“注入系统消息到开头”这一单一职责
5
+ * Minimal Provider: constrained to the single responsibility of "injecting system message at the beginning"
6
6
  */
7
7
  export abstract class BaseProvider extends BaseProcessor {
8
- // 子类可选择实现;默认不构建额外上下文
8
+ // Subclasses can optionally implement; by default no additional context is built
9
9
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
10
10
  protected async buildContext(_context: PipelineContext): Promise<string | null> {
11
11
  return null;
@@ -96,7 +96,7 @@ describe('BaseProcessor', () => {
96
96
  const invalidContext = { messages: 'not an array' } as any;
97
97
 
98
98
  await expect(processor.process(invalidContext)).rejects.toThrow(ProcessorError);
99
- await expect(processor.process(invalidContext)).rejects.toThrow('无效的上下文');
99
+ await expect(processor.process(invalidContext)).rejects.toThrow('Invalid context');
100
100
  });
101
101
 
102
102
  it('should validate output context', async () => {
@@ -104,7 +104,7 @@ describe('BaseProcessor', () => {
104
104
  const context = createContext([{ content: 'test', role: 'user' }]);
105
105
 
106
106
  await expect(processor.process(context)).rejects.toThrow(ProcessorError);
107
- await expect(processor.process(context)).rejects.toThrow('无效的输出上下文');
107
+ await expect(processor.process(context)).rejects.toThrow('Invalid output context');
108
108
  });
109
109
 
110
110
  it('should wrap errors in ProcessorError', async () => {
@@ -145,13 +145,13 @@ describe('BaseProcessor', () => {
145
145
  it('should reject null context', async () => {
146
146
  const processor = new TestProcessor();
147
147
 
148
- await expect(processor.process(null as any)).rejects.toThrow('无效的上下文');
148
+ await expect(processor.process(null as any)).rejects.toThrow('Invalid context');
149
149
  });
150
150
 
151
151
  it('should reject undefined context', async () => {
152
152
  const processor = new TestProcessor();
153
153
 
154
- await expect(processor.process(undefined as any)).rejects.toThrow('无效的上下文');
154
+ await expect(processor.process(undefined as any)).rejects.toThrow('Invalid context');
155
155
  });
156
156
 
157
157
  it('should reject context without messages array', async () => {
@@ -162,7 +162,7 @@ describe('BaseProcessor', () => {
162
162
  metadata: {},
163
163
  } as any;
164
164
 
165
- await expect(processor.process(invalidContext)).rejects.toThrow('无效的上下文');
165
+ await expect(processor.process(invalidContext)).rejects.toThrow('Invalid context');
166
166
  });
167
167
  });
168
168
 
@@ -6,8 +6,8 @@ import type { PipelineContext, ProcessorOptions } from '../types';
6
6
  const log = debug('context-engine:processor:MessageCleanupProcessor');
7
7
 
8
8
  /**
9
- * 消息清理处理器
10
- * 负责清理消息中的多余字段,只保留 OpenAI 格式所需的必要字段
9
+ * Message Cleanup Processor
10
+ * Responsible for cleaning up redundant fields in messages, keeping only necessary fields required by OpenAI format
11
11
  */
12
12
  export class MessageCleanupProcessor extends BaseProcessor {
13
13
  readonly name = 'MessageCleanupProcessor';
@@ -21,7 +21,7 @@ export class MessageCleanupProcessor extends BaseProcessor {
21
21
 
22
22
  let cleanedCount = 0;
23
23
 
24
- // 清理每条消息,只保留必要字段
24
+ // Clean each message, keeping only necessary fields
25
25
  for (let i = 0; i < clonedContext.messages.length; i++) {
26
26
  const message = clonedContext.messages[i];
27
27
  const cleanedMessage = this.cleanMessage(message);
@@ -32,7 +32,7 @@ export class MessageCleanupProcessor extends BaseProcessor {
32
32
  }
33
33
  }
34
34
 
35
- // 更新元数据
35
+ // Update metadata
36
36
  clonedContext.metadata.messageCleanup = {
37
37
  cleanedCount,
38
38
  totalMessages: clonedContext.messages.length,
@@ -43,7 +43,7 @@ export class MessageCleanupProcessor extends BaseProcessor {
43
43
  }
44
44
 
45
45
  /**
46
- * 清理单条消息,只保留必要字段
46
+ * Clean a single message, keeping only necessary fields
47
47
  */
48
48
  private cleanMessage(message: any): any {
49
49
  switch (message.role) {
@@ -80,7 +80,7 @@ export class MessageCleanupProcessor extends BaseProcessor {
80
80
  }
81
81
 
82
82
  default: {
83
- // 对于未知角色,保持原样
83
+ // For unknown roles, keep as is
84
84
  return message;
85
85
  }
86
86
  }
@@ -64,7 +64,7 @@ export class MessageContentProcessor extends BaseProcessor {
64
64
  let userMessagesProcessed = 0;
65
65
  let assistantMessagesProcessed = 0;
66
66
 
67
- // 处理每条消息的内容
67
+ // Process the content of each message
68
68
  for (let i = 0; i < clonedContext.messages.length; i++) {
69
69
  const message = clonedContext.messages[i];
70
70
 
@@ -91,11 +91,11 @@ export class MessageContentProcessor extends BaseProcessor {
91
91
  }
92
92
  } catch (error) {
93
93
  log.extend('error')(`Error processing message ${message.id} content: ${error}`);
94
- // 继续处理其他消息
94
+ // Continue processing other messages
95
95
  }
96
96
  }
97
97
 
98
- // 更新元数据
98
+ // Update metadata
99
99
  clonedContext.metadata.messageContentProcessed = processedCount;
100
100
  clonedContext.metadata.userMessagesProcessed = userMessagesProcessed;
101
101
  clonedContext.metadata.assistantMessagesProcessed = assistantMessagesProcessed;
@@ -163,14 +163,14 @@ export class MessageContentProcessor extends BaseProcessor {
163
163
  contentParts.push(...videoContentParts);
164
164
  }
165
165
 
166
- // 明确返回的字段,只保留必要的消息字段
166
+ // Explicitly return fields, keeping only necessary message fields
167
167
  const hasFileContext = (hasFiles || hasImages || hasVideos) && this.config.fileContext?.enabled;
168
168
  const hasVisionContent =
169
169
  hasImages && this.config.isCanUseVision?.(this.config.model, this.config.provider);
170
170
  const hasVideoContent =
171
171
  hasVideos && this.config.isCanUseVideo?.(this.config.model, this.config.provider);
172
172
 
173
- // 如果只有文本内容且没有添加文件上下文也没有视觉/视频内容,返回纯文本
173
+ // If only text content and no file context added and no vision/video content, return plain text
174
174
  if (
175
175
  contentParts.length === 1 &&
176
176
  contentParts[0].type === 'text' &&
@@ -185,7 +185,7 @@ export class MessageContentProcessor extends BaseProcessor {
185
185
  meta: message.meta,
186
186
  role: message.role,
187
187
  updatedAt: message.updatedAt,
188
- // 保留其他可能需要的字段,但移除已处理的文件相关字段
188
+ // Keep other potentially needed fields, but remove processed file-related fields
189
189
  ...(message.tools && { tools: message.tools }),
190
190
  ...(message.tool_calls && { tool_calls: message.tool_calls }),
191
191
  ...(message.tool_call_id && { tool_call_id: message.tool_call_id }),
@@ -193,7 +193,7 @@ export class MessageContentProcessor extends BaseProcessor {
193
193
  };
194
194
  }
195
195
 
196
- // 返回结构化内容
196
+ // Return structured content
197
197
  return {
198
198
  content: contentParts,
199
199
  createdAt: message.createdAt,
@@ -201,7 +201,7 @@ export class MessageContentProcessor extends BaseProcessor {
201
201
  meta: message.meta,
202
202
  role: message.role,
203
203
  updatedAt: message.updatedAt,
204
- // 保留其他可能需要的字段,但移除已处理的文件相关字段
204
+ // Keep other potentially needed fields, but remove processed file-related fields
205
205
  ...(message.tools && { tools: message.tools }),
206
206
  ...(message.tool_calls && { tool_calls: message.tool_calls }),
207
207
  ...(message.tool_call_id && { tool_call_id: message.tool_call_id }),
@@ -210,10 +210,10 @@ export class MessageContentProcessor extends BaseProcessor {
210
210
  }
211
211
 
212
212
  /**
213
- * 处理助手消息内容
213
+ * Process assistant message content
214
214
  */
215
215
  private async processAssistantMessage(message: any): Promise<any> {
216
- // 检查是否有推理内容(thinking mode
216
+ // Check if there is reasoning content (thinking mode)
217
217
  const shouldIncludeThinking = message.reasoning && !!message.reasoning?.signature;
218
218
 
219
219
  if (shouldIncludeThinking) {
@@ -235,11 +235,11 @@ export class MessageContentProcessor extends BaseProcessor {
235
235
  };
236
236
  }
237
237
 
238
- // 检查是否有图片(助手消息也可能包含图片)
238
+ // Check if there are images (assistant messages may also contain images)
239
239
  const hasImages = message.imageList && message.imageList.length > 0;
240
240
 
241
241
  if (hasImages && this.config.isCanUseVision?.(this.config.model, this.config.provider)) {
242
- // 创建结构化内容
242
+ // Create structured content
243
243
  const contentParts: UserMessageContentPart[] = [];
244
244
 
245
245
  if (message.content) {
@@ -249,7 +249,7 @@ export class MessageContentProcessor extends BaseProcessor {
249
249
  });
250
250
  }
251
251
 
252
- // 处理图片内容
252
+ // Process image content
253
253
  const imageContentParts = await this.processImageList(message.imageList || []);
254
254
  contentParts.push(...imageContentParts);
255
255
 
@@ -259,7 +259,7 @@ export class MessageContentProcessor extends BaseProcessor {
259
259
  };
260
260
  }
261
261
 
262
- // 普通助手消息,返回纯文本内容
262
+ // Regular assistant message, return plain text content
263
263
  return {
264
264
  ...message,
265
265
  content: message.content,
@@ -267,7 +267,7 @@ export class MessageContentProcessor extends BaseProcessor {
267
267
  }
268
268
 
269
269
  /**
270
- * 处理图片列表
270
+ * Process image list
271
271
  */
272
272
  private async processImageList(imageList: any[]): Promise<UserMessageContentPart[]> {
273
273
  if (!imageList || imageList.length === 0) {
@@ -293,7 +293,7 @@ export class MessageContentProcessor extends BaseProcessor {
293
293
  }
294
294
 
295
295
  /**
296
- * 处理视频列表
296
+ * Process video list
297
297
  */
298
298
  private async processVideoList(videoList: any[]): Promise<UserMessageContentPart[]> {
299
299
  if (!videoList || videoList.length === 0) {
@@ -309,7 +309,7 @@ export class MessageContentProcessor extends BaseProcessor {
309
309
  }
310
310
 
311
311
  /**
312
- * 验证内容部分格式
312
+ * Validate content part format
313
313
  */
314
314
  private validateContentPart(part: UserMessageContentPart): boolean {
315
315
  if (!part || !part.type) return false;
@@ -133,7 +133,7 @@ export class PlaceholderVariablesProcessor extends BaseProcessor {
133
133
  `Starting placeholder variables processing with ${Object.keys(this.config.variableGenerators).length} generators`,
134
134
  );
135
135
 
136
- // 处理每条消息的占位符变量
136
+ // Process placeholder variables for each message
137
137
  for (let i = 0; i < clonedContext.messages.length; i++) {
138
138
  const message = clonedContext.messages[i];
139
139
 
@@ -148,11 +148,11 @@ export class PlaceholderVariablesProcessor extends BaseProcessor {
148
148
  }
149
149
  } catch (error) {
150
150
  log.extend('error')(`Error processing placeholders in message ${message.id}: ${error}`);
151
- // 继续处理其他消息
151
+ // Continue processing other messages
152
152
  }
153
153
  }
154
154
 
155
- // 更新元数据
155
+ // Update metadata
156
156
  clonedContext.metadata.placeholderVariablesProcessed = processedCount;
157
157
 
158
158
  log(`Placeholder variables processing completed, processed ${processedCount} messages`);
@@ -161,7 +161,7 @@ export class PlaceholderVariablesProcessor extends BaseProcessor {
161
161
  }
162
162
 
163
163
  /**
164
- * 处理单个消息的占位符变量
164
+ * Process placeholder variables for a single message
165
165
  */
166
166
  private processMessagePlaceholders(message: any, depth: number): any {
167
167
  if (!message?.content) return message;
@@ -41,7 +41,7 @@ export class ToolCallProcessor extends BaseProcessor {
41
41
  let toolCallsConverted = 0;
42
42
  let toolMessagesConverted = 0;
43
43
 
44
- // 处理每条消息的工具调用
44
+ // Process tool calls for each message
45
45
  for (let i = 0; i < clonedContext.messages.length; i++) {
46
46
  const message = clonedContext.messages[i];
47
47
 
@@ -52,7 +52,7 @@ export class ToolCallProcessor extends BaseProcessor {
52
52
  processedCount++;
53
53
  clonedContext.messages[i] = updatedMessage;
54
54
 
55
- // 统计转换的工具调用和工具消息数量
55
+ // Count converted tool calls and tool messages
56
56
  if (message.role === 'assistant' && message.tools) {
57
57
  toolCallsConverted += message.tools.length;
58
58
  }
@@ -60,15 +60,15 @@ export class ToolCallProcessor extends BaseProcessor {
60
60
  toolMessagesConverted++;
61
61
  }
62
62
 
63
- log(`处理消息 ${message.id},角色: ${message.role}`);
63
+ log(`Processed message ${message.id}, role: ${message.role}`);
64
64
  }
65
65
  } catch (error) {
66
- log.extend('error')(`处理消息 ${message.id} 工具调用时出错: ${error}`);
67
- // 继续处理其他消息
66
+ log.extend('error')(`Error processing tool call in message ${message.id}: ${error}`);
67
+ // Continue processing other messages
68
68
  }
69
69
  }
70
70
 
71
- // 更新元数据
71
+ // Update metadata
72
72
  clonedContext.metadata.toolCallProcessed = processedCount;
73
73
  clonedContext.metadata.toolCallsConverted = toolCallsConverted;
74
74
  clonedContext.metadata.toolMessagesConverted = toolMessagesConverted;
@@ -82,7 +82,7 @@ export class ToolCallProcessor extends BaseProcessor {
82
82
  }
83
83
 
84
84
  /**
85
- * 处理单条消息的工具调用
85
+ * Process tool calls for a single message
86
86
  */
87
87
  private async processMessage(message: any, supportTools: boolean): Promise<any> {
88
88
  switch (message.role) {
@@ -101,26 +101,26 @@ export class ToolCallProcessor extends BaseProcessor {
101
101
  }
102
102
 
103
103
  /**
104
- * 处理助手消息的工具调用
104
+ * Process tool calls in assistant message
105
105
  */
106
106
  private processAssistantMessage(message: any, supportTools: boolean): any {
107
- // 检查是否有工具调用
107
+ // Check if there are tool calls
108
108
  const hasTools = message.tools && message.tools.length > 0;
109
109
  const hasEmptyToolCalls = message.tool_calls && message.tool_calls.length === 0;
110
110
 
111
111
  if (!supportTools || (!hasTools && hasEmptyToolCalls)) {
112
- // 如果不支持工具或只有空的工具调用,返回普通消息(移除工具相关属性)
112
+ // If tools not supported or only has empty tool calls, return regular message (remove tool-related properties)
113
113
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
114
114
  const { tools, tool_calls, ...messageWithoutTools } = message;
115
115
  return messageWithoutTools;
116
116
  }
117
117
 
118
118
  if (!hasTools) {
119
- // 如果没有 tools 但有其他工具调用属性,只移除 tools
119
+ // If no tools but has other tool call properties, only remove tools
120
120
  return message;
121
121
  }
122
122
 
123
- // tools 转换为 tool_calls 格式
123
+ // Convert tools to tool_calls format
124
124
  const tool_calls = message.tools.map(
125
125
  (tool: any): MessageToolCall => ({
126
126
  function: {
@@ -138,11 +138,11 @@ export class ToolCallProcessor extends BaseProcessor {
138
138
  }
139
139
 
140
140
  /**
141
- * 处理工具消息
141
+ * Process tool message
142
142
  */
143
143
  private processToolMessage(message: any, supportTools: boolean): any {
144
144
  if (!supportTools) {
145
- // 如果不支持工具,将工具消息转换为用户消息
145
+ // If tools not supported, convert tool message to user message
146
146
  return {
147
147
  ...message,
148
148
  name: undefined,
@@ -152,7 +152,7 @@ export class ToolCallProcessor extends BaseProcessor {
152
152
  };
153
153
  }
154
154
 
155
- // 生成工具名称
155
+ // Generate tool name
156
156
  const toolName = message.plugin
157
157
  ? this.config.genToolCallingName
158
158
  ? this.config.genToolCallingName(
@@ -166,19 +166,19 @@ export class ToolCallProcessor extends BaseProcessor {
166
166
  return {
167
167
  ...message,
168
168
  name: toolName,
169
- // 保留 tool_call_id 用于关联
169
+ // Keep tool_call_id for association
170
170
  };
171
171
  }
172
172
 
173
173
  /**
174
- * 验证工具调用格式
174
+ * Validate tool call format
175
175
  */
176
176
  private validateToolCall(tool: any): boolean {
177
177
  return !!(tool && tool.id && tool.identifier && tool.apiName && tool.arguments);
178
178
  }
179
179
 
180
180
  /**
181
- * 验证工具消息格式
181
+ * Validate tool message format
182
182
  */
183
183
  private validateToolMessage(message: any): boolean {
184
184
  return !!(message && message.tool_call_id && message.content !== undefined);
@@ -19,7 +19,7 @@ export class ToolMessageReorder extends BaseProcessor {
19
19
  protected async doProcess(context: PipelineContext): Promise<PipelineContext> {
20
20
  const clonedContext = this.cloneContext(context);
21
21
 
22
- // 重新排序消息
22
+ // Reorder messages
23
23
  const reorderedMessages = this.reorderToolMessages(clonedContext.messages);
24
24
 
25
25
  const originalCount = clonedContext.messages.length;
@@ -27,7 +27,7 @@ export class ToolMessageReorder extends BaseProcessor {
27
27
 
28
28
  clonedContext.messages = reorderedMessages;
29
29
 
30
- // 更新元数据
30
+ // Update metadata
31
31
  clonedContext.metadata.toolMessageReorder = {
32
32
  originalCount,
33
33
  removedInvalidTools: originalCount - reorderedCount,
@@ -48,10 +48,10 @@ export class ToolMessageReorder extends BaseProcessor {
48
48
  }
49
49
 
50
50
  /**
51
- * 重新排序工具消息
51
+ * Reorder tool messages
52
52
  */
53
53
  private reorderToolMessages(messages: any[]): any[] {
54
- // 1. 先收集所有 assistant 消息中的有效 tool_call_id
54
+ // 1. First collect all valid tool_call_ids from assistant messages
55
55
  const validToolCallIds = new Set<string>();
56
56
  messages.forEach((message) => {
57
57
  if (message.role === 'assistant' && message.tool_calls) {
@@ -61,7 +61,7 @@ export class ToolMessageReorder extends BaseProcessor {
61
61
  }
62
62
  });
63
63
 
64
- // 2. 收集所有有效的 tool 消息
64
+ // 2. Collect all valid tool messages
65
65
  const toolMessages: Record<string, any> = {};
66
66
  messages.forEach((message) => {
67
67
  if (
@@ -73,10 +73,10 @@ export class ToolMessageReorder extends BaseProcessor {
73
73
  }
74
74
  });
75
75
 
76
- // 3. 重新排序消息
76
+ // 3. Reorder messages
77
77
  const reorderedMessages: any[] = [];
78
78
  messages.forEach((message) => {
79
- // 跳过无效的 tool 消息
79
+ // Skip invalid tool messages
80
80
  if (
81
81
  message.role === 'tool' &&
82
82
  (!message.tool_call_id || !validToolCallIds.has(message.tool_call_id))
@@ -85,7 +85,7 @@ export class ToolMessageReorder extends BaseProcessor {
85
85
  return;
86
86
  }
87
87
 
88
- // 检查是否已经添加过该 tool 消息
88
+ // Check if this tool message has already been added
89
89
  const hasPushed = reorderedMessages.some(
90
90
  (m) => !!message.tool_call_id && m.tool_call_id === message.tool_call_id,
91
91
  );
@@ -94,7 +94,7 @@ export class ToolMessageReorder extends BaseProcessor {
94
94
 
95
95
  reorderedMessages.push(message);
96
96
 
97
- // 如果是 assistant 消息且有 tool_calls,添加对应的 tool 消息
97
+ // If assistant message with tool_calls, add corresponding tool messages
98
98
  if (message.role === 'assistant' && message.tool_calls) {
99
99
  message.tool_calls.forEach((toolCall: any) => {
100
100
  const correspondingToolMessage = toolMessages[toolCall.id];
@@ -109,5 +109,5 @@ export class ToolMessageReorder extends BaseProcessor {
109
109
  return reorderedMessages;
110
110
  }
111
111
 
112
- // 简化:移除验证/统计等辅助方法
112
+ // Simplified: removed validation/statistics helper methods
113
113
  }
@@ -40,19 +40,19 @@ export class HistorySummaryProvider extends BaseProvider {
40
40
  protected async doProcess(context: PipelineContext): Promise<PipelineContext> {
41
41
  const clonedContext = this.cloneContext(context);
42
42
 
43
- // 检查是否有历史摘要
43
+ // Check if history summary exists
44
44
  if (!this.config.historySummary) {
45
45
  log('No history summary content, skipping processing');
46
46
  return this.markAsExecuted(clonedContext);
47
47
  }
48
48
 
49
- // 格式化历史摘要
49
+ // Format history summary
50
50
  const formattedSummary = this.formatHistorySummary(this.config.historySummary);
51
51
 
52
- // 注入历史摘要
52
+ // Inject history summary
53
53
  this.injectHistorySummary(clonedContext, formattedSummary);
54
54
 
55
- // 更新元数据
55
+ // Update metadata
56
56
  clonedContext.metadata.historySummary = {
57
57
  formattedLength: formattedSummary.length,
58
58
  injected: true,
@@ -80,7 +80,7 @@ export class HistorySummaryProvider extends BaseProvider {
80
80
  const existingSystemMessage = context.messages.find((msg) => msg.role === 'system');
81
81
 
82
82
  if (existingSystemMessage) {
83
- // 合并到现有系统消息
83
+ // Merge to existing system message
84
84
  existingSystemMessage.content = [existingSystemMessage.content, formattedSummary]
85
85
  .filter(Boolean)
86
86
  .join('\n\n');
@@ -89,7 +89,7 @@ export class HistorySummaryProvider extends BaseProvider {
89
89
  `History summary merged to existing system message, final length: ${existingSystemMessage.content.length}`,
90
90
  );
91
91
  } else {
92
- // 创建新的系统消息
92
+ // Create new system message
93
93
  const systemMessage = {
94
94
  content: formattedSummary,
95
95
  role: 'system' as const,