@lobehub/lobehub 2.0.0-next.198 → 2.0.0-next.199

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.199](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.198...v2.0.0-next.199)
6
+
7
+ <sup>Released on **2026-01-03**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Filter empty assistant messages for Anthropic API.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Filter empty assistant messages for Anthropic API, closes [#11129](https://github.com/lobehub/lobe-chat/issues/11129) ([7af750b](https://github.com/lobehub/lobe-chat/commit/7af750b))
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.198](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.197...v2.0.0-next.198)
6
31
 
7
32
  <sup>Released on **2026-01-03**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "fixes": [
5
+ "Filter empty assistant messages for Anthropic API."
6
+ ]
7
+ },
8
+ "date": "2026-01-03",
9
+ "version": "2.0.0-next.199"
10
+ },
2
11
  {
3
12
  "children": {
4
13
  "fixes": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.0.0-next.198",
3
+ "version": "2.0.0-next.199",
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",
@@ -155,9 +155,9 @@ describe('anthropicHelpers', () => {
155
155
  role: 'user',
156
156
  };
157
157
  const result = await buildAnthropicMessage(message);
158
- expect(result.role).toBe('user');
159
- expect(result.content).toHaveLength(2);
160
- expect((result.content[1] as any).type).toBe('image');
158
+ expect(result!.role).toBe('user');
159
+ expect(result!.content).toHaveLength(2);
160
+ expect((result!.content[1] as any).type).toBe('image');
161
161
  });
162
162
 
163
163
  it('should correctly convert tool message', async () => {
@@ -167,8 +167,8 @@ describe('anthropicHelpers', () => {
167
167
  tool_call_id: 'tool123',
168
168
  };
169
169
  const result = await buildAnthropicMessage(message);
170
- expect(result.role).toBe('user');
171
- expect(result.content).toEqual([
170
+ expect(result!.role).toBe('user');
171
+ expect(result!.content).toEqual([
172
172
  {
173
173
  content: 'Tool result content',
174
174
  tool_use_id: 'tool123',
@@ -193,8 +193,8 @@ describe('anthropicHelpers', () => {
193
193
  ],
194
194
  };
195
195
  const result = await buildAnthropicMessage(message);
196
- expect(result.role).toBe('assistant');
197
- expect(result.content).toEqual([
196
+ expect(result!.role).toBe('assistant');
197
+ expect(result!.content).toEqual([
198
198
  { text: 'Here is the result:', type: 'text' },
199
199
  {
200
200
  id: 'call1',
@@ -266,15 +266,35 @@ describe('anthropicHelpers', () => {
266
266
 
267
267
  const contents = await buildAnthropicMessages(messages);
268
268
 
269
+ // Empty assistant messages should be filtered out
269
270
  expect(contents).toEqual([
270
271
  {
271
272
  content: '## Tools\n\nYou can use these tools',
272
273
  role: 'user',
273
274
  },
275
+ ]);
276
+ });
277
+
278
+ it('should filter out assistant message with whitespace-only content', async () => {
279
+ const messages: OpenAIChatMessage[] = [
274
280
  {
275
- content: '',
281
+ content: 'Hello',
282
+ role: 'user',
283
+ },
284
+ {
285
+ content: ' \n\t ',
276
286
  role: 'assistant',
277
287
  },
288
+ ];
289
+
290
+ const contents = await buildAnthropicMessages(messages);
291
+
292
+ // Whitespace-only assistant messages should be filtered out
293
+ expect(contents).toEqual([
294
+ {
295
+ content: 'Hello',
296
+ role: 'user',
297
+ },
278
298
  ]);
279
299
  });
280
300
  it('should correctly convert OpenAI tool message to Anthropic format', async () => {
@@ -62,7 +62,7 @@ const buildArrayContent = async (content: UserMessageContentPart[]) => {
62
62
 
63
63
  export const buildAnthropicMessage = async (
64
64
  message: OpenAIChatMessage,
65
- ): Promise<Anthropic.Messages.MessageParam> => {
65
+ ): Promise<Anthropic.Messages.MessageParam | undefined> => {
66
66
  const content = message.content as string | UserMessageContentPart[];
67
67
 
68
68
  switch (message.role) {
@@ -118,7 +118,10 @@ export const buildAnthropicMessage = async (
118
118
  }
119
119
 
120
120
  // or it's a plain assistant message
121
- return { content: content as string, role: 'assistant' };
121
+ // Anthropic API requires non-empty content, filter out empty/whitespace-only content
122
+ const textContent = (content as string)?.trim();
123
+ if (!textContent) return undefined;
124
+ return { content: textContent, role: 'assistant' };
122
125
  }
123
126
 
124
127
  case 'function': {
@@ -176,7 +179,10 @@ export const buildAnthropicMessages = async (
176
179
  }
177
180
  } else {
178
181
  const anthropicMessage = await buildAnthropicMessage(message);
179
- messages.push({ ...anthropicMessage, role: anthropicMessage.role });
182
+ // Filter out undefined messages (e.g., empty assistant messages)
183
+ if (anthropicMessage) {
184
+ messages.push(anthropicMessage);
185
+ }
180
186
  }
181
187
  }
182
188