docs(changelog): update for v0.42.0-preview.1

This commit is contained in:
gemini-cli-robot
2026-05-05 22:51:06 +00:00
committed by github-actions[bot]
parent e039fcdf2a
commit 65893ee03f
54 changed files with 215 additions and 292 deletions
+1 -1
View File
@@ -281,7 +281,7 @@ export type ElicitationResponse = {
export interface ErrorData {
// One of https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
status: // 400
| 'INVALID_ARGUMENT'
| 'INVALID_ARGUMENT'
| 'FAILED_PRECONDITION'
| 'OUT_OF_RANGE'
// 401
@@ -84,9 +84,8 @@ vi.mock('../../utils/debugLogger.js', () => ({
}));
// Re-import mocked modules for assertions.
const { MCPOAuthTokenStorage } = await import(
'../../mcp/oauth-token-storage.js'
);
const { MCPOAuthTokenStorage } =
await import('../../mcp/oauth-token-storage.js');
const {
refreshAccessToken,
exchangeCodeForToken,
@@ -379,9 +379,8 @@ describe('browserAgentFactory', () => {
describe('resetBrowserSession', () => {
it('should delegate to BrowserManager.resetAll', async () => {
const { BrowserManager: MockBrowserManager } = await import(
'./browserManager.js'
);
const { BrowserManager: MockBrowserManager } =
await import('./browserManager.js');
await resetBrowserSession();
expect(
(
+6 -9
View File
@@ -1627,9 +1627,8 @@ describe('oauth2', () => {
});
it('should save credentials using OAuthCredentialStorage during web login', async () => {
const { OAuthCredentialStorage } = await import(
'./oauth-credential-storage.js'
);
const { OAuthCredentialStorage } =
await import('./oauth-credential-storage.js');
const mockAuthUrl = 'https://example.com/auth';
const mockCode = 'test-code';
const mockState = 'test-state';
@@ -1729,9 +1728,8 @@ describe('oauth2', () => {
});
it('should load credentials using OAuthCredentialStorage and not from file', async () => {
const { OAuthCredentialStorage } = await import(
'./oauth-credential-storage.js'
);
const { OAuthCredentialStorage } =
await import('./oauth-credential-storage.js');
const cachedCreds = { refresh_token: 'cached-encrypted-token' };
vi.mocked(OAuthCredentialStorage.loadCredentials).mockResolvedValue(
cachedCreds,
@@ -1767,9 +1765,8 @@ describe('oauth2', () => {
});
it('should clear credentials using OAuthCredentialStorage', async () => {
const { OAuthCredentialStorage } = await import(
'./oauth-credential-storage.js'
);
const { OAuthCredentialStorage } =
await import('./oauth-credential-storage.js');
// Create a dummy unencrypted credential file. It should not be deleted.
const credsPath = path.join(tempHomeDir, GEMINI_DIR, 'oauth_creds.json');
+4 -6
View File
@@ -436,9 +436,8 @@ describe('Server Config (config.ts)', () => {
// interactive defaults to false
});
const { McpClientManager } = await import(
'../tools/mcp-client-manager.js'
);
const { McpClientManager } =
await import('../tools/mcp-client-manager.js');
let mcpStarted = false;
vi.mocked(McpClientManager).mockImplementation(
@@ -466,9 +465,8 @@ describe('Server Config (config.ts)', () => {
interactive: true,
});
const { McpClientManager } = await import(
'../tools/mcp-client-manager.js'
);
const { McpClientManager } =
await import('../tools/mcp-client-manager.js');
let mcpStarted = false;
let resolveMcp: (value: unknown) => void;
const mcpPromise = new Promise((resolve) => {
+2 -3
View File
@@ -2453,9 +2453,8 @@ export class Config implements McpContext, AgentLoopContext {
if (this.experimentalJitContext && this.memoryContextManager) {
await this.memoryContextManager.refresh();
} else {
const { refreshServerHierarchicalMemory } = await import(
'../utils/memoryDiscovery.js'
);
const { refreshServerHierarchicalMemory } =
await import('../utils/memoryDiscovery.js');
await refreshServerHierarchicalMemory(this);
}
if (this._geminiClient?.isInitialized()) {
+12 -18
View File
@@ -1305,9 +1305,8 @@ ${JSON.stringify(
it('should stop infinite loop after MAX_TURNS when nextSpeaker always returns model', async () => {
// Get the mocked checkNextSpeaker function and configure it to trigger infinite loop
const { checkNextSpeaker } = await import(
'../utils/nextSpeakerChecker.js'
);
const { checkNextSpeaker } =
await import('../utils/nextSpeakerChecker.js');
const mockCheckNextSpeaker = vi.mocked(checkNextSpeaker);
mockCheckNextSpeaker.mockResolvedValue({
next_speaker: 'model',
@@ -1429,9 +1428,8 @@ ${JSON.stringify(
// someone tries to bypass it by calling with a very large turns value
// Get the mocked checkNextSpeaker function and configure it to trigger infinite loop
const { checkNextSpeaker } = await import(
'../utils/nextSpeakerChecker.js'
);
const { checkNextSpeaker } =
await import('../utils/nextSpeakerChecker.js');
const mockCheckNextSpeaker = vi.mocked(checkNextSpeaker);
mockCheckNextSpeaker.mockResolvedValue({
next_speaker: 'model',
@@ -2837,9 +2835,8 @@ ${JSON.stringify(
it('should not call checkNextSpeaker when turn.run() yields an error', async () => {
// Arrange
const { checkNextSpeaker } = await import(
'../utils/nextSpeakerChecker.js'
);
const { checkNextSpeaker } =
await import('../utils/nextSpeakerChecker.js');
const mockCheckNextSpeaker = vi.mocked(checkNextSpeaker);
const mockStream = (async function* () {
@@ -2874,9 +2871,8 @@ ${JSON.stringify(
it('should not call checkNextSpeaker when turn.run() yields a value then an error', async () => {
// Arrange
const { checkNextSpeaker } = await import(
'../utils/nextSpeakerChecker.js'
);
const { checkNextSpeaker } =
await import('../utils/nextSpeakerChecker.js');
const mockCheckNextSpeaker = vi.mocked(checkNextSpeaker);
const mockStream = (async function* () {
@@ -3254,9 +3250,8 @@ ${JSON.stringify(
});
it('should fire BeforeAgent once and AfterAgent once even with recursion', async () => {
const { checkNextSpeaker } = await import(
'../utils/nextSpeakerChecker.js'
);
const { checkNextSpeaker } =
await import('../utils/nextSpeakerChecker.js');
vi.mocked(checkNextSpeaker)
.mockResolvedValueOnce({ next_speaker: 'model', reasoning: 'more' })
.mockResolvedValueOnce(null);
@@ -3295,9 +3290,8 @@ ${JSON.stringify(
});
it('should use original request in AfterAgent hook even when continuation happened', async () => {
const { checkNextSpeaker } = await import(
'../utils/nextSpeakerChecker.js'
);
const { checkNextSpeaker } =
await import('../utils/nextSpeakerChecker.js');
vi.mocked(checkNextSpeaker)
.mockResolvedValueOnce({ next_speaker: 'model', reasoning: 'more' })
.mockResolvedValueOnce(null);
@@ -699,9 +699,8 @@ describe('ide-connection-utils', () => {
describe('createProxyAwareFetch', () => {
it('should return a proxy-aware fetcher function', async () => {
const { createProxyAwareFetch } = await import(
'./ide-connection-utils.js'
);
const { createProxyAwareFetch } =
await import('./ide-connection-utils.js');
const fetcher = await createProxyAwareFetch('127.0.0.1');
expect(typeof fetcher).toBe('function');
});
@@ -334,9 +334,8 @@ describe('memoryService', () => {
});
it('writes state atomically via temp file + rename', async () => {
const { writeExtractionState, readExtractionState } = await import(
'./memoryService.js'
);
const { writeExtractionState, readExtractionState } =
await import('./memoryService.js');
const statePath = path.join(tmpDir, '.extraction-state.json');
const state: ExtractionState = {
@@ -364,9 +363,8 @@ describe('memoryService', () => {
describe('startMemoryService', () => {
it('skips when lock is held by another instance', async () => {
const { startMemoryService } = await import('./memoryService.js');
const { LocalAgentExecutor } = await import(
'../agents/local-executor.js'
);
const { LocalAgentExecutor } =
await import('../agents/local-executor.js');
const memoryDir = path.join(tmpDir, 'memory');
const skillsDir = path.join(tmpDir, 'skills');
@@ -404,9 +402,8 @@ describe('memoryService', () => {
it('skips when no unprocessed sessions exist', async () => {
const { startMemoryService } = await import('./memoryService.js');
const { LocalAgentExecutor } = await import(
'../agents/local-executor.js'
);
const { LocalAgentExecutor } =
await import('../agents/local-executor.js');
const memoryDir = path.join(tmpDir, 'memory2');
const skillsDir = path.join(tmpDir, 'skills2');
@@ -439,12 +436,10 @@ describe('memoryService', () => {
it('releases lock on error', async () => {
const { startMemoryService } = await import('./memoryService.js');
const { LocalAgentExecutor } = await import(
'../agents/local-executor.js'
);
const { ExecutionLifecycleService } = await import(
'./executionLifecycleService.js'
);
const { LocalAgentExecutor } =
await import('../agents/local-executor.js');
const { ExecutionLifecycleService } =
await import('./executionLifecycleService.js');
const memoryDir = path.join(tmpDir, 'memory3');
const skillsDir = path.join(tmpDir, 'skills3');
@@ -498,9 +493,8 @@ describe('memoryService', () => {
it('emits feedback when new skills are created during extraction', async () => {
const { startMemoryService } = await import('./memoryService.js');
const { LocalAgentExecutor } = await import(
'../agents/local-executor.js'
);
const { LocalAgentExecutor } =
await import('../agents/local-executor.js');
// Reset mocks that may carry state from prior tests
vi.mocked(coreEvents.emitFeedback).mockClear();
@@ -568,12 +562,10 @@ describe('memoryService', () => {
});
it('records inbox patches as memoryCandidatesCreated without applying them', async () => {
const { startMemoryService, readExtractionState } = await import(
'./memoryService.js'
);
const { LocalAgentExecutor } = await import(
'../agents/local-executor.js'
);
const { startMemoryService, readExtractionState } =
await import('./memoryService.js');
const { LocalAgentExecutor } =
await import('../agents/local-executor.js');
vi.mocked(coreEvents.emitFeedback).mockClear();
vi.mocked(LocalAgentExecutor.create).mockReset();
@@ -671,12 +663,10 @@ describe('memoryService', () => {
});
it('records only sessions whose read_file completed successfully as processed', async () => {
const { startMemoryService, readExtractionState } = await import(
'./memoryService.js'
);
const { LocalAgentExecutor } = await import(
'../agents/local-executor.js'
);
const { startMemoryService, readExtractionState } =
await import('./memoryService.js');
const { LocalAgentExecutor } =
await import('../agents/local-executor.js');
vi.mocked(LocalAgentExecutor.create).mockReset();
@@ -1633,9 +1623,8 @@ describe('memoryService', () => {
});
it('writeExtractionState + readExtractionState roundtrips runs correctly', async () => {
const { writeExtractionState, readExtractionState } = await import(
'./memoryService.js'
);
const { writeExtractionState, readExtractionState } =
await import('./memoryService.js');
const statePath = path.join(tmpDir, 'roundtrip-state.json');
const runs: ExtractionRun[] = [
@@ -1981,9 +1970,8 @@ describe('memoryService', () => {
describe('startMemoryService feedback for patch-only runs', () => {
it('emits feedback when extraction produces only patch suggestions', async () => {
const { startMemoryService } = await import('./memoryService.js');
const { LocalAgentExecutor } = await import(
'../agents/local-executor.js'
);
const { LocalAgentExecutor } =
await import('../agents/local-executor.js');
vi.mocked(coreEvents.emitFeedback).mockClear();
vi.mocked(LocalAgentExecutor.create).mockReset();
@@ -2065,9 +2053,8 @@ describe('memoryService', () => {
it('does not emit feedback for old inbox patches when this run creates none', async () => {
const { startMemoryService } = await import('./memoryService.js');
const { LocalAgentExecutor } = await import(
'../agents/local-executor.js'
);
const { LocalAgentExecutor } =
await import('../agents/local-executor.js');
vi.mocked(coreEvents.emitFeedback).mockClear();
vi.mocked(LocalAgentExecutor.create).mockReset();
@@ -143,9 +143,8 @@ describe('sessionSummaryUtils', () => {
mockGenerateSummary = vi.fn().mockResolvedValue('Add dark mode to the app');
const { SessionSummaryService } = await import(
'./sessionSummaryService.js'
);
const { SessionSummaryService } =
await import('./sessionSummaryService.js');
(
SessionSummaryService as unknown as ReturnType<typeof vi.fn>
).mockImplementation(() => ({
@@ -1885,9 +1885,8 @@ describe('ShellExecutionService environment variables', () => {
vi.stubEnv('GEMINI_CLI_TEST_VAR', 'test-value'); // A test var that should be kept
vi.resetModules();
const { ShellExecutionService } = await import(
'./shellExecutionService.js'
);
const { ShellExecutionService } =
await import('./shellExecutionService.js');
// Test pty path
await ShellExecutionService.execute(
@@ -1945,9 +1944,8 @@ describe('ShellExecutionService environment variables', () => {
vi.stubEnv('GEMINI_CLI_TEST_VAR', 'test-value'); // A test var that should be kept
vi.resetModules();
const { ShellExecutionService } = await import(
'./shellExecutionService.js'
);
const { ShellExecutionService } =
await import('./shellExecutionService.js');
// Test pty path
await ShellExecutionService.execute(
@@ -2002,9 +2000,8 @@ describe('ShellExecutionService environment variables', () => {
vi.stubEnv('GITHUB_SHA', '');
vi.stubEnv('SURFACE', '');
vi.resetModules();
const { ShellExecutionService } = await import(
'./shellExecutionService.js'
);
const { ShellExecutionService } =
await import('./shellExecutionService.js');
// Test pty path
await ShellExecutionService.execute(
@@ -2110,9 +2107,8 @@ describe('ShellExecutionService environment variables', () => {
vi.stubEnv('GIT_CONFIG_KEY_1', 'pull.rebase');
vi.stubEnv('GIT_CONFIG_VALUE_1', 'true');
const { ShellExecutionService } = await import(
'./shellExecutionService.js'
);
const { ShellExecutionService } =
await import('./shellExecutionService.js');
mockGetPty.mockResolvedValue(null); // Force child_process fallback
await ShellExecutionService.execute(
@@ -2162,9 +2158,8 @@ describe('ShellExecutionService environment variables', () => {
vi.stubEnv('GCM_INTERACTIVE', undefined);
vi.stubEnv('GIT_CONFIG_COUNT', undefined);
const { ShellExecutionService } = await import(
'./shellExecutionService.js'
);
const { ShellExecutionService } =
await import('./shellExecutionService.js');
mockGetPty.mockResolvedValue(null); // Force child_process fallback
await ShellExecutionService.execute(
+4 -6
View File
@@ -1261,9 +1261,8 @@ function doIt() {
describe('JIT context discovery', () => {
it('should append JIT context to output when enabled and context is found', async () => {
const { discoverJitContext, appendJitContext } = await import(
'./jit-context.js'
);
const { discoverJitContext, appendJitContext } =
await import('./jit-context.js');
vi.mocked(discoverJitContext).mockResolvedValue('Use the useAuth hook.');
vi.mocked(appendJitContext).mockImplementation((content, context) => {
if (!context) return content;
@@ -1292,9 +1291,8 @@ function doIt() {
});
it('should not append JIT context when disabled', async () => {
const { discoverJitContext, appendJitContext } = await import(
'./jit-context.js'
);
const { discoverJitContext, appendJitContext } =
await import('./jit-context.js');
vi.mocked(discoverJitContext).mockResolvedValue('');
vi.mocked(appendJitContext).mockImplementation((content, context) => {
if (!context) return content;
+3 -2
View File
@@ -21,8 +21,9 @@ import { debugLogger } from '../utils/debugLogger.js';
/**
* A declarative tool that supports a modify operation.
*/
export interface ModifiableDeclarativeTool<TParams extends object>
extends DeclarativeTool<TParams, ToolResult> {
export interface ModifiableDeclarativeTool<
TParams extends object,
> extends DeclarativeTool<TParams, ToolResult> {
getModifyContext(abortSignal: AbortSignal): ModifyContext<TParams>;
}
+2 -4
View File
@@ -157,8 +157,7 @@ export interface PolicyUpdateOptions {
export abstract class BaseToolInvocation<
TParams extends object,
TResult extends ToolResult,
> implements ToolInvocation<TParams, TResult>
{
> implements ToolInvocation<TParams, TResult> {
constructor(
readonly params: TParams,
protected readonly messageBus: MessageBus,
@@ -462,8 +461,7 @@ export interface ToolParameterSchema {
export abstract class DeclarativeTool<
TParams extends object,
TResult extends ToolResult,
> implements ToolBuilder<TParams, TResult>
{
> implements ToolBuilder<TParams, TResult> {
constructor(
readonly name: string,
readonly displayName: string,
+2 -1
View File
@@ -978,7 +978,8 @@ describe('WriteFileTool', () => {
const content = 'test content';
let existsSyncSpy: // eslint-disable-next-line @typescript-eslint/no-explicit-any
ReturnType<typeof vi.spyOn<any, 'existsSync'>> | undefined = undefined;
ReturnType<typeof vi.spyOn<any, 'existsSync'>> | undefined =
undefined;
try {
if (mockFsExistsSync) {
@@ -20,8 +20,7 @@ export interface TranscriptionEvents {
/**
* Common interface for all transcription backends (Cloud or Local).
*/
export interface TranscriptionProvider
extends EventEmitter<TranscriptionEvents> {
export interface TranscriptionProvider extends EventEmitter<TranscriptionEvents> {
/** Establish connection to the transcription service. */
connect(): Promise<void>;
/** Send a chunk of raw audio data to the service. */