mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-07-21 23:40:44 -07:00
chore(context): remove dead initialization trigger and unawaited promise
This commit is contained in:
@@ -688,6 +688,7 @@ export interface ConfigParameters {
|
||||
enableShellOutputEfficiency?: boolean;
|
||||
shellToolInactivityTimeout?: number;
|
||||
fakeResponses?: string;
|
||||
fakeResponsesNonStrict?: string;
|
||||
recordResponses?: string;
|
||||
ptyInfo?: string;
|
||||
disableYoloMode?: boolean;
|
||||
@@ -919,6 +920,7 @@ export class Config implements McpContext, AgentLoopContext {
|
||||
private readonly enableShellOutputEfficiency: boolean;
|
||||
private readonly shellToolInactivityTimeout: number;
|
||||
readonly fakeResponses?: string;
|
||||
readonly fakeResponsesNonStrict?: string;
|
||||
readonly recordResponses?: string;
|
||||
private readonly disableYoloMode: boolean;
|
||||
private readonly disableAlwaysAllow: boolean;
|
||||
@@ -1299,6 +1301,7 @@ export class Config implements McpContext, AgentLoopContext {
|
||||
this.storage.setCustomPlansDir(params.planSettings?.directory);
|
||||
|
||||
this.fakeResponses = params.fakeResponses;
|
||||
this.fakeResponsesNonStrict = params.fakeResponsesNonStrict;
|
||||
this.recordResponses = params.recordResponses;
|
||||
this.fileExclusions = new FileExclusions(this);
|
||||
this.eventEmitter = params.eventEmitter;
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
import type { ContextProcessor, AsyncContextProcessor } from '../pipeline.js';
|
||||
|
||||
export type PipelineTrigger =
|
||||
| 'initialization'
|
||||
| 'new_message'
|
||||
| 'retained_exceeded'
|
||||
| 'gc_backstop'
|
||||
|
||||
@@ -437,7 +437,7 @@ export class ContextManager {
|
||||
return SnapshotStateHelper.exportState(this.buffer.nodes);
|
||||
}
|
||||
|
||||
async restoreState(state: ContextEngineState): Promise<void> {
|
||||
restoreState(state: ContextEngineState): void {
|
||||
if (!state) return;
|
||||
SnapshotStateHelper.restoreState(state, this.env.inbox);
|
||||
}
|
||||
|
||||
@@ -90,6 +90,9 @@ export function createStateSnapshotProcessor(
|
||||
const isValid = consumedIds.every((id) => targetIds.has(id));
|
||||
|
||||
if (isValid) {
|
||||
debugLogger.log(
|
||||
`[StateSnapshotProcessor] Successfully spliced PROPOSED_SNAPSHOT from Inbox into Graph. Consumed ${consumedIds.length} nodes.`,
|
||||
);
|
||||
// If valid, apply it!
|
||||
const newId = randomUUID();
|
||||
|
||||
@@ -120,6 +123,10 @@ export function createStateSnapshotProcessor(
|
||||
|
||||
inbox.consume(proposed.id);
|
||||
return returnedNodes;
|
||||
} else {
|
||||
debugLogger.log(
|
||||
`[StateSnapshotProcessor] Rejected PROPOSED_SNAPSHOT from Inbox because one or more target IDs were missing from the current graph window.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,12 +82,21 @@ export function findLatestSnapshotBaseline(
|
||||
|
||||
import type { LiveInbox } from '../pipeline/inbox.js';
|
||||
import type { ContextEngineState } from '../../services/chatRecordingTypes.js';
|
||||
import { debugLogger } from '../../utils/debugLogger.js';
|
||||
|
||||
export const SnapshotStateHelper = {
|
||||
exportState(nodes: readonly ConcreteNode[]): ContextEngineState {
|
||||
const baseline = findLatestSnapshotBaseline(nodes);
|
||||
if (!baseline) return {};
|
||||
if (!baseline) {
|
||||
debugLogger.log(
|
||||
'[SnapshotStateHelper] exportState: No snapshot baseline found in current nodes.',
|
||||
);
|
||||
return {};
|
||||
}
|
||||
|
||||
debugLogger.log(
|
||||
`[SnapshotStateHelper] exportState: Exporting snapshot ID ${baseline.id} representing ${baseline.abstractsIds.length} consumed nodes.`,
|
||||
);
|
||||
return {
|
||||
snapshot: {
|
||||
text: baseline.text,
|
||||
@@ -98,18 +107,30 @@ export const SnapshotStateHelper = {
|
||||
},
|
||||
|
||||
restoreState(state: ContextEngineState, inbox: LiveInbox): void {
|
||||
if (!state.snapshot) return;
|
||||
if (!state.snapshot) {
|
||||
debugLogger.log(
|
||||
'[SnapshotStateHelper] restoreState: No snapshot found in provided ContextEngineState.',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
typeof state.snapshot.text === 'string' &&
|
||||
Array.isArray(state.snapshot.consumedIds)
|
||||
) {
|
||||
debugLogger.log(
|
||||
`[SnapshotStateHelper] restoreState: Publishing hydrated snapshot to LiveInbox with ${state.snapshot.consumedIds.length} consumed IDs.`,
|
||||
);
|
||||
inbox.publish('PROPOSED_SNAPSHOT', {
|
||||
newText: state.snapshot.text,
|
||||
consumedIds: state.snapshot.consumedIds,
|
||||
type: 'accumulate',
|
||||
timestamp: state.snapshot.timestamp ?? Date.now(),
|
||||
});
|
||||
} else {
|
||||
debugLogger.log(
|
||||
'[SnapshotStateHelper] restoreState: Invalid snapshot structural format.',
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -23,6 +23,7 @@ import type { UserTierId, GeminiUserTier } from '../code_assist/types.js';
|
||||
import { LoggingContentGenerator } from './loggingContentGenerator.js';
|
||||
import { InstallationManager } from '../utils/installationManager.js';
|
||||
import { FakeContentGenerator } from './fakeContentGenerator.js';
|
||||
import { NonStrictFakeContentGenerator } from './nonStrictFakeContentGenerator.js';
|
||||
import { parseCustomHeaders } from '../utils/customHeaderUtils.js';
|
||||
import { determineSurface } from '../utils/surface.js';
|
||||
import { RecordingContentGenerator } from './recordingContentGenerator.js';
|
||||
@@ -193,6 +194,12 @@ export async function createContentGenerator(
|
||||
sessionId?: string,
|
||||
): Promise<ContentGenerator> {
|
||||
const generator = await (async () => {
|
||||
if (gcConfig.fakeResponsesNonStrict) {
|
||||
const fakeGenerator = await NonStrictFakeContentGenerator.fromFile(
|
||||
gcConfig.fakeResponsesNonStrict,
|
||||
);
|
||||
return new LoggingContentGenerator(fakeGenerator, gcConfig);
|
||||
}
|
||||
if (gcConfig.fakeResponses) {
|
||||
const fakeGenerator = await FakeContentGenerator.fromFile(
|
||||
gcConfig.fakeResponses,
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2026 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {
|
||||
GenerateContentResponse,
|
||||
type CountTokensResponse,
|
||||
type GenerateContentParameters,
|
||||
type CountTokensParameters,
|
||||
EmbedContentResponse,
|
||||
type EmbedContentParameters,
|
||||
} from '@google/genai';
|
||||
import { promises } from 'node:fs';
|
||||
import type { ContentGenerator } from './contentGenerator.js';
|
||||
import type { UserTierId, GeminiUserTier } from '../code_assist/types.js';
|
||||
import { safeJsonStringify } from '../utils/safeJsonStringify.js';
|
||||
import type { LlmRole } from '../telemetry/types.js';
|
||||
import type { FakeResponse } from './fakeContentGenerator.js';
|
||||
|
||||
/**
|
||||
* A ContentGenerator that responds with canned responses, but unlike FakeContentGenerator,
|
||||
* it is "non-strict": it will find and use the first available response that matches
|
||||
* the requested method, rather than strictly following the input order.
|
||||
*
|
||||
* This is useful for testing asynchronous or non-deterministic background tasks
|
||||
* (like token calibration or background snapshots) that might fire out-of-order.
|
||||
*/
|
||||
export class NonStrictFakeContentGenerator implements ContentGenerator {
|
||||
userTier?: UserTierId;
|
||||
userTierName?: string;
|
||||
paidTier?: GeminiUserTier;
|
||||
|
||||
constructor(private readonly responses: FakeResponse[]) {}
|
||||
|
||||
static async fromFile(
|
||||
filePath: string,
|
||||
): Promise<NonStrictFakeContentGenerator> {
|
||||
const fileContent = await promises.readFile(filePath, 'utf-8');
|
||||
const responses = fileContent
|
||||
.split('\n')
|
||||
.filter((line) => line.trim() !== '')
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
.map((line) => JSON.parse(line) as FakeResponse);
|
||||
return new NonStrictFakeContentGenerator(responses);
|
||||
}
|
||||
|
||||
private getNextResponse<
|
||||
M extends FakeResponse['method'],
|
||||
R = Extract<FakeResponse, { method: M }>['response'],
|
||||
>(method: M, request: unknown): R {
|
||||
const index = this.responses.findIndex((r) => r.method === method);
|
||||
if (index === -1) {
|
||||
throw new Error(
|
||||
`No more mock responses for ${method}, got request:\n` +
|
||||
safeJsonStringify(request),
|
||||
);
|
||||
}
|
||||
const response = this.responses.splice(index, 1)[0];
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
return response.response as R;
|
||||
}
|
||||
|
||||
async generateContent(
|
||||
request: GenerateContentParameters,
|
||||
_userPromptId: string,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
role: LlmRole,
|
||||
): Promise<GenerateContentResponse> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return Object.setPrototypeOf(
|
||||
this.getNextResponse('generateContent', request),
|
||||
GenerateContentResponse.prototype,
|
||||
);
|
||||
}
|
||||
|
||||
async generateContentStream(
|
||||
request: GenerateContentParameters,
|
||||
_userPromptId: string,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
role: LlmRole,
|
||||
): Promise<AsyncGenerator<GenerateContentResponse>> {
|
||||
const responses = this.getNextResponse('generateContentStream', request);
|
||||
async function* stream() {
|
||||
for (const response of responses) {
|
||||
yield Object.setPrototypeOf(
|
||||
response,
|
||||
GenerateContentResponse.prototype,
|
||||
);
|
||||
}
|
||||
}
|
||||
return stream();
|
||||
}
|
||||
|
||||
async countTokens(
|
||||
request: CountTokensParameters,
|
||||
): Promise<CountTokensResponse> {
|
||||
return this.getNextResponse('countTokens', request);
|
||||
}
|
||||
|
||||
async embedContent(
|
||||
request: EmbedContentParameters,
|
||||
): Promise<EmbedContentResponse> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return Object.setPrototypeOf(
|
||||
this.getNextResponse('embedContent', request),
|
||||
EmbedContentResponse.prototype,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user