[ResposeOps] Gemini connector, remove bad variable reference (#195308)

This commit is contained in:
Steph Milovic 2024-10-08 10:44:32 -06:00 committed by GitHub
parent 80a5565aee
commit 32a478ccc3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 46 additions and 62 deletions

View file

@ -491,7 +491,7 @@ For an <<bedrock-action-type,{bedrock} connector>>, specifies the AWS access key
`xpack.actions.preconfigured.<connector-id>.secrets.apikey`::
An API key secret that varies by connector:
`xpack.actions.preconfigured.<connector-id>.secrets.credentialsJSON`::
`xpack.actions.preconfigured.<connector-id>.secrets.credentialsJson`::
For an <<gemini-action-type,{gemini} connector>>, specifies the GCP service account credentials JSON file for authentication.
+
--

View file

@ -2,8 +2,8 @@ title: Connector secrets properties for a Google Gemini connector
description: Defines secrets for connectors when type is `.gemini`.
type: object
required:
- credentialsJSON
- credentialsJson
properties:
credentialsJSON:
credentialsJson:
type: string
description: The service account credentials JSON file. The service account should have Vertex AI user IAM role assigned to it.
description: The service account credentials JSON file. The service account should have Vertex AI user IAM role assigned to it.

View file

@ -37,7 +37,7 @@ const geminiConnector = {
gcpProjectID: 'test-project',
},
secrets: {
credentialsJSON: JSON.stringify({
credentialsJson: JSON.stringify({
type: 'service_account',
project_id: '',
private_key_id: '',
@ -83,6 +83,10 @@ describe('GeminiConnectorFields renders', () => {
);
expect(getAllByTestId('gemini-api-doc')[0]).toBeInTheDocument();
expect(getAllByTestId('gemini-api-model-doc')[0]).toBeInTheDocument();
expect(getAllByTestId('secrets.credentialsJson-input')[0]).toHaveValue(
geminiConnector.secrets.credentialsJson
);
});
describe('Dashboard link', () => {

View file

@ -8,7 +8,7 @@
import React from 'react';
import { fireEvent, render } from '@testing-library/react';
import GeminiParamsFields from './params';
import { DEFAULT_GEMINI_URL, SUB_ACTION } from '../../../common/gemini/constants';
import { SUB_ACTION } from '../../../common/gemini/constants';
import { I18nProvider } from '@kbn/i18n-react';
const messageVariables = [
@ -48,37 +48,9 @@ describe('Gemini Params Fields renders', () => {
};
const editAction = jest.fn();
const errors = {};
const actionConnector = {
secrets: {
credentialsJSON: JSON.stringify({
type: 'service_account',
project_id: '',
private_key_id: '',
private_key: '-----BEGIN PRIVATE KEY----------END PRIVATE KEY-----\n',
client_email: '',
client_id: '',
auth_uri: 'https://accounts.google.com/o/oauth2/auth',
token_uri: 'https://oauth2.googleapis.com/token',
auth_provider_x509_cert_url: 'https://www.googleapis.com/oauth2/v1/certs',
client_x509_cert_url: '',
}),
},
id: 'test',
actionTypeId: '.gemini',
isPreconfigured: false,
isSystemAction: false as const,
isDeprecated: false,
name: 'My Gemini Connector',
config: {
apiUrl: DEFAULT_GEMINI_URL,
gcpRegion: 'us-central-1',
gcpProjectID: 'test-project',
},
};
render(
<GeminiParamsFields
actionParams={actionParams}
actionConnector={actionConnector}
editAction={editAction}
index={0}
messageVariables={messageVariables}

View file

@ -37,7 +37,7 @@ export const SECRET = i18n.translate('xpack.stackConnectors.components.gemini.se
});
export const CREDENTIALS_JSON = i18n.translate(
'xpack.stackConnectors.components.gemini.credentialsJSON',
'xpack.stackConnectors.components.gemini.credentialsJson',
{
defaultMessage: 'Credentials JSON',
}

View file

@ -201,16 +201,16 @@ export class GeminiConnector extends SubActionConnector<Config, Secrets> {
/** Retrieve access token based on the GCP service account credential json file */
private async getAccessToken(): Promise<string | null> {
// Validate the service account credentials JSON file input
let credentialsJSON;
let credentialsJson;
try {
credentialsJSON = JSON.parse(this.secrets.credentialsJson);
credentialsJson = JSON.parse(this.secrets.credentialsJson);
} catch (error) {
throw new Error(`Failed to parse credentials JSON file: Invalid JSON format`);
}
const accessToken = await getGoogleOAuthJwtAccessToken({
connectorId: this.connector.id,
logger: this.logger,
credentials: credentialsJSON,
credentials: credentialsJson,
connectorTokenClient: this.connectorTokenClient,
});
return accessToken;

View file

@ -43196,7 +43196,7 @@
"xpack.stackConnectors.components.gemini.bodyCodeEditorAriaLabel": "Éditeur de code",
"xpack.stackConnectors.components.gemini.bodyFieldLabel": "Corps",
"xpack.stackConnectors.components.gemini.connectorTypeTitle": "Google Gemini",
"xpack.stackConnectors.components.gemini.credentialsJSON": "Informations d'identification JSON",
"xpack.stackConnectors.components.gemini.credentialsJson": "Informations d'identification JSON",
"xpack.stackConnectors.components.gemini.dashboardLink": "Affichez le tableau de bord d'utilisation de {apiProvider} pour le connecteur \"{ connectorName }\"",
"xpack.stackConnectors.components.gemini.defaultModelTextFieldLabel": "Modèle par défaut",
"xpack.stackConnectors.components.gemini.documentation": "documentation",

View file

@ -42935,7 +42935,7 @@
"xpack.stackConnectors.components.gemini.bodyCodeEditorAriaLabel": "コードエディター",
"xpack.stackConnectors.components.gemini.bodyFieldLabel": "本文",
"xpack.stackConnectors.components.gemini.connectorTypeTitle": "Google Gemini",
"xpack.stackConnectors.components.gemini.credentialsJSON": "資格情報JSON",
"xpack.stackConnectors.components.gemini.credentialsJson": "資格情報JSON",
"xpack.stackConnectors.components.gemini.dashboardLink": "\"{ connectorName }\"コネクターの{apiProvider}使用状況ダッシュボードを表示",
"xpack.stackConnectors.components.gemini.defaultModelTextFieldLabel": "デフォルトモデル",
"xpack.stackConnectors.components.gemini.documentation": "ドキュメンテーション",

View file

@ -42986,7 +42986,7 @@
"xpack.stackConnectors.components.gemini.bodyCodeEditorAriaLabel": "代码编辑器",
"xpack.stackConnectors.components.gemini.bodyFieldLabel": "正文",
"xpack.stackConnectors.components.gemini.connectorTypeTitle": "Google Gemini",
"xpack.stackConnectors.components.gemini.credentialsJSON": "凭据 JSON",
"xpack.stackConnectors.components.gemini.credentialsJson": "凭据 JSON",
"xpack.stackConnectors.components.gemini.dashboardLink": "查看“{ connectorName }”连接器的 {apiProvider} 使用情况仪表板",
"xpack.stackConnectors.components.gemini.defaultModelTextFieldLabel": "默认模型",
"xpack.stackConnectors.components.gemini.documentation": "文档",

View file

@ -40,6 +40,7 @@ const enabledActionTypes = [
'.bedrock',
'.cases-webhook',
'.email',
'.gemini',
'.index',
'.opsgenie',
'.pagerduty',

View file

@ -11,6 +11,7 @@ import {
geminiSuccessResponse,
} from '@kbn/actions-simulators-plugin/server/gemini_simulation';
import { TaskErrorSource } from '@kbn/task-manager-plugin/common';
import { DEFAULT_GEMINI_MODEL } from '@kbn/stack-connectors-plugin/common/gemini/constants';
import { FtrProviderContext } from '../../../../../common/ftr_provider_context';
const connectorTypeId = '.gemini';
@ -20,7 +21,7 @@ const defaultConfig = {
gcpProjectID: 'test-project',
};
const secrets = {
credentialsJSON: JSON.stringify({
credentialsJson: JSON.stringify({
type: 'service_account',
project_id: '',
private_key_id: '',
@ -39,14 +40,14 @@ export default function geminiTest({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const configService = getService('config');
const createConnector = async (url: string) => {
const createConnector = async (apiUrl: string) => {
const { body } = await supertest
.post('/api/actions/connector')
.set('kbn-xsrf', 'foo')
.send({
name,
connector_type_id: connectorTypeId,
config: { ...defaultConfig, url },
config: { ...defaultConfig, apiUrl },
secrets,
})
.expect(200);
@ -62,10 +63,10 @@ export default function geminiTest({ getService }: FtrProviderContext) {
config: configService.get('kbnTestServer.serverArgs'),
},
});
const config = { ...defaultConfig, url: '' };
const config = { ...defaultConfig, apiUrl: '' };
before(async () => {
config.url = await simulator.start();
config.apiUrl = await simulator.start();
});
after(() => {
@ -92,7 +93,10 @@ export default function geminiTest({ getService }: FtrProviderContext) {
name,
connector_type_id: connectorTypeId,
is_missing_secrets: false,
config,
config: {
...config,
defaultModel: DEFAULT_GEMINI_MODEL,
},
});
});
@ -112,20 +116,20 @@ export default function geminiTest({ getService }: FtrProviderContext) {
statusCode: 400,
error: 'Bad Request',
message:
'error validating action type config: [url, gcpRegion, gcpProjectID]: expected value of type [string] but got [undefined]',
'error validating action type config: [apiUrl]: expected value of type [string] but got [undefined]',
});
});
});
it('should return 400 Bad Request when creating the connector without the project id', async () => {
const testConfig = { gcpRegion: 'us-central-1', url: '' };
const testConfig = { gcpRegion: 'us-central-1', apiUrl: 'https://url.co' };
await supertest
.post('/api/actions/connector')
.set('kbn-xsrf', 'foo')
.send({
name,
connector_type_id: connectorTypeId,
testConfig,
config: testConfig,
secrets,
})
.expect(400)
@ -140,14 +144,14 @@ export default function geminiTest({ getService }: FtrProviderContext) {
});
it('should return 400 Bad Request when creating the connector without the region', async () => {
const testConfig = { gcpProjectID: 'test-project', url: '' };
const testConfig = { gcpProjectID: 'test-project', apiUrl: 'https://url.co' };
await supertest
.post('/api/actions/connector')
.set('kbn-xsrf', 'foo')
.send({
name,
connector_type_id: connectorTypeId,
testConfig,
config: testConfig,
secrets,
})
.expect(400)
@ -169,7 +173,8 @@ export default function geminiTest({ getService }: FtrProviderContext) {
name,
connector_type_id: connectorTypeId,
config: {
url: 'http://gemini.mynonexistent.com',
...defaultConfig,
apiUrl: 'http://gemini.mynonexistent.com',
},
secrets,
})
@ -179,7 +184,7 @@ export default function geminiTest({ getService }: FtrProviderContext) {
statusCode: 400,
error: 'Bad Request',
message:
'error validating action type config: error validating url: target url "http://gemini.mynonexistent.com" is not added to the Kibana config xpack.actions.allowedHosts',
'error validating action type config: Error configuring Google Gemini action: Error: error validating url: target url "http://gemini.mynonexistent.com" is not added to the Kibana config xpack.actions.allowedHosts',
});
});
});
@ -199,7 +204,7 @@ export default function geminiTest({ getService }: FtrProviderContext) {
statusCode: 400,
error: 'Bad Request',
message:
'error validating action type secrets: [token]: expected value of type [string] but got [undefined]',
'error validating action type secrets: [credentialsJson]: expected value of type [string] but got [undefined]',
});
});
});
@ -257,7 +262,7 @@ export default function geminiTest({ getService }: FtrProviderContext) {
retry: true,
message: 'an error occurred while running the action',
errorSource: TaskErrorSource.FRAMEWORK,
service_message: `Sub action "invalidAction" is not registered. Connector id: ${geminiActionId}. Connector name: Gemini. Connector type: .gemini`,
service_message: `Sub action "invalidAction" is not registered. Connector id: ${geminiActionId}. Connector name: Google Gemini. Connector type: .gemini`,
});
});
});
@ -269,19 +274,21 @@ export default function geminiTest({ getService }: FtrProviderContext) {
config: configService.get('kbnTestServer.serverArgs'),
},
});
let url: string;
let apiUrl: string;
let geminiActionId: string;
before(async () => {
url = await simulator.start();
geminiActionId = await createConnector(url);
apiUrl = await simulator.start();
geminiActionId = await createConnector(apiUrl);
});
after(() => {
simulator.close();
});
it('should invoke AI with assistant AI body argument formatted to gemini expectations', async () => {
// TODO to fix, we need to figure out how to mock the gcp oauth token
// https://github.com/elastic/kibana/issues/195437
it.skip('should invoke AI with assistant AI body argument formatted to gemini expectations', async () => {
const { body } = await supertest
.post(`/api/actions/connector/${geminiActionId}/_execute`)
.set('kbn-xsrf', 'foo')
@ -289,7 +296,7 @@ export default function geminiTest({ getService }: FtrProviderContext) {
params: {
subAction: 'invokeAI',
subActionParams: {
contents: [
messages: [
{
role: 'user',
parts: [
@ -315,7 +322,6 @@ export default function geminiTest({ getService }: FtrProviderContext) {
],
},
],
generation_config: { temperature: 0, maxOutputTokens: 8192 },
},
},
})

View file

@ -45,6 +45,7 @@ export default function connectorsTests({ loadTestFile, getService }: FtrProvide
loadTestFile(require.resolve('./connector_types/d3security'));
loadTestFile(require.resolve('./connector_types/thehive'));
loadTestFile(require.resolve('./connector_types/bedrock'));
loadTestFile(require.resolve('./connector_types/gemini'));
loadTestFile(require.resolve('./create'));
loadTestFile(require.resolve('./delete'));
loadTestFile(require.resolve('./execute'));