diff --git a/packages/a2a-server/src/agent/task.ts b/packages/a2a-server/src/agent/task.ts index a76054263f..0067c30cac 100644 --- a/packages/a2a-server/src/agent/task.ts +++ b/packages/a2a-server/src/agent/task.ts @@ -877,23 +877,21 @@ export class Task { } private async _handleToolConfirmationPart(part: Part): Promise { - if ( - part.kind !== 'data' || - !part.data || - // eslint-disable-next-line no-restricted-syntax - typeof part.data['callId'] !== 'string' || - // eslint-disable-next-line no-restricted-syntax - typeof part.data['outcome'] !== 'string' - ) { - return false; - } - if (!part.data['outcome']) { + if (part.kind !== 'data' || !part.data) { return false; } const callId = part.data['callId']; const outcomeString = part.data['outcome']; + if (typeof callId !== 'string' || typeof outcomeString !== 'string') { + return false; + } + + if (!outcomeString) { + return false; + } + this.toolsAlreadyConfirmed.add(callId); let confirmationOutcome: ToolConfirmationOutcome | undefined; diff --git a/packages/cli/src/commands/hooks/migrate.ts b/packages/cli/src/commands/hooks/migrate.ts index 36bb2cf9aa..d9921fbd10 100644 --- a/packages/cli/src/commands/hooks/migrate.ts +++ b/packages/cli/src/commands/hooks/migrate.ts @@ -79,9 +79,10 @@ function migrateClaudeHook(claudeHook: unknown): unknown { migrated['command'] = hook['command']; // Replace CLAUDE_PROJECT_DIR with GEMINI_PROJECT_DIR in command - // eslint-disable-next-line no-restricted-syntax - if (typeof migrated['command'] === 'string') { - migrated['command'] = migrated['command'].replace( + + const command = migrated['command']; + if (typeof command === 'string') { + migrated['command'] = command.replace( /\$CLAUDE_PROJECT_DIR/g, '$GEMINI_PROJECT_DIR', ); @@ -94,9 +95,10 @@ function migrateClaudeHook(claudeHook: unknown): unknown { } // Map timeout field (Claude uses seconds, Gemini uses seconds) - // eslint-disable-next-line no-restricted-syntax - if ('timeout' in hook && typeof hook['timeout'] === 'number') { - migrated['timeout'] = hook['timeout']; + + const timeout = hook['timeout']; + if ('timeout' in hook && typeof timeout === 'number') { + migrated['timeout'] = timeout; } return migrated; @@ -140,12 +142,9 @@ function migrateClaudeHooks(claudeConfig: unknown): Record { const migratedDef: Record = {}; // Transform matcher - if ( - 'matcher' in definition && - // eslint-disable-next-line no-restricted-syntax - typeof definition['matcher'] === 'string' - ) { - migratedDef['matcher'] = transformMatcher(definition['matcher']); + const matcher = definition['matcher']; + if ('matcher' in definition && typeof matcher === 'string') { + migratedDef['matcher'] = transformMatcher(matcher); } // Copy sequential flag diff --git a/packages/core/src/context/chatCompressionService.ts b/packages/core/src/context/chatCompressionService.ts index 992ca67cf9..39c52584df 100644 --- a/packages/core/src/context/chatCompressionService.ts +++ b/packages/core/src/context/chatCompressionService.ts @@ -157,18 +157,12 @@ async function truncateHistoryToBudget( if (typeof responseObj === 'string') { contentStr = responseObj; } else if (responseObj && typeof responseObj === 'object') { - if ( - 'output' in responseObj && - // eslint-disable-next-line no-restricted-syntax - typeof responseObj['output'] === 'string' - ) { - contentStr = responseObj['output']; - } else if ( - 'content' in responseObj && - // eslint-disable-next-line no-restricted-syntax - typeof responseObj['content'] === 'string' - ) { - contentStr = responseObj['content']; + const output = responseObj['output']; + const content = responseObj['content']; + if (typeof output === 'string') { + contentStr = output; + } else if (typeof content === 'string') { + contentStr = content; } else { contentStr = JSON.stringify(responseObj, null, 2); } diff --git a/packages/core/src/hooks/hookAggregator.ts b/packages/core/src/hooks/hookAggregator.ts index b67266edf5..3c3dee96de 100644 --- a/packages/core/src/hooks/hookAggregator.ts +++ b/packages/core/src/hooks/hookAggregator.ts @@ -360,12 +360,9 @@ export class HookAggregator { } // Extract additionalContext from various hook types - if ( - 'additionalContext' in specific && - // eslint-disable-next-line no-restricted-syntax - typeof specific['additionalContext'] === 'string' - ) { - contexts.push(specific['additionalContext']); + const additionalContext = specific['additionalContext']; + if (typeof additionalContext === 'string') { + contexts.push(additionalContext); } } } diff --git a/packages/core/src/services/loopDetectionService.ts b/packages/core/src/services/loopDetectionService.ts index 53030911b0..6cff6b90e2 100644 --- a/packages/core/src/services/loopDetectionService.ts +++ b/packages/core/src/services/loopDetectionService.ts @@ -583,16 +583,12 @@ export class LoopDetectionService { return { isLoop: false }; } + const flashConfidenceValue = flashResult['unproductive_state_confidence']; const flashConfidence = - // eslint-disable-next-line no-restricted-syntax - typeof flashResult['unproductive_state_confidence'] === 'number' - ? flashResult['unproductive_state_confidence'] - : 0; + typeof flashConfidenceValue === 'number' ? flashConfidenceValue : 0; + const flashAnalysisValue = flashResult['unproductive_state_analysis']; const flashAnalysis = - // eslint-disable-next-line no-restricted-syntax - typeof flashResult['unproductive_state_analysis'] === 'string' - ? flashResult['unproductive_state_analysis'] - : ''; + typeof flashAnalysisValue === 'string' ? flashAnalysisValue : ''; const doubleCheckModelName = this.context.config.modelConfigService.getResolvedConfig({ @@ -634,17 +630,17 @@ export class LoopDetectionService { signal, ); + const mainModelConfidenceValue = + mainModelResult?.['unproductive_state_confidence']; const mainModelConfidence = - mainModelResult && - // eslint-disable-next-line no-restricted-syntax - typeof mainModelResult['unproductive_state_confidence'] === 'number' - ? mainModelResult['unproductive_state_confidence'] + typeof mainModelConfidenceValue === 'number' + ? mainModelConfidenceValue : 0; + const mainModelAnalysisValue = + mainModelResult?.['unproductive_state_analysis']; const mainModelAnalysis = - mainModelResult && - // eslint-disable-next-line no-restricted-syntax - typeof mainModelResult['unproductive_state_analysis'] === 'string' - ? mainModelResult['unproductive_state_analysis'] + typeof mainModelAnalysisValue === 'string' + ? mainModelAnalysisValue : undefined; logLlmLoopCheck( @@ -689,11 +685,8 @@ export class LoopDetectionService { role: LlmRole.UTILITY_LOOP_DETECTOR, }); - if ( - result && - // eslint-disable-next-line no-restricted-syntax - typeof result['unproductive_state_confidence'] === 'number' - ) { + const confidenceValue = result?.['unproductive_state_confidence']; + if (result && typeof confidenceValue === 'number') { return result; } return null; diff --git a/packages/core/src/telemetry/semantic.ts b/packages/core/src/telemetry/semantic.ts index 6dae06d381..e805c2f84a 100644 --- a/packages/core/src/telemetry/semantic.ts +++ b/packages/core/src/telemetry/semantic.ts @@ -63,8 +63,9 @@ function getStringReferences(parts: AnyPart[]): StringReference[] { }); } } else if (part instanceof GenericPart) { - // eslint-disable-next-line no-restricted-syntax - if (part.type === 'executableCode' && typeof part['code'] === 'string') { + const codeValue = part['code']; + const outputValue = part['output']; + if (part.type === 'executableCode' && typeof codeValue === 'string') { refs.push({ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion get: () => part['code'] as string, @@ -74,8 +75,7 @@ function getStringReferences(parts: AnyPart[]): StringReference[] { }); } else if ( part.type === 'codeExecutionResult' && - // eslint-disable-next-line no-restricted-syntax - typeof part['output'] === 'string' + typeof outputValue === 'string' ) { refs.push({ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion diff --git a/packages/core/src/test-utils/mock-message-bus.ts b/packages/core/src/test-utils/mock-message-bus.ts index 322b38d9a8..3b7a5bd101 100644 --- a/packages/core/src/test-utils/mock-message-bus.ts +++ b/packages/core/src/test-utils/mock-message-bus.ts @@ -62,6 +62,7 @@ export class MockMessageBus { if (!this.subscriptions.has(type)) { this.subscriptions.set(type, new Set()); } + this.subscriptions.get(type)!.add(listener as (message: Message) => void); }, ); diff --git a/packages/core/src/tools/mcp-tool.ts b/packages/core/src/tools/mcp-tool.ts index caaba717d1..c14f277e07 100644 --- a/packages/core/src/tools/mcp-tool.ts +++ b/packages/core/src/tools/mcp-tool.ts @@ -106,13 +106,12 @@ export interface McpToolAnnotation extends Record { export function isMcpToolAnnotation( annotation: unknown, ): annotation is McpToolAnnotation { - if (typeof annotation !== 'object' || annotation === null) { - return false; - } - // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion - const record = annotation as Record; - const serverName = record['_serverName']; - return typeof serverName === 'string'; + return ( + typeof annotation === 'object' && + annotation !== null && + // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + typeof (annotation as Record)['_serverName'] === 'string' + ); } type ToolParams = Record; diff --git a/packages/core/src/utils/editCorrector.ts b/packages/core/src/utils/editCorrector.ts index 2c58bad98f..89cd014a19 100644 --- a/packages/core/src/utils/editCorrector.ts +++ b/packages/core/src/utils/editCorrector.ts @@ -110,13 +110,13 @@ Return ONLY the corrected string in the specified JSON format with the key 'corr role: LlmRole.UTILITY_EDIT_CORRECTOR, }); + const correctedStringValue = result?.['corrected_string_escaping']; if ( result && - // eslint-disable-next-line no-restricted-syntax - typeof result['corrected_string_escaping'] === 'string' && - result['corrected_string_escaping'].length > 0 + typeof correctedStringValue === 'string' && + correctedStringValue.length > 0 ) { - return result['corrected_string_escaping']; + return correctedStringValue; } else { return potentiallyProblematicString; } diff --git a/packages/core/src/utils/googleErrors.ts b/packages/core/src/utils/googleErrors.ts index bcb57425b3..a77551c0f3 100644 --- a/packages/core/src/utils/googleErrors.ts +++ b/packages/core/src/utils/googleErrors.ts @@ -231,8 +231,9 @@ export function parseGoogleApiError(error: unknown): GoogleApiError | null { } // Basic structural check before casting. // Since the proto definitions are loose, we primarily rely on @type presence. - // eslint-disable-next-line no-restricted-syntax - if (typeof detailObj['@type'] === 'string') { + + const typeValue = detailObj['@type']; + if (typeof typeValue === 'string') { // We can just cast it; the consumer will have to switch on @type // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion details.push(detailObj as unknown as GoogleApiErrorDetail); diff --git a/packages/core/src/utils/oauth-flow.ts b/packages/core/src/utils/oauth-flow.ts index 67062c9ec5..95d71510a4 100644 --- a/packages/core/src/utils/oauth-flow.ts +++ b/packages/core/src/utils/oauth-flow.ts @@ -372,31 +372,30 @@ async function parseTokenEndpointResponse( // Try to parse as JSON first, fall back to form-urlencoded try { const data: unknown = JSON.parse(responseText); - if ( - data && - typeof data === 'object' && - 'access_token' in data && - // eslint-disable-next-line no-restricted-syntax - typeof (data as Record)['access_token'] === 'string' - ) { + if (data && typeof data === 'object' && 'access_token' in data) { const obj = data as Record; - const result: OAuthTokenResponse = { - access_token: String(obj['access_token']), - token_type: - // eslint-disable-next-line no-restricted-syntax - typeof obj['token_type'] === 'string' ? obj['token_type'] : 'Bearer', - expires_in: - // eslint-disable-next-line no-restricted-syntax - typeof obj['expires_in'] === 'number' ? obj['expires_in'] : undefined, - refresh_token: - // eslint-disable-next-line no-restricted-syntax - typeof obj['refresh_token'] === 'string' - ? obj['refresh_token'] - : undefined, - // eslint-disable-next-line no-restricted-syntax - scope: typeof obj['scope'] === 'string' ? obj['scope'] : undefined, - }; - return result; + const accessTokenValue = obj['access_token']; + if (typeof accessTokenValue === 'string') { + const tokenTypeValue = obj['token_type']; + const expiresInValue = obj['expires_in']; + const refreshTokenValue = obj['refresh_token']; + const scopeValue = obj['scope']; + + const result: OAuthTokenResponse = { + access_token: accessTokenValue, + token_type: + typeof tokenTypeValue === 'string' ? tokenTypeValue : 'Bearer', + expires_in: + typeof expiresInValue === 'number' ? expiresInValue : undefined, + refresh_token: + typeof refreshTokenValue === 'string' + ? refreshTokenValue + : undefined, + + scope: typeof scopeValue === 'string' ? scopeValue : undefined, + }; + return result; + } } // JSON parsed but doesn't look like a token response — fall through } catch {