| // Copyright 2026 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import {assert} from 'chai'; |
| |
| import {setupLocaleHooks} from '../../testing/LocaleHelpers.js'; |
| import {setupRuntimeHooks} from '../../testing/RuntimeHelpers.js'; |
| |
| import {AidaClient, AidaGcaTranslation, GcaTypes} from './host.js'; |
| |
| const DEFAULT_CLIENT = 'CHROME_DEVTOOLS'; |
| const DEFAULT_METADATA: AidaClient.RequestMetadata = { |
| disable_user_content_logging: false, |
| client_version: '1.2.3.4', |
| }; |
| const DEFAULT_LABELS = { |
| client: 'chrome_devtools', |
| client_version: '1_2_3_4', |
| disable_user_content_logging: 'false', |
| }; |
| |
| function createAidaDoConversationRequest(overrides: Partial<AidaClient.DoConversationRequest> = {}): |
| AidaClient.DoConversationRequest { |
| const {metadata, ...otherOverrides} = overrides; |
| return { |
| current_message: {parts: [{text: 'Hello'}], role: AidaClient.Role.USER}, |
| client: DEFAULT_CLIENT, |
| metadata: {...DEFAULT_METADATA, ...metadata}, |
| ...otherOverrides, |
| }; |
| } |
| |
| function createGcaRequest( |
| experience: string, overrides: Partial<GcaTypes.GenerateContentRequest> = {}): GcaTypes.GenerateContentRequest { |
| const {labels, aicode, ...otherOverrides} = overrides; |
| return { |
| contents: [{role: 'user', parts: [{text: 'Hello'}]}], |
| ...otherOverrides, |
| labels: {...DEFAULT_LABELS, ...labels}, |
| aicode: aicode || { |
| experience, |
| }, |
| }; |
| } |
| |
| function createGcaResponse(overrides: Partial<GcaTypes.GenerateContentResponse> = {}): |
| GcaTypes.GenerateContentResponse { |
| return { |
| candidates: [{ |
| index: 0, |
| content: {role: 'model', parts: [{text: 'Hello there!'}]}, |
| finishReason: GcaTypes.FinishReason.STOP, |
| safetyRatings: [], |
| citationMetadata: {citations: []}, |
| groundingMetadata: {}, |
| aicodeOutput: {contents: []}, |
| }], |
| promptFeedback: |
| {blockReason: GcaTypes.BlockReason.BLOCKED_REASON_UNSPECIFIED, safetyRatings: [], blockReasonMessage: ''}, |
| usageMetadata: { |
| promptTokenCount: 0, |
| candidatesTokenCount: 0, |
| totalTokenCount: 0, |
| thoughtsTokenCount: 0, |
| cachedContentTokenCount: 0, |
| }, |
| modelVersion: 'test-model', |
| responseId: 'response-123', |
| ...overrides, |
| }; |
| } |
| function createAidaEvent(overrides: Partial<AidaClient.AidaRegisterClientEvent> = {}): |
| AidaClient.AidaRegisterClientEvent { |
| return { |
| corresponding_aida_rpc_global_id: '123', |
| disable_user_content_logging: false, |
| ...overrides, |
| }; |
| } |
| |
| /* eslint-disable @typescript-eslint/no-explicit-any */ |
| function describeCommonRequestFields( |
| aidaRequestFactory: (overrides: any) => any, |
| translateFn: (req: any) => GcaTypes.GenerateContentRequest, |
| ) { |
| describe('common fields', () => { |
| it('maps common options and metadata', () => { |
| const aidaRequest = aidaRequestFactory({ |
| options: {temperature: 0.5, model_id: 'test-model'}, |
| metadata: {string_session_id: 'session-123'}, |
| }); |
| const result = translateFn(aidaRequest); |
| assert.strictEqual(result.model, 'test-model'); |
| assert.strictEqual(result.labels?.['session_id'], 'session-123'); |
| assert.strictEqual(result.labels?.['client_version'], '1_2_3_4'); |
| assert.strictEqual(result.labels?.['disable_user_content_logging'], 'false'); |
| assert.strictEqual(result.generationConfig?.temperature, 0.5); |
| }); |
| |
| it('maps client and feature labels', () => { |
| const aidaRequest = aidaRequestFactory({ |
| functionality_type: AidaClient.FunctionalityType.EXPLAIN_ERROR, |
| client_feature: AidaClient.ClientFeature.CHROME_CONSOLE_INSIGHTS, |
| }); |
| const result = translateFn(aidaRequest); |
| assert.strictEqual(result.labels?.['client'], 'chrome_devtools'); |
| assert.strictEqual(result.labels?.['functionality_type'], 'explain_error'); |
| assert.strictEqual(result.labels?.['client_feature'], 'chrome_console_insights'); |
| }); |
| }); |
| } |
| |
| describe('AidaGcaTranslation', () => { |
| setupLocaleHooks(); |
| setupRuntimeHooks(); |
| describe('AIDA DoConversationRequest to GCA GenerateContentRequest', () => { |
| describeCommonRequestFields( |
| createAidaDoConversationRequest, AidaGcaTranslation.aidaDoConversationRequestToGcaRequest); |
| |
| it('translates a basic request', () => { |
| assert.deepEqual( |
| AidaGcaTranslation.aidaDoConversationRequestToGcaRequest(createAidaDoConversationRequest()), |
| createGcaRequest('chat_console_insights')); |
| }); |
| |
| it('translates a request with preamble and options', () => { |
| const aidaRequest = createAidaDoConversationRequest({ |
| preamble: 'You are an AI assistant', |
| options: {temperature: 0.5, model_id: 'test-model'}, |
| }); |
| |
| const expectedGcaRequest = createGcaRequest('chat_console_insights', { |
| model: 'test-model', |
| systemInstruction: {role: 'user', parts: [{text: 'You are an AI assistant'}]}, |
| generationConfig: {temperature: 0.5}, |
| }); |
| |
| assert.deepEqual(AidaGcaTranslation.aidaDoConversationRequestToGcaRequest(aidaRequest), expectedGcaRequest); |
| }); |
| |
| it('translates a request with facts', () => { |
| const aidaRequest = createAidaDoConversationRequest({ |
| facts: [ |
| {text: 'Fact 1', metadata: {source: 'src1', score: 1}}, |
| {text: 'Fact 2', metadata: {source: 'src2', score: 2}}, |
| ], |
| }); |
| |
| const expectedGcaRequest = createGcaRequest('chat_console_insights', { |
| contents: [ |
| {role: 'user', parts: [{text: '[source: src1] Fact 1'}, {text: '[source: src2] Fact 2'}]}, |
| {role: 'user', parts: [{text: 'Hello'}]}, |
| ], |
| }); |
| |
| assert.deepEqual(AidaGcaTranslation.aidaDoConversationRequestToGcaRequest(aidaRequest), expectedGcaRequest); |
| }); |
| |
| it('translates a request with historical contexts', () => { |
| const aidaRequest = createAidaDoConversationRequest({ |
| historical_contexts: [ |
| {parts: [{text: 'Hello'}], role: AidaClient.Role.USER}, |
| {parts: [{text: 'Hi there!'}], role: AidaClient.Role.MODEL}, |
| ], |
| current_message: {parts: [{text: 'How are you?'}], role: AidaClient.Role.USER}, |
| }); |
| |
| const expectedGcaRequest = createGcaRequest('chat_console_insights', { |
| contents: [ |
| {role: 'user', parts: [{text: 'Hello'}]}, |
| {role: 'model', parts: [{text: 'Hi there!'}]}, |
| {role: 'user', parts: [{text: 'How are you?'}]}, |
| ], |
| }); |
| |
| assert.deepEqual(AidaGcaTranslation.aidaDoConversationRequestToGcaRequest(aidaRequest), expectedGcaRequest); |
| }); |
| |
| it('translates a request with function declarations', () => { |
| const aidaRequest = createAidaDoConversationRequest({ |
| function_declarations: [{ |
| name: 'my_func', |
| description: 'A description', |
| parameters: { |
| type: AidaClient.ParametersTypes.OBJECT, |
| description: 'Params', |
| properties: {arg1: {type: AidaClient.ParametersTypes.STRING, description: 'An arg'}}, |
| required: ['arg1'], |
| }, |
| }], |
| }); |
| |
| const expectedGcaRequest = createGcaRequest('chat_console_insights', { |
| tools: [{ |
| functionDeclarations: [{ |
| name: 'my_func', |
| description: 'A description', |
| parameters: { |
| type: GcaTypes.Type.OBJECT, |
| description: 'Params', |
| properties: {arg1: {type: GcaTypes.Type.STRING, description: 'An arg'}}, |
| required: ['arg1'], |
| }, |
| }], |
| }], |
| }); |
| |
| assert.deepEqual(AidaGcaTranslation.aidaDoConversationRequestToGcaRequest(aidaRequest), expectedGcaRequest); |
| }); |
| }); |
| |
| describe('GCA GenerateContentResponse to AIDA DoConversationResponse', () => { |
| it('translates a basic response', () => { |
| assert.deepEqual(AidaGcaTranslation.gcaResponseToAidaDoConversationResponse(createGcaResponse()), { |
| explanation: 'Hello there!', |
| metadata: {rpcGlobalId: 'response-123'}, |
| functionCalls: undefined, |
| completed: true, |
| }); |
| }); |
| |
| it('translates a response with function calls', () => { |
| const gcaResponse = createGcaResponse({ |
| candidates: [{ |
| index: 0, |
| content: { |
| role: 'model', |
| parts: [ |
| {text: 'I am calling a function.'}, |
| {functionCall: {name: 'my_func', args: {arg1: 'val1'}}}, |
| ], |
| }, |
| finishReason: GcaTypes.FinishReason.STOP, |
| safetyRatings: [], |
| citationMetadata: {citations: []}, |
| groundingMetadata: {}, |
| aicodeOutput: {contents: []}, |
| }], |
| }); |
| |
| assert.deepEqual(AidaGcaTranslation.gcaResponseToAidaDoConversationResponse(gcaResponse), { |
| explanation: 'I am calling a function.', |
| metadata: {rpcGlobalId: 'response-123'}, |
| functionCalls: [{name: 'my_func', args: {arg1: 'val1'}}], |
| completed: true, |
| }); |
| }); |
| }); |
| |
| describe('convert Aida parts to GCA parts', () => { |
| it('translates function response part', () => { |
| const aidaRequest = createAidaDoConversationRequest({ |
| current_message: { |
| parts: [ |
| {functionResponse: {name: 'my_func1', response: {result: 'ok'}}}, |
| {functionResponse: {name: 'my_func2', response: {output: 'abcd'}}}, |
| {functionResponse: {name: 'my_func3', response: {error: 'error'}}}, |
| {functionResponse: {name: 'my_func4', response: {somethingElse: 'zxy'}}}, |
| ], |
| role: AidaClient.Role.USER, |
| }, |
| }); |
| |
| const gcaRequest = AidaGcaTranslation.aidaDoConversationRequestToGcaRequest(aidaRequest); |
| assert.deepEqual(gcaRequest.contents[0].parts, [ |
| {functionResponse: {name: 'my_func1', response: {output: 'ok'}}}, |
| {functionResponse: {name: 'my_func2', response: {output: 'abcd'}}}, |
| {functionResponse: {name: 'my_func3', response: {error: 'error'}}}, |
| {functionResponse: {name: 'my_func4', response: {output: {somethingElse: 'zxy'}}}}, |
| ]); |
| }); |
| |
| it('translates inline data part', () => { |
| const aidaRequest = createAidaDoConversationRequest({ |
| current_message: { |
| parts: [{inlineData: {mimeType: 'image/png', data: 'base64data'}}], |
| role: AidaClient.Role.USER, |
| }, |
| }); |
| |
| const gcaRequest = AidaGcaTranslation.aidaDoConversationRequestToGcaRequest(aidaRequest); |
| assert.deepEqual(gcaRequest.contents[0].parts?.[0], { |
| inlineData: {mimeType: 'image/png', data: 'base64data'}, |
| }); |
| }); |
| }); |
| |
| describe('AidaClientEvent to GCA TelemetryRequest', () => { |
| const telemetryCases = [ |
| { |
| name: 'translates positive sentiment feedback', |
| event: {do_conversation_client_event: {user_feedback: {sentiment: AidaClient.Rating.POSITIVE}}}, |
| expectedMetric: {suggestionInteraction: {interaction: GcaTypes.InteractionType.THUMBS_UP}}, |
| }, |
| { |
| name: 'translates negative sentiment feedback', |
| event: {do_conversation_client_event: {user_feedback: {sentiment: AidaClient.Rating.NEGATIVE}}}, |
| expectedMetric: {suggestionInteraction: {interaction: GcaTypes.InteractionType.THUMBS_DOWN}}, |
| }, |
| { |
| name: 'translates code completion impression', |
| event: { |
| complete_code_client_event: { |
| user_impression: { |
| sample: {sample_id: 1}, |
| latency: {duration: {seconds: 1, nanos: 500000000}}, |
| }, |
| }, |
| }, |
| expectedMetric: { |
| suggestionOffered: { |
| method: GcaTypes.Method.COMPLETE_CODE, |
| status: GcaTypes.SuggestionStatus.NO_ERROR, |
| responseLatency: '1.5s', |
| }, |
| }, |
| }, |
| { |
| name: 'translates code completion acceptance', |
| event: {complete_code_client_event: {user_acceptance: {sample: {sample_id: 5}}}}, |
| expectedMetric: {suggestionInteraction: {interaction: GcaTypes.InteractionType.ACCEPT, candidateIndex: 5}}, |
| }, |
| { |
| name: 'translates code generation impression', |
| event: { |
| generate_code_client_event: { |
| user_impression: { |
| sample: {sample_id: 1}, |
| latency: {duration: {seconds: 2, nanos: 0}}, |
| }, |
| }, |
| }, |
| expectedMetric: { |
| suggestionOffered: { |
| method: GcaTypes.Method.GENERATE_CODE, |
| status: GcaTypes.SuggestionStatus.NO_ERROR, |
| responseLatency: '2s', |
| }, |
| }, |
| }, |
| ]; |
| |
| for (const {name, event, expectedMetric} of telemetryCases) { |
| it(name, () => { |
| const clientEvent = createAidaEvent(event); |
| const telemetryRequest = AidaGcaTranslation.aidaEventToGcaTelemetryRequest(clientEvent); |
| assert.lengthOf(telemetryRequest.feedbackMetrics, 1); |
| assert.strictEqual(telemetryRequest.feedbackMetrics[0].responseId, '123'); |
| if (expectedMetric.suggestionInteraction) { |
| assert.deepEqual( |
| telemetryRequest.feedbackMetrics[0].suggestionInteraction, expectedMetric.suggestionInteraction); |
| } |
| if (expectedMetric.suggestionOffered) { |
| assert.deepEqual(telemetryRequest.feedbackMetrics[0].suggestionOffered, expectedMetric.suggestionOffered); |
| } |
| }); |
| } |
| |
| it('returns empty metrics when no event is present', () => { |
| const telemetryRequest = AidaGcaTranslation.aidaEventToGcaTelemetryRequest(createAidaEvent()); |
| assert.lengthOf(telemetryRequest.feedbackMetrics, 0); |
| }); |
| |
| it('handles conversation event without sentiment', () => { |
| const telemetryRequest = AidaGcaTranslation.aidaEventToGcaTelemetryRequest( |
| createAidaEvent({do_conversation_client_event: {user_feedback: {}}})); |
| assert.lengthOf(telemetryRequest.feedbackMetrics, 0); |
| }); |
| }); |
| |
| function createAidaCompletionRequest(overrides: Partial<AidaClient.CompletionRequest> = {}): |
| AidaClient.CompletionRequest { |
| const {metadata, ...otherOverrides} = overrides; |
| return { |
| client: DEFAULT_CLIENT, |
| prefix: 'function foo() {', |
| suffix: '}', |
| metadata: {...DEFAULT_METADATA, ...metadata}, |
| ...otherOverrides, |
| }; |
| } |
| |
| describe('AIDA CompletionRequest to GCA GenerateContentRequest', () => { |
| describeCommonRequestFields(createAidaCompletionRequest, AidaGcaTranslation.aidaCompletionRequestToGcaRequest); |
| |
| it('translates a basic completion request', () => { |
| assert.deepEqual(AidaGcaTranslation.aidaCompletionRequestToGcaRequest(createAidaCompletionRequest({ |
| additional_files: [{ |
| path: 'fake-path.js', |
| content: 'description/instructions', |
| included_reason: AidaClient.Reason.RELATED_FILE, |
| }], |
| })), |
| createGcaRequest('complete_code', { |
| contents: [], |
| aicode: { |
| experience: 'complete_code', |
| files: [ |
| { |
| fileUri: 'devtools-code-completion', |
| inclusionReason: [GcaTypes.InclusionReason.ACTIVE], |
| segments: [ |
| {content: 'function foo() {', isSelected: false}, |
| {content: '', isSelected: true}, |
| {content: '}', isSelected: false}, |
| ], |
| }, |
| { |
| fileUri: 'fake-path.js', |
| inclusionReason: [GcaTypes.InclusionReason.RELATED], |
| segments: [{content: 'description/instructions', isSelected: false}], |
| }, |
| ], |
| }, |
| })); |
| }); |
| |
| it('translates a completion request with options and additional files', () => { |
| const aidaRequest = createAidaCompletionRequest({ |
| prefix: 'console.log(', |
| suffix: undefined, |
| options: { |
| temperature: 0, |
| model_id: 'code-model', |
| inference_language: AidaClient.AidaInferenceLanguage.JAVASCRIPT, |
| stop_sequences: ['\n'], |
| }, |
| metadata: {...DEFAULT_METADATA, string_session_id: 'session-456'}, |
| last_user_action: AidaClient.EditType.ADD, |
| additional_files: [ |
| {path: 'utils.js', content: 'export const log = () => {}', included_reason: AidaClient.Reason.CURRENTLY_OPEN}, |
| ], |
| }); |
| |
| const expectedGcaRequest = createGcaRequest('complete_code', { |
| contents: [], |
| |
| model: 'code-model', |
| generationConfig: {stopSequences: ['\n'], temperature: 0}, |
| labels: { |
| inference_language: 'javascript', |
| last_user_action: 'add', |
| session_id: 'session-456', |
| ...DEFAULT_LABELS, |
| }, |
| aicode: { |
| experience: 'complete_code', |
| files: [ |
| { |
| fileUri: 'devtools-code-completion', |
| inclusionReason: [1], |
| segments: [{content: 'console.log(', isSelected: false}, {content: '', isSelected: true}], |
| }, |
| { |
| fileUri: 'utils.js', |
| inclusionReason: [GcaTypes.InclusionReason.OPEN], |
| segments: [{content: 'export const log = () => {}', isSelected: false}], |
| }, |
| ], |
| }, |
| }); |
| |
| assert.deepEqual(AidaGcaTranslation.aidaCompletionRequestToGcaRequest(aidaRequest), expectedGcaRequest); |
| }); |
| }); |
| |
| describe('GCA GenerateContentResponse to AIDA CompletionResponse', () => { |
| it('translates a basic completion response', () => { |
| const gcaResponse = createGcaResponse({ |
| modelVersion: 'code-model', |
| responseId: 'response-456', |
| candidates: [{ |
| index: 0, |
| content: {role: 'model', parts: [{text: '"hello")'}]}, |
| finishReason: GcaTypes.FinishReason.STOP, |
| safetyRatings: [], |
| citationMetadata: {citations: []}, |
| groundingMetadata: {}, |
| aicodeOutput: {contents: []}, |
| }], |
| }); |
| |
| assert.deepEqual(AidaGcaTranslation.gcaResponseToAidaCompletionResponse(gcaResponse), { |
| generatedSamples: [{ |
| generationString: '"hello")', |
| score: 0, |
| sampleId: 0, |
| attributionMetadata: {attributionAction: AidaClient.RecitationAction.CITE, citations: []}, |
| }], |
| metadata: {rpcGlobalId: 'response-456'}, |
| }); |
| }); |
| }); |
| |
| function createAidaGenerateCodeRequest(overrides: Partial<AidaClient.GenerateCodeRequest> = {}): |
| AidaClient.GenerateCodeRequest { |
| const {metadata, ...otherOverrides} = overrides; |
| return { |
| client: DEFAULT_CLIENT, |
| preamble: 'Generate a function', |
| current_message: {parts: [{text: 'that adds two numbers'}], role: AidaClient.Role.USER}, |
| use_case: AidaClient.UseCase.CODE_GENERATION, |
| metadata: {...DEFAULT_METADATA, ...metadata}, |
| ...otherOverrides, |
| }; |
| } |
| |
| describe('AIDA GenerateCodeRequest to GCA GenerateContentRequest', () => { |
| describeCommonRequestFields(createAidaGenerateCodeRequest, AidaGcaTranslation.aidaGenerateCodeRequestToGcaRequest); |
| |
| it('translates a basic generate code request', () => { |
| assert.deepEqual(AidaGcaTranslation.aidaGenerateCodeRequestToGcaRequest(createAidaGenerateCodeRequest()), { |
| aicode: {experience: 'generate_code'}, |
| contents: [{role: 'user', parts: [{text: 'that adds two numbers'}]}], |
| systemInstruction: {role: 'user', parts: [{text: 'Generate a function'}]}, |
| labels: {use_case: 'code_generation', ...DEFAULT_LABELS}, |
| }); |
| }); |
| |
| it('translates a generate code request with options and context files', () => { |
| const aidaRequest = createAidaGenerateCodeRequest({ |
| preamble: 'Help me with this', |
| current_message: {parts: [{text: 'fix the bug'}], role: AidaClient.Role.USER}, |
| options: { |
| temperature: 0.7, |
| model_id: 'gen-model', |
| inference_language: AidaClient.AidaInferenceLanguage.TYPESCRIPT, |
| expect_code_output: true, |
| }, |
| client_feature: AidaClient.ClientFeature.CHROME_FILE_AGENT, |
| metadata: {...DEFAULT_METADATA, string_session_id: 'session-789'}, |
| context_files: [{ |
| path: 'app.ts', |
| full_content: 'console.log("bug")', |
| programming_language: AidaClient.AidaInferenceLanguage.TYPESCRIPT, |
| }], |
| }); |
| |
| const expectedGcaRequest = createGcaRequest('generate_code', { |
| contents: [{role: 'user', parts: [{text: 'fix the bug'}]}], |
| systemInstruction: {role: 'user', parts: [{text: 'Help me with this'}]}, |
| model: 'gen-model', |
| generationConfig: {temperature: 0.7}, |
| labels: { |
| inference_language: 'typescript', |
| expect_code_output: 'true', |
| client_feature: 'chrome_file_agent', |
| session_id: 'session-789', |
| use_case: 'code_generation', |
| ...DEFAULT_LABELS, |
| }, |
| aicode: { |
| experience: 'generate_code', |
| files: [{fileUri: 'app.ts', programmingLanguage: 'TYPESCRIPT'}], |
| }, |
| }); |
| |
| assert.deepEqual(AidaGcaTranslation.aidaGenerateCodeRequestToGcaRequest(aidaRequest), expectedGcaRequest); |
| }); |
| }); |
| |
| describe('GCA GenerateContentResponse to AIDA GenerateCodeResponse', () => { |
| it('translates a basic generate code response', () => { |
| const gcaResponse = createGcaResponse({ |
| modelVersion: 'gen-model', |
| responseId: 'response-789', |
| candidates: [{ |
| index: 0, |
| content: {role: 'model', parts: [{text: 'const add = (a, b) => a + b;'}]}, |
| finishReason: GcaTypes.FinishReason.STOP, |
| safetyRatings: [], |
| citationMetadata: {citations: []}, |
| groundingMetadata: {}, |
| aicodeOutput: {contents: []}, |
| }], |
| }); |
| |
| assert.deepEqual(AidaGcaTranslation.gcaResponseToAidaGenerateCodeResponse(gcaResponse), { |
| samples: [{ |
| generationString: 'const add = (a, b) => a + b;', |
| score: 0, |
| sampleId: 0, |
| attributionMetadata: {attributionAction: AidaClient.RecitationAction.CITE, citations: []}, |
| }], |
| metadata: {rpcGlobalId: 'response-789'}, |
| }); |
| }); |
| }); |
| |
| describe('GCA GenerateContentResponse to AIDA ChunkResponse', () => { |
| it('translates a basic chunk response and includes modelVersion', () => { |
| const gcaResponse = createGcaResponse({ |
| modelVersion: 'gen-model', |
| responseId: 'response-789', |
| candidates: [{ |
| index: 0, |
| content: {role: 'model', parts: [{text: 'const add = (a, b) => a + b;'}]}, |
| finishReason: GcaTypes.FinishReason.STOP, |
| safetyRatings: [], |
| citationMetadata: {citations: []}, |
| groundingMetadata: {}, |
| aicodeOutput: {contents: []}, |
| }], |
| }); |
| |
| assert.deepEqual(AidaGcaTranslation.gcaChunkResponseToAidaChunkResponse(gcaResponse), [{ |
| textChunk: { |
| text: 'const add = (a, b) => a + b;', |
| }, |
| metadata: { |
| rpcGlobalId: 'response-789', |
| attributionMetadata: { |
| attributionAction: AidaClient.RecitationAction.CITE, |
| citations: [], |
| }, |
| inferenceOptionMetadata: {modelId: 'gen-model'}, |
| }, |
| }]); |
| }); |
| }); |
| it('translates a functionCallChunk with thoughtSignature', () => { |
| const gcaResponse = createGcaResponse({ |
| modelVersion: 'gen-model', |
| responseId: 'response-789', |
| candidates: [{ |
| index: 0, |
| content: { |
| role: 'model', |
| parts: [{functionCall: {name: 'getStyles', args: {uid: 1}}, thoughtSignature: 'thought-sig-abc'}], |
| }, |
| finishReason: GcaTypes.FinishReason.STOP, |
| safetyRatings: [], |
| citationMetadata: {citations: []}, |
| groundingMetadata: {}, |
| aicodeOutput: {contents: []}, |
| }], |
| }); |
| assert.deepEqual(AidaGcaTranslation.gcaChunkResponseToAidaChunkResponse(gcaResponse), [ |
| { |
| functionCallChunk: { |
| functionCall: { |
| name: 'getStyles', |
| args: {uid: 1}, |
| thoughtSignature: 'thought-sig-abc', |
| }, |
| }, |
| metadata: { |
| rpcGlobalId: 'response-789', |
| inferenceOptionMetadata: {modelId: 'gen-model'}, |
| attributionMetadata: {attributionAction: AidaClient.RecitationAction.CITE, citations: []}, |
| }, |
| }, |
| ]); |
| }); |
| }); |