diff --git a/packages/core/src/code_assist/converter.ts b/packages/core/src/code_assist/converter.ts index 1f2b4417acc..1d41101f318 100644 --- a/packages/core/src/code_assist/converter.ts +++ b/packages/core/src/code_assist/converter.ts @@ -181,6 +181,16 @@ function maybeToContent(content?: ContentUnion): Content | undefined { return toContent(content); } +function isPart(c: ContentUnion): c is PartUnion { + return ( + typeof c === 'object' && + c !== null && + !Array.isArray(c) && + !('parts' in c) && + !('role' in c) + ); +} + function toContent(content: ContentUnion): Content { if (Array.isArray(content)) { // it's a PartsUnion[] @@ -196,7 +206,7 @@ function toContent(content: ContentUnion): Content { parts: [{ text: content }], }; } - if ('parts' in content) { + if (!isPart(content)) { // it's a Content - process parts to handle thought filtering return { ...content, @@ -208,8 +218,7 @@ function toContent(content: ContentUnion): Content { // it's a Part return { role: 'user', - // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion - parts: [toPart(content as Part)], + parts: [toPart(content)], }; } diff --git a/packages/core/src/code_assist/experiments/experiments.ts b/packages/core/src/code_assist/experiments/experiments.ts index 614fbda43e6..94b99b311a4 100644 --- a/packages/core/src/code_assist/experiments/experiments.ts +++ b/packages/core/src/code_assist/experiments/experiments.ts @@ -35,7 +35,7 @@ export async function getExperiments( const expPath = process.env['GEMINI_EXP']; debugLogger.debug('Reading experiments from', expPath); const content = await fs.promises.readFile(expPath, 'utf8'); - const response = JSON.parse(content); + const response: ListExperimentsResponse = JSON.parse(content); if ( (response.flags && !Array.isArray(response.flags)) || (response.experimentIds && !Array.isArray(response.experimentIds)) @@ -44,8 +44,7 @@ export async function getExperiments( 'Invalid format for experiments file: `flags` and `experimentIds` must be arrays if present.', ); } - // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion - return parseExperiments(response as ListExperimentsResponse); + return parseExperiments(response); } catch (e) { debugLogger.debug('Failed to read experiments from GEMINI_EXP', e); } diff --git a/packages/core/src/code_assist/oauth-credential-storage.ts b/packages/core/src/code_assist/oauth-credential-storage.ts index 836fe1c4c35..39163384b90 100644 --- a/packages/core/src/code_assist/oauth-credential-storage.ts +++ b/packages/core/src/code_assist/oauth-credential-storage.ts @@ -125,8 +125,7 @@ export class OAuthCredentialStorage { throw error; } - // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion - const credentials = JSON.parse(credsJson) as Credentials; + const credentials: Credentials = JSON.parse(credsJson); // Save to new storage await this.saveCredentials(credentials); diff --git a/packages/core/src/code_assist/oauth2.ts b/packages/core/src/code_assist/oauth2.ts index 9676f2aa74e..e5ad7e584ac 100644 --- a/packages/core/src/code_assist/oauth2.ts +++ b/packages/core/src/code_assist/oauth2.ts @@ -115,9 +115,9 @@ async function initOauthClient( if ( credentials && - // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion - (credentials as { type?: string }).type === - 'external_account_authorized_user' + typeof credentials === 'object' && + 'type' in credentials && + credentials.type === 'external_account_authorized_user' ) { const auth = new GoogleAuth({ scopes: OAUTH_SCOPE, @@ -603,9 +603,10 @@ export function getAvailablePort(): Promise { } const server = net.createServer(); server.listen(0, () => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion - const address = server.address()! as net.AddressInfo; - port = address.port; + const address = server.address(); + if (address && typeof address === 'object') { + port = address.port; + } }); server.on('listening', () => { server.close(); diff --git a/packages/core/src/code_assist/server.ts b/packages/core/src/code_assist/server.ts index ba9b96bcb39..ff5fb76e070 100644 --- a/packages/core/src/code_assist/server.ts +++ b/packages/core/src/code_assist/server.ts @@ -7,7 +7,6 @@ import type { AuthClient } from 'google-auth-library'; import type { CodeAssistGlobalUserSettingResponse, - GoogleRpcResponse, LoadCodeAssistRequest, LoadCodeAssistResponse, LongRunningOperationResponse, @@ -296,7 +295,7 @@ export class CodeAssistServer implements ContentGenerator { req: object, signal?: AbortSignal, ): Promise { - const res = await this.client.request({ + const res = await this.client.request({ url: this.getMethodUrl(method), method: 'POST', headers: { @@ -307,15 +306,14 @@ export class CodeAssistServer implements ContentGenerator { body: JSON.stringify(req), signal, }); - // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion - return res.data as T; + return res.data; } private async makeGetRequest( url: string, signal?: AbortSignal, ): Promise { - const res = await this.client.request({ + const res = await this.client.request({ url, method: 'GET', headers: { @@ -325,8 +323,7 @@ export class CodeAssistServer implements ContentGenerator { responseType: 'json', signal, }); - // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion - return res.data as T; + return res.data; } async requestGet(method: string, signal?: AbortSignal): Promise { @@ -371,8 +368,7 @@ export class CodeAssistServer implements ContentGenerator { if (bufferedLines.length === 0) { continue; // no data to yield } - // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion - yield JSON.parse(bufferedLines.join('\n')) as T; + yield JSON.parse(bufferedLines.join('\n')); bufferedLines = []; // Reset the buffer after yielding } // Ignore other lines like comments or id fields @@ -397,23 +393,43 @@ export class CodeAssistServer implements ContentGenerator { } } -function isVpcScAffectedUser(error: unknown): boolean { - if (error && typeof error === 'object' && 'response' in error) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion - const gaxiosError = error as { - response?: { - data?: unknown; +interface VpcScErrorResponse { + response: { + data: { + error: { + details: unknown[]; }; }; - // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion - const response = gaxiosError.response?.data as - | GoogleRpcResponse - | undefined; - if (Array.isArray(response?.error?.details)) { - return response.error.details.some( - (detail) => detail.reason === 'SECURITY_POLICY_VIOLATED', - ); - } + }; +} + +function isVpcScErrorResponse(error: unknown): error is VpcScErrorResponse { + return ( + !!error && + typeof error === 'object' && + 'response' in error && + !!error.response && + typeof error.response === 'object' && + 'data' in error.response && + !!error.response.data && + typeof error.response.data === 'object' && + 'error' in error.response.data && + !!error.response.data.error && + typeof error.response.data.error === 'object' && + 'details' in error.response.data.error && + Array.isArray(error.response.data.error.details) + ); +} + +function isVpcScAffectedUser(error: unknown): boolean { + if (isVpcScErrorResponse(error)) { + return error.response.data.error.details.some( + (detail: unknown) => + detail && + typeof detail === 'object' && + 'reason' in detail && + detail.reason === 'SECURITY_POLICY_VIOLATED', + ); } return false; }