Skip to content
Open
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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,6 @@ gemini-debug.log
.genkit
.gemini-clipboard/
.eslintcache
evals/logs/
evals/logs/

evals/logs/
47 changes: 47 additions & 0 deletions packages/sdk/src/agent.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { GeminiCliAgent } from './agent.js';
import { GeminiCliSession } from './session.js';

beforeEach(() => {
vi.restoreAllMocks();
});

describe('GeminiCliSession', () => {
it('propagates errors from dynamic instructions', async () => {
vi.spyOn(GeminiCliSession.prototype, 'initialize').mockImplementation(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async function (this: any) {
this.client = {
getHistory: () => [],
async *sendMessageStream () {},
};
this.initialized = true;
},
Comment on lines 17 to 25
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The mock for GeminiCliSession.prototype.initialize is incomplete. While it correctly mocks getHistory, the sendStream method also calls client.sendMessageStream. If the instructions function did not throw an error, the test would likely fail with a TypeError because sendMessageStream is not defined on the mocked client. A more robust mock should include all methods that sendStream expects to find on the client object to prevent future breakage or unexpected behavior if the test path changes.

    vi.spyOn(GeminiCliSession.prototype, 'initialize').mockImplementation(
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      async function (this: any) {
        this.client = {
          getHistory: () => [],
          sendMessageStream: async function* () {},
        };
        this.initialized = true;
      },
    );

);

let callCount = 0;
const agent = new GeminiCliAgent({
instructions: () => {
callCount++;
throw new Error('Dynamic instruction failure');
},
model: 'gemini-2.0-flash',
});

const stream = agent.session().sendStream('Say hello.');

await expect(async () => {
for await (const _event of stream) {
// consume stream
}
}).rejects.toThrow('Dynamic instruction failure');

expect(callCount).toBe(1);
});
});