refactor(core): make Config spread-safe for AgentLoopContext

This commit is contained in:
mkorwel
2026-03-19 19:21:36 -07:00
parent 0aaf26d256
commit 00f652ad18
+41 -83
View File
@@ -668,7 +668,8 @@ export interface ConfigParameters {
}
export class Config implements McpContext, AgentLoopContext {
private _toolRegistry!: ToolRegistry;
/** @internal */
toolRegistry!: ToolRegistry;
private mcpClientManager?: McpClientManager;
private readonly a2aClientManager?: A2AClientManager;
private allowedMcpServers: string[];
@@ -676,12 +677,15 @@ export class Config implements McpContext, AgentLoopContext {
private allowedEnvironmentVariables: string[];
private blockedEnvironmentVariables: string[];
private readonly enableEnvironmentVariableRedaction: boolean;
private _promptRegistry!: PromptRegistry;
private _resourceRegistry!: ResourceRegistry;
/** @internal */
promptRegistry!: PromptRegistry;
/** @internal */
resourceRegistry!: ResourceRegistry;
private agentRegistry!: AgentRegistry;
private readonly acknowledgedAgentsService: AcknowledgedAgentsService;
private skillManager!: SkillManager;
private _sessionId: string;
/** @internal */
promptId: string;
private readonly clientName: string | undefined;
private clientVersion: string;
private fileSystemService: FileSystemService;
@@ -717,8 +721,10 @@ export class Config implements McpContext, AgentLoopContext {
private readonly accessibility: AccessibilitySettings;
private readonly telemetrySettings: TelemetrySettings;
private readonly usageStatisticsEnabled: boolean;
private _geminiClient!: GeminiClient;
private readonly _sandboxManager: SandboxManager;
/** @internal */
geminiClient!: GeminiClient;
/** @internal */
readonly sandboxManager: SandboxManager;
private baseLlmClient!: BaseLlmClient;
private localLiteRtLmClient?: LocalLiteRtLmClient;
private modelRouterService: ModelRouterService;
@@ -815,7 +821,8 @@ export class Config implements McpContext, AgentLoopContext {
private readonly eventEmitter?: EventEmitter;
private readonly useWriteTodos: boolean;
private readonly workspacePoliciesDir: string | undefined;
private readonly _messageBus: MessageBus;
/** @internal */
readonly messageBus: MessageBus;
private readonly policyEngine: PolicyEngine;
private policyUpdateConfirmationRequest:
| PolicyUpdateConfirmationRequest
@@ -885,7 +892,7 @@ export class Config implements McpContext, AgentLoopContext {
private approvedPlanPath: string | undefined;
constructor(params: ConfigParameters) {
this._sessionId = params.sessionId;
this.promptId = params.sessionId;
this.clientName = params.clientName;
this.clientVersion = params.clientVersion ?? 'unknown';
this.approvedPlanPath = undefined;
@@ -905,14 +912,14 @@ export class Config implements McpContext, AgentLoopContext {
networkAccess: false,
};
this._sandboxManager = createSandboxManager(this.sandbox, params.targetDir);
this.sandboxManager = createSandboxManager(this.sandbox, params.targetDir);
if (
!(this._sandboxManager instanceof NoopSandboxManager) &&
!(this.sandboxManager instanceof NoopSandboxManager) &&
this.sandbox.enabled
) {
this.fileSystemService = new SandboxedFileSystemService(
this._sandboxManager,
this.sandboxManager,
params.targetDir,
);
} else {
@@ -1101,7 +1108,7 @@ export class Config implements McpContext, AgentLoopContext {
showColor: params.shellExecutionConfig?.showColor ?? false,
pager: params.shellExecutionConfig?.pager ?? 'cat',
sanitizationConfig: this.sanitizationConfig,
sandboxManager: this._sandboxManager,
sandboxManager: this.sandboxManager,
sandboxConfig: this.sandbox,
};
this.truncateToolOutputThreshold =
@@ -1125,7 +1132,7 @@ export class Config implements McpContext, AgentLoopContext {
this.extensionManagement = params.extensionManagement ?? true;
this.extensionRegistryURI = params.extensionRegistryURI;
this.enableExtensionReloading = params.enableExtensionReloading ?? false;
this.storage = new Storage(this.targetDir, this._sessionId);
this.storage = new Storage(this.targetDir, this.promptId);
this.storage.setCustomPlansDir(params.planSettings?.directory);
this.fakeResponses = params.fakeResponses;
@@ -1163,7 +1170,7 @@ export class Config implements McpContext, AgentLoopContext {
ConsecaSafetyChecker.getInstance().setContext(this);
}
this._messageBus = new MessageBus(this.policyEngine, this.debugMode);
this.messageBus = new MessageBus(this.policyEngine, this.debugMode);
this.acknowledgedAgentsService = new AcknowledgedAgentsService();
this.skillManager = new SkillManager();
this.outputSettings = {
@@ -1223,14 +1230,13 @@ export class Config implements McpContext, AgentLoopContext {
);
}
}
this._geminiClient = new GeminiClient(this);
this.geminiClient = new GeminiClient(this);
this.a2aClientManager = new A2AClientManager(this);
this.modelRouterService = new ModelRouterService(this);
}
get config(): Config {
return this;
}
/** @internal */
readonly config: Config = this;
isInitialized(): boolean {
return this.initialized;
@@ -1278,15 +1284,15 @@ export class Config implements McpContext, AgentLoopContext {
if (this.getCheckpointingEnabled()) {
await this.getGitService();
}
this._promptRegistry = new PromptRegistry();
this._resourceRegistry = new ResourceRegistry();
this.promptRegistry = new PromptRegistry();
this.resourceRegistry = new ResourceRegistry();
this.agentRegistry = new AgentRegistry(this);
await this.agentRegistry.initialize();
coreEvents.on(CoreEvent.AgentsRefreshed, this.onAgentsRefreshed);
this._toolRegistry = await this.createToolRegistry();
this.toolRegistry = await this.createToolRegistry();
discoverToolsHandle?.end();
this.mcpClientManager = new McpClientManager(
this.clientVersion,
@@ -1294,7 +1300,7 @@ export class Config implements McpContext, AgentLoopContext {
this.eventEmitter,
);
this.mcpClientManager.setMainRegistries({
toolRegistry: this._toolRegistry,
toolRegistry: this.toolRegistry,
promptRegistry: this.promptRegistry,
resourceRegistry: this.resourceRegistry,
});
@@ -1346,7 +1352,7 @@ export class Config implements McpContext, AgentLoopContext {
await this.contextManager.refresh();
}
await this._geminiClient.initialize();
await this.geminiClient.initialize();
this.initialized = true;
}
@@ -1370,7 +1376,7 @@ export class Config implements McpContext, AgentLoopContext {
authMethod !== AuthType.USE_GEMINI
) {
// Restore the conversation history to the new client
this._geminiClient.stripThoughtsFromHistory();
this.geminiClient.stripThoughtsFromHistory();
}
// Reset availability status when switching auth (e.g. from limited key to OAuth)
@@ -1503,54 +1509,6 @@ export class Config implements McpContext, AgentLoopContext {
return this.localLiteRtLmClient;
}
get promptId(): string {
return this._sessionId;
}
/**
* @deprecated Do not access directly on Config.
* Use the injected AgentLoopContext instead.
*/
get toolRegistry(): ToolRegistry {
return this._toolRegistry;
}
/**
* @deprecated Do not access directly on Config.
* Use the injected AgentLoopContext instead.
*/
get promptRegistry(): PromptRegistry {
return this._promptRegistry;
}
/**
* @deprecated Do not access directly on Config.
* Use the injected AgentLoopContext instead.
*/
get resourceRegistry(): ResourceRegistry {
return this._resourceRegistry;
}
/**
* @deprecated Do not access directly on Config.
* Use the injected AgentLoopContext instead.
*/
get messageBus(): MessageBus {
return this._messageBus;
}
/**
* @deprecated Do not access directly on Config.
* Use the injected AgentLoopContext instead.
*/
get geminiClient(): GeminiClient {
return this._geminiClient;
}
get sandboxManager(): SandboxManager {
return this._sandboxManager;
}
getSessionId(): string {
return this.promptId;
}
@@ -1560,7 +1518,7 @@ export class Config implements McpContext, AgentLoopContext {
}
setSessionId(sessionId: string): void {
this._sessionId = sessionId;
this.promptId = sessionId;
}
setTerminalBackground(terminalBackground: string | undefined): void {
@@ -1843,7 +1801,7 @@ export class Config implements McpContext, AgentLoopContext {
}
getPromptRegistry(): PromptRegistry {
return this._promptRegistry;
return this.promptRegistry;
}
getSkillManager(): SkillManager {
@@ -1851,7 +1809,7 @@ export class Config implements McpContext, AgentLoopContext {
}
getResourceRegistry(): ResourceRegistry {
return this._resourceRegistry;
return this.resourceRegistry;
}
getDebugMode(): boolean {
@@ -2127,9 +2085,9 @@ export class Config implements McpContext, AgentLoopContext {
);
await refreshServerHierarchicalMemory(this);
}
if (this._geminiClient?.isInitialized()) {
await this._geminiClient.setTools();
this._geminiClient.updateSystemInstruction();
if (this.geminiClient?.isInitialized()) {
await this.geminiClient.setTools();
this.geminiClient.updateSystemInstruction();
}
}
@@ -2332,8 +2290,8 @@ export class Config implements McpContext, AgentLoopContext {
(currentMode === ApprovalMode.YOLO || mode === ApprovalMode.YOLO);
if (isPlanModeTransition || isYoloModeTransition) {
if (this._geminiClient?.isInitialized()) {
this._geminiClient.setTools().catch((err) => {
if (this.geminiClient?.isInitialized()) {
this.geminiClient.setTools().catch((err) => {
debugLogger.error('Failed to update tools', err);
});
}
@@ -3393,8 +3351,8 @@ export class Config implements McpContext, AgentLoopContext {
}
private onAgentsRefreshed = async () => {
if (this._toolRegistry) {
this.registerSubAgentTools(this._toolRegistry);
if (this.toolRegistry) {
this.registerSubAgentTools(this.toolRegistry);
}
// Propagate updates to the active chat session
const client = this.geminiClient;
@@ -3415,7 +3373,7 @@ export class Config implements McpContext, AgentLoopContext {
this.logCurrentModeDuration(this.getApprovalMode());
coreEvents.off(CoreEvent.AgentsRefreshed, this.onAgentsRefreshed);
this.agentRegistry?.dispose();
this._geminiClient?.dispose();
this.geminiClient?.dispose();
if (this.mcpClientManager) {
await this.mcpClientManager.stop();
}