Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion packages/core/src/agent/content-utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { describe, expect, it } from 'vitest';
import { describe, expect, it, vi } from 'vitest';
import {
geminiPartsToContentParts,
contentPartsToGeminiParts,
buildToolResponseData,
} from './content-utils.js';
import type { Part } from '@google/genai';
import type { ContentPart } from './types.js';
import { debugLogger } from '../utils/debugLogger.js';

describe('geminiPartsToContentParts', () => {
it('converts text parts', () => {
Expand Down Expand Up @@ -191,11 +192,17 @@ describe('contentPartsToGeminiParts', () => {
const content = [
{ type: 'custom_widget', payload: 123 },
] as unknown as ContentPart[];

const warnSpy = vi.spyOn(debugLogger, 'warn');
const result = contentPartsToGeminiParts(content);

expect(warnSpy).toHaveBeenCalled();
expect(result).toHaveLength(1);
expect(result[0]).toEqual({
text: JSON.stringify({ type: 'custom_widget', payload: 123 }),
});

warnSpy.mockRestore();
});
});

Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/agent/content-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import type { Part } from '@google/genai';
import type { ContentPart } from './types.js';
import { debugLogger } from '../utils/debugLogger.js';

/**
* Converts Gemini API Part objects to framework-agnostic ContentPart objects.
Expand Down Expand Up @@ -93,6 +94,9 @@ export function contentPartsToGeminiParts(content: ContentPart[]): Part[] {
result.push({ text: part.text });
break;
default:
debugLogger.warn(
`Unhandled ContentPart type: ${JSON.stringify(part)} fallback to serialization`,
);
// Serialize unknown ContentPart variants instead of dropping them
result.push({ text: JSON.stringify(part) });
break;
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/agent/legacy-agent-session.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1330,6 +1330,7 @@ describe('LegacyAgentSession', () => {
);
expect(err?.message).toBe('Connection refused');
expect(err?.fatal).toBe(true);
expect(err?._meta?.['stack']).toBeDefined();

const streamEnd = events.find(
(e): e is AgentEvent<'agent_end'> => e.type === 'agent_end',
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/agent/legacy-agent-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ export class LegacyAgentProtocol implements AgentProtocol {
} else {
this._emitErrorAndAgentEnd(err);
}
} finally {
this._clearActiveStream();
}
}
Expand Down Expand Up @@ -390,6 +391,7 @@ export class LegacyAgentProtocol implements AgentProtocol {
const meta: Record<string, unknown> = {};
if (err instanceof Error) {
meta['errorName'] = err.constructor.name;
meta['stack'] = err.stack;
Comment thread
adamfweidman marked this conversation as resolved.
if ('exitCode' in err && typeof err.exitCode === 'number') {
meta['exitCode'] = err.exitCode;
}
Expand Down
Loading