From 12c8469b34c9b0bb3d61604f98250017d2bce59b Mon Sep 17 00:00:00 2001 From: Adam Weidman <65992621+adamfweidman@users.noreply.github.com> Date: Fri, 8 May 2026 13:12:54 -0400 Subject: [PATCH] refactor(core): agent session protocol changes (#26661) --- packages/core/src/agent/content-utils.test.ts | 9 ++++++++- packages/core/src/agent/content-utils.ts | 4 ++++ packages/core/src/agent/legacy-agent-session.test.ts | 1 + packages/core/src/agent/legacy-agent-session.ts | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/core/src/agent/content-utils.test.ts b/packages/core/src/agent/content-utils.test.ts index 7de54c56fa..acf8a4a329 100644 --- a/packages/core/src/agent/content-utils.test.ts +++ b/packages/core/src/agent/content-utils.test.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it, vi } from 'vitest'; import { geminiPartsToContentParts, contentPartsToGeminiParts, @@ -12,6 +12,7 @@ import { } 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', () => { @@ -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(); }); }); diff --git a/packages/core/src/agent/content-utils.ts b/packages/core/src/agent/content-utils.ts index aaf191fe8e..42b0b7fec7 100644 --- a/packages/core/src/agent/content-utils.ts +++ b/packages/core/src/agent/content-utils.ts @@ -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. @@ -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; diff --git a/packages/core/src/agent/legacy-agent-session.test.ts b/packages/core/src/agent/legacy-agent-session.test.ts index db3c173983..525548e292 100644 --- a/packages/core/src/agent/legacy-agent-session.test.ts +++ b/packages/core/src/agent/legacy-agent-session.test.ts @@ -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', diff --git a/packages/core/src/agent/legacy-agent-session.ts b/packages/core/src/agent/legacy-agent-session.ts index d65c583b0b..e8d5e56ef5 100644 --- a/packages/core/src/agent/legacy-agent-session.ts +++ b/packages/core/src/agent/legacy-agent-session.ts @@ -166,6 +166,7 @@ export class LegacyAgentProtocol implements AgentProtocol { } else { this._emitErrorAndAgentEnd(err); } + } finally { this._clearActiveStream(); } } @@ -390,6 +391,7 @@ export class LegacyAgentProtocol implements AgentProtocol { const meta: Record = {}; if (err instanceof Error) { meta['errorName'] = err.constructor.name; + meta['stack'] = err.stack; if ('exitCode' in err && typeof err.exitCode === 'number') { meta['exitCode'] = err.exitCode; }