From 05857120125f43bb1df71ba73f1fb8582b4528ee Mon Sep 17 00:00:00 2001 From: Kylie Meli Date: Fri, 10 Jan 2025 12:09:39 -0500 Subject: [PATCH] [Automatic Import] Migrating to UX design and adding support for generating auth (#202587) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary This PR adds authentication to the generated CEL programs, and overhauls the UI flow to be closer to the forthcoming UX design. ## Details This PR provides the following updates related to CEL generation: 1. Adds support for generating auth - basic, oauth2, digest and api tokens 2. Adds new tooling for working with the OpenAPI specs and support for reducing the spec to minimally required information to the LLM (new Kibana dep on [oas](https://www.npmjs.com/package/oas)) 3. Addresses various feedback around the generated CEL program (error handling, cursor, trimming the state.url, etc) 4. Migrates the CEL flow to be closer to the forthcoming design specified by UX, now within a flyout on the datastream step. 5. Removes the dependency on the CEL generation feature flag ## Current screenshots
Click me the datastream setup page: Screenshot 2024-12-13 at 4 33 28 PM the user selects the cel input and the button to configure shows up: Screenshot 2024-12-13 at 4 33 49 PM upon clicking the button, the flyout opens: Screenshot 2024-12-13 at 4 34 02 PM the user can upload the spec file (a json or yaml openapi file): Screenshot 2024-12-13 at 4 34 30 PM the llm will suggest paths to use, or the user can select to enter manually and view all the GETs Screenshot 2024-12-13 at 4 35 26 PM we will also suggest an auth method based on the spec, but allow the user to select otherwise if they want: Screenshot 2024-12-13 at 4 35 37 PM if they choose an auth the spec doesn't specify, we will warn but not block: Screenshot 2024-12-16 at 9 07 52 AM once path and auth are selected, they can save and continue (generate the cel config): Screenshot 2024-12-13 at 4 35 50 PM generating: Screenshot 2024-12-13 at 4 36 18 PM all configured: Screenshot 2024-12-13 at 4 36 35 PM
## Sample results > **_Note:_** All these sample integrations are built with the teleport log samples. ### API key [eset.json](https://github.com/user-attachments/files/18151638/eset.json) [eset___api_key-1.0.0.zip](https://github.com/user-attachments/files/18151622/eset___api_key-1.0.0.zip) ### OAuth2 [bitwarden.json](https://github.com/user-attachments/files/18151635/bitwarden.json) [bitwarden___oauth-1.0.0.zip](https://github.com/user-attachments/files/18151618/bitwarden___oauth-1.0.0.zip) ### Basic [sumlogic-api.yaml.zip](https://github.com/user-attachments/files/18151650/sumlogic-api.yaml.zip) [sumologic___basic-1.0.0.zip](https://github.com/user-attachments/files/18151630/sumologic___basic-1.0.0.zip) Relates: - https://github.com/elastic/kibana/issues/197651 - https://github.com/elastic/kibana/issues/197653 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Ilya Nikokoshev --- package.json | 2 + .../translations/translations/fr-FR.json | 18 - .../translations/translations/ja-JP.json | 18 - .../translations/translations/zh-CN.json | 18 - .../__jest__/fixtures/api_analysis.ts | 22 + .../__jest__/fixtures/cel.ts | 38 +- .../__jest__/fixtures/index.ts | 15 +- .../api/analyze_api/analyze_api_route.gen.ts | 33 + .../analyze_api/analyze_api_route.schema.yaml | 39 + .../api/analyze_api/analyze_api_route.test.ts | 20 + .../common/api/cel/cel_input_route.gen.ts | 8 +- .../api/cel/cel_input_route.schema.yaml | 12 +- .../common/api/model/api_test.mock.ts | 19 +- .../api/model/cel_input_attributes.gen.ts | 47 +- .../model/cel_input_attributes.schema.yaml | 81 +- .../common/api/model/response_schemas.gen.ts | 11 +- .../api/model/response_schemas.schema.yaml | 17 +- .../integration_assistant/common/constants.ts | 1 + .../common/experimental_features.ts | 1 + .../integration_assistant/common/index.ts | 4 +- .../docs/imgs/analyze_api_graph.png | Bin 0 -> 12498 bytes .../docs/imgs/cel_graph.png | Bin 23312 -> 75906 bytes .../public/common/lib/api.ts | 18 +- .../create_integration_assistant.test.tsx | 328 +---- .../create_integration_assistant.tsx | 71 +- .../cel_configuration/create_cel_config.tsx | 109 ++ .../flyout/cel_configuration/footer.tsx | 93 ++ .../cel_configuration/index.ts} | 5 +- .../auth_selection.tsx | 74 ++ .../cel_confirm_step.tsx | 154 +++ .../endpoint_selection.tsx | 116 ++ .../generation_modal.tsx | 255 ++++ .../steps/cel_confirm_settings_step}/index.ts | 3 +- .../is_step_ready.ts | 11 + .../cel_confirm_settings_step/translations.ts | 88 ++ .../cel_input_step/api_definition_input.tsx | 173 +++ .../steps/cel_input_step/cel_input_step.tsx | 103 ++ .../steps/cel_input_step/generation_modal.tsx | 67 +- .../steps/cel_input_step/index.ts | 0 .../steps/cel_input_step/is_step_ready.ts | 11 + .../steps/cel_input_step/translations.ts | 101 ++ .../flyout/cel_configuration/translations.ts | 37 + .../footer/footer.tsx | 20 +- .../footer/translations.ts | 4 - .../mocks/state.ts | 15 +- .../create_integration_assistant/state.ts | 18 +- .../cel_input_step/api_definition_input.tsx | 118 -- .../steps/cel_input_step/cel_input_step.tsx | 71 -- .../steps/cel_input_step/is_step_ready.ts | 17 - .../steps/cel_input_step/translations.ts | 87 -- .../data_stream_step/data_stream_name.tsx | 37 + .../data_stream_step.test.tsx | 41 + .../data_stream_step/data_stream_step.tsx | 71 +- .../steps/data_stream_step/translations.ts | 51 + .../review_cel_step/cel_config_results.tsx | 65 - .../steps/review_cel_step/review_cel_step.tsx | 43 - .../steps/review_cel_step/translations.ts | 30 - .../create_integration_assistant/types.ts | 18 +- .../public/util/oas.test.ts | 1094 +++++++++++++++++ .../integration_assistant/public/util/oas.ts | 181 +++ .../scripts/draw_graphs_script.ts | 2 + .../server/graphs/api_analysis/constants.ts | 8 + .../server/graphs/api_analysis/graph.test.ts | 61 + .../server/graphs/api_analysis/graph.ts | 68 + .../server/graphs/api_analysis/index.ts | 8 + .../server/graphs/api_analysis/paths.test.ts | 28 + .../server/graphs/api_analysis/paths.ts | 30 + .../server/graphs/api_analysis/prompts.ts | 43 + .../server/graphs/api_analysis/types.ts | 20 + .../server/graphs/cel/analyze_headers.test.ts | 28 + .../server/graphs/cel/analyze_headers.ts | 28 + .../server/graphs/cel/auth_basic.test.ts | 28 + .../server/graphs/cel/auth_basic.ts | 31 + .../server/graphs/cel/auth_digest.test.ts | 28 + .../server/graphs/cel/auth_digest.ts | 30 + .../server/graphs/cel/auth_header.ts | 29 + .../server/graphs/cel/auth_oauth2.test.ts | 28 + .../server/graphs/cel/auth_oauth2.ts | 31 + .../server/graphs/cel/build_program.ts | 3 +- .../server/graphs/cel/constants.ts | 210 +++- .../server/graphs/cel/graph.test.ts | 170 ++- .../server/graphs/cel/graph.ts | 119 +- .../server/graphs/cel/prompts.ts | 201 ++- .../graphs/cel/retrieve_state_details.test.ts | 1 + .../graphs/cel/retrieve_state_details.ts | 10 +- .../server/graphs/cel/summarize_query.ts | 3 +- .../server/graphs/cel/types.ts | 5 +- .../server/graphs/cel/util.test.ts | 12 +- .../server/graphs/cel/util.ts | 17 + .../server/integration_builder/agent.test.ts | 40 +- .../server/integration_builder/agent.ts | 36 +- .../build_integration.test.ts | 12 +- .../integration_builder/build_integration.ts | 2 +- .../server/integration_builder/constants.ts | 11 + .../integration_builder/data_stream.test.ts | 17 +- .../server/integration_builder/data_stream.ts | 55 +- .../integration_assistant/server/plugin.ts | 7 +- .../server/routes/analyze_api_route.test.ts | 69 ++ .../server/routes/analyze_api_route.ts | 110 ++ .../server/routes/cel_route.test.ts | 22 +- .../server/routes/cel_routes.ts | 12 +- .../server/routes/register_routes.ts | 12 +- .../templates/agent/cel_generated.yml.hbs.njk | 141 +++ .../templates/manifest/cel_manifest.yml.njk | 41 +- .../integration_assistant/server/types.ts | 19 +- yarn.lock | 224 +++- 106 files changed, 5238 insertions(+), 1094 deletions(-) create mode 100644 x-pack/platform/plugins/shared/integration_assistant/__jest__/fixtures/api_analysis.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/common/api/analyze_api/analyze_api_route.gen.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/common/api/analyze_api/analyze_api_route.schema.yaml create mode 100644 x-pack/platform/plugins/shared/integration_assistant/common/api/analyze_api/analyze_api_route.test.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/docs/imgs/analyze_api_graph.png create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/flyout/cel_configuration/create_cel_config.tsx create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/flyout/cel_configuration/footer.tsx rename x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/{steps/review_cel_step/is_step_ready.ts => flyout/cel_configuration/index.ts} (57%) create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/flyout/cel_configuration/steps/cel_confirm_settings_step/auth_selection.tsx create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/flyout/cel_configuration/steps/cel_confirm_settings_step/cel_confirm_step.tsx create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/flyout/cel_configuration/steps/cel_confirm_settings_step/endpoint_selection.tsx create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/flyout/cel_configuration/steps/cel_confirm_settings_step/generation_modal.tsx rename x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/{steps/review_cel_step => flyout/cel_configuration/steps/cel_confirm_settings_step}/index.ts (84%) create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/flyout/cel_configuration/steps/cel_confirm_settings_step/is_step_ready.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/flyout/cel_configuration/steps/cel_confirm_settings_step/translations.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/flyout/cel_configuration/steps/cel_input_step/api_definition_input.tsx create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/flyout/cel_configuration/steps/cel_input_step/cel_input_step.tsx rename x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/{ => flyout/cel_configuration}/steps/cel_input_step/generation_modal.tsx (77%) rename x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/{ => flyout/cel_configuration}/steps/cel_input_step/index.ts (100%) create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/flyout/cel_configuration/steps/cel_input_step/is_step_ready.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/flyout/cel_configuration/steps/cel_input_step/translations.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/flyout/cel_configuration/translations.ts delete mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/steps/cel_input_step/api_definition_input.tsx delete mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/steps/cel_input_step/cel_input_step.tsx delete mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/steps/cel_input_step/is_step_ready.ts delete mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/steps/cel_input_step/translations.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/steps/data_stream_step/data_stream_name.tsx delete mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/steps/review_cel_step/cel_config_results.tsx delete mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/steps/review_cel_step/review_cel_step.tsx delete mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/steps/review_cel_step/translations.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/util/oas.test.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/public/util/oas.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/api_analysis/constants.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/api_analysis/graph.test.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/api_analysis/graph.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/api_analysis/index.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/api_analysis/paths.test.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/api_analysis/paths.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/api_analysis/prompts.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/api_analysis/types.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/cel/analyze_headers.test.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/cel/analyze_headers.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/cel/auth_basic.test.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/cel/auth_basic.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/cel/auth_digest.test.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/cel/auth_digest.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/cel/auth_header.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/cel/auth_oauth2.test.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/graphs/cel/auth_oauth2.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/routes/analyze_api_route.test.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/routes/analyze_api_route.ts create mode 100644 x-pack/platform/plugins/shared/integration_assistant/server/templates/agent/cel_generated.yml.hbs.njk diff --git a/package.json b/package.json index 018267b0388e5..510a94f8a2dc1 100644 --- a/package.json +++ b/package.json @@ -1173,6 +1173,7 @@ "json-stable-stringify": "^1.0.1", "json-stringify-pretty-compact": "1.2.0", "json-stringify-safe": "5.0.1", + "jsonpath-plus": "^10.2.0", "jsonwebtoken": "^9.0.2", "jsts": "^1.6.2", "kea": "^2.6.0", @@ -1204,6 +1205,7 @@ "nodemailer": "^6.9.15", "normalize-path": "^3.0.0", "nunjucks": "^3.2.4", + "oas": "^25.2.0", "object-hash": "^1.3.1", "object-path-immutable": "^3.1.1", "openai": "^4.72.0", diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index 42de200cec13b..4f2e66adc349a 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -23845,7 +23845,6 @@ "xpack.ingestPipelines.testPipelineFlyout.successNotificationText": "Pipeline exécuté", "xpack.ingestPipelines.testPipelineFlyout.title": "Pipeline de test", "xpack.integrationAssistant.bottomBar.addToElastic": "Ajouter à Elastic", - "xpack.integrationAssistant.bottomBar.analyzeCel": "Générer la configuration d'entrée CEL", "xpack.integrationAssistant.bottomBar.analyzeLogs": "Analyser les logs", "xpack.integrationAssistant.bottomBar.close": "Fermer", "xpack.integrationAssistant.bottomBar.loading": "Chargement", @@ -23901,17 +23900,6 @@ "xpack.integrationAssistant.missingPrivileges.title": "Privilèges manquants", "xpack.integrationAssistant.pages.header.avatarTitle": "Alimenté par l’IA générative", "xpack.integrationAssistant.pages.header.title": "Nouvelle intégration", - "xpack.integrationAssistant.step.celInput.apiDefinition.description": "Glissez et déposez un fichier ou parcourez les fichiers.", - "xpack.integrationAssistant.step.celInput.apiDefinition.description2": "Spécifications relatives à OpenAPI", - "xpack.integrationAssistant.step.celInput.apiDefinition.label": "Spéc. relatives à OpenAPI", - "xpack.integrationAssistant.step.celInput.celInputDescription": "Chargez un fichier de spécifications OpenAPI pour générer une configuration pour l'entrée CEL", - "xpack.integrationAssistant.step.celInput.celInputTitle": "Générer la configuration d'entrée CEL", - "xpack.integrationAssistant.step.celInput.generationError": "Une erreur s'est produite durant : Génération d'entrée CEL", - "xpack.integrationAssistant.step.celInput.openapiSpec.errorCanNotRead": "Impossible de lire le fichier de logs exemple", - "xpack.integrationAssistant.step.celInput.openapiSpec.errorCanNotReadWithReason": "Une erreur s'est produite lors de la lecture du fichier de spécifications : {reason}", - "xpack.integrationAssistant.step.celInput.openapiSpec.errorTooLargeToParse": "Ce fichier de spécifications est trop volumineux pour être analysé", - "xpack.integrationAssistant.step.celInput.progress.relatedGraph": "Génération de la configuration d'entrée CEL", - "xpack.integrationAssistant.step.celInput.retryButtonLabel": "Réessayer", "xpack.integrationAssistant.step.connector": "Connecteur", "xpack.integrationAssistant.step.dataStream": "Flux de données", "xpack.integrationAssistant.step.dataStream.analyzing": "Analyse", @@ -23963,12 +23951,6 @@ "xpack.integrationAssistant.step.review.ingestPipelineTitle": "Pipeline d'ingestion", "xpack.integrationAssistant.step.review.save": "Enregistrer", "xpack.integrationAssistant.step.review.title": "Examiner les résultats", - "xpack.integrationAssistant.step.reviewCel.description": "Vérifiez les paramètres de configuration d'entrée CEL générés pour votre intégration. Ces paramètres seront automatiquement renseignés dans la configuration d'intégration où la modification sera possible.", - "xpack.integrationAssistant.step.reviewCel.program": "Le programme CEL à exécuter pour chaque sondage", - "xpack.integrationAssistant.step.reviewCel.redact": "Champs à adapter", - "xpack.integrationAssistant.step.reviewCel.save": "Enregistrer", - "xpack.integrationAssistant.step.reviewCel.state": "État initial de l'évaluation du CEL", - "xpack.integrationAssistant.step.reviewCel.title": "Examiner les résultats", "xpack.integrationAssistant.steps.connector.createConnectorLabel": "Créer un nouveau connecteur", "xpack.integrationAssistant.steps.connector.description": "Sélectionnez un connecteur d’IA pour vous aider à créer votre intégration personnalisée", "xpack.integrationAssistant.steps.connector.supportedModelsInfo": "Pour une expérience optimale, nous recommandons actuellement d'utiliser un fournisseur prenant en charge les nouveaux modèles Claude. Nous travaillons actuellement à l'ajout d'une meilleure prise en charge de GPT-4 et de modèles similaires", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index 2303c208517ba..dd966042483a8 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -23706,7 +23706,6 @@ "xpack.ingestPipelines.testPipelineFlyout.successNotificationText": "パイプラインが実行されました", "xpack.ingestPipelines.testPipelineFlyout.title": "パイプラインをテスト", "xpack.integrationAssistant.bottomBar.addToElastic": "Elasticに追加", - "xpack.integrationAssistant.bottomBar.analyzeCel": "CEL入力構成を生成", "xpack.integrationAssistant.bottomBar.analyzeLogs": "ログを分析", "xpack.integrationAssistant.bottomBar.close": "閉じる", "xpack.integrationAssistant.bottomBar.loading": "読み込み中", @@ -23762,17 +23761,6 @@ "xpack.integrationAssistant.missingPrivileges.title": "不足している権限", "xpack.integrationAssistant.pages.header.avatarTitle": "生成AIを活用", "xpack.integrationAssistant.pages.header.title": "新しい統合", - "xpack.integrationAssistant.step.celInput.apiDefinition.description": "ファイルをドラッグアンドドロップするか、ファイルを参照します。", - "xpack.integrationAssistant.step.celInput.apiDefinition.description2": "OpenAPI仕様", - "xpack.integrationAssistant.step.celInput.apiDefinition.label": "OpenAPI仕様", - "xpack.integrationAssistant.step.celInput.celInputDescription": "OpenAPI仕様ファイルをアップロードして、CEL入力の構成を生成", - "xpack.integrationAssistant.step.celInput.celInputTitle": "CEL入力構成を生成", - "xpack.integrationAssistant.step.celInput.generationError": "エラーが発生しました:CEL入力生成", - "xpack.integrationAssistant.step.celInput.openapiSpec.errorCanNotRead": "ログサンプルファイルを読み取れませんでした", - "xpack.integrationAssistant.step.celInput.openapiSpec.errorCanNotReadWithReason": "仕様ファイルの読み取り中にエラーが発生しました:{reason}", - "xpack.integrationAssistant.step.celInput.openapiSpec.errorTooLargeToParse": "この仕様ファイルは大きすぎて解析できません", - "xpack.integrationAssistant.step.celInput.progress.relatedGraph": "CEL入力構成を生成中", - "xpack.integrationAssistant.step.celInput.retryButtonLabel": "再試行", "xpack.integrationAssistant.step.connector": "コネクター", "xpack.integrationAssistant.step.dataStream": "データストリーム", "xpack.integrationAssistant.step.dataStream.analyzing": "分析中", @@ -23824,12 +23812,6 @@ "xpack.integrationAssistant.step.review.ingestPipelineTitle": "パイプラインを投入", "xpack.integrationAssistant.step.review.save": "保存", "xpack.integrationAssistant.step.review.title": "結果を確認", - "xpack.integrationAssistant.step.reviewCel.description": "統合の生成されたCEL入力構成設定を確認してください。これらの設定は、編集が可能な場合、統合構成に自動的に入力されます。", - "xpack.integrationAssistant.step.reviewCel.program": "各ポーリングで実行されるCELプログラム", - "xpack.integrationAssistant.step.reviewCel.redact": "改訂されたフィールド", - "xpack.integrationAssistant.step.reviewCel.save": "保存", - "xpack.integrationAssistant.step.reviewCel.state": "初期CEL評価状態", - "xpack.integrationAssistant.step.reviewCel.title": "結果を確認", "xpack.integrationAssistant.steps.connector.createConnectorLabel": "新しいコネクターを作成", "xpack.integrationAssistant.steps.connector.description": "カスタム統合の作成を支援するAIコネクターを選択", "xpack.integrationAssistant.steps.connector.supportedModelsInfo": "現在、最高のエクスペリエンスが得られるように、新しいClaudeモデルをサポートするプロバイダーを利用することをお勧めします。現在、GPT-4や類似モデルへの改善されたサポートの追加に取り組んでいます。", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index e56d56268807d..c722363c6b6c9 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -23297,7 +23297,6 @@ "xpack.ingestPipelines.testPipelineFlyout.successNotificationText": "管道已执行", "xpack.ingestPipelines.testPipelineFlyout.title": "测试管道", "xpack.integrationAssistant.bottomBar.addToElastic": "添加到 Elastic", - "xpack.integrationAssistant.bottomBar.analyzeCel": "生成 CEL 输入配置", "xpack.integrationAssistant.bottomBar.analyzeLogs": "分析日志", "xpack.integrationAssistant.bottomBar.close": "关闭", "xpack.integrationAssistant.bottomBar.loading": "正在加载", @@ -23353,17 +23352,6 @@ "xpack.integrationAssistant.missingPrivileges.title": "缺少权限", "xpack.integrationAssistant.pages.header.avatarTitle": "由生成式 AI 提供支持", "xpack.integrationAssistant.pages.header.title": "新集成", - "xpack.integrationAssistant.step.celInput.apiDefinition.description": "拖放文件或浏览文件。", - "xpack.integrationAssistant.step.celInput.apiDefinition.description2": "OpenAPI 规范", - "xpack.integrationAssistant.step.celInput.apiDefinition.label": "OpenAPI 规范", - "xpack.integrationAssistant.step.celInput.celInputDescription": "上传 OpenAPI 规范文件以为 CEL 输入生成配置", - "xpack.integrationAssistant.step.celInput.celInputTitle": "生成 CEL 输入配置", - "xpack.integrationAssistant.step.celInput.generationError": "以下期间发生错误:CEL 输入生成", - "xpack.integrationAssistant.step.celInput.openapiSpec.errorCanNotRead": "无法读取日志样例文件", - "xpack.integrationAssistant.step.celInput.openapiSpec.errorCanNotReadWithReason": "读取规范文件时发生错误:{reason}", - "xpack.integrationAssistant.step.celInput.openapiSpec.errorTooLargeToParse": "此规范文件太大,无法解析", - "xpack.integrationAssistant.step.celInput.progress.relatedGraph": "正在生成 CEL 输入配置", - "xpack.integrationAssistant.step.celInput.retryButtonLabel": "重试", "xpack.integrationAssistant.step.connector": "连接器", "xpack.integrationAssistant.step.dataStream": "数据流", "xpack.integrationAssistant.step.dataStream.analyzing": "正在分析", @@ -23415,12 +23403,6 @@ "xpack.integrationAssistant.step.review.ingestPipelineTitle": "采集管道", "xpack.integrationAssistant.step.review.save": "保存", "xpack.integrationAssistant.step.review.title": "复查结果", - "xpack.integrationAssistant.step.reviewCel.description": "查看为您的集成生成的 CEL 输入配置设置。在可以进行编辑的情况下,会将这些设置自动填充到集成配置中。", - "xpack.integrationAssistant.step.reviewCel.program": "要为每次轮询运行的 CEL 程序", - "xpack.integrationAssistant.step.reviewCel.redact": "已编辑字段", - "xpack.integrationAssistant.step.reviewCel.save": "保存", - "xpack.integrationAssistant.step.reviewCel.state": "初始 CEL 评估状态", - "xpack.integrationAssistant.step.reviewCel.title": "复查结果", "xpack.integrationAssistant.steps.connector.createConnectorLabel": "创建新连接器", "xpack.integrationAssistant.steps.connector.description": "选择 AI 连接器以帮助您创建定制集成", "xpack.integrationAssistant.steps.connector.supportedModelsInfo": "当前,我们建议使用支持更新 Claude 模型的提供商,以获得最佳体验。目前,我们正努力为 GPT-4 和类似模型添加更全面的支持", diff --git a/x-pack/platform/plugins/shared/integration_assistant/__jest__/fixtures/api_analysis.ts b/x-pack/platform/plugins/shared/integration_assistant/__jest__/fixtures/api_analysis.ts new file mode 100644 index 0000000000000..e181160624af1 --- /dev/null +++ b/x-pack/platform/plugins/shared/integration_assistant/__jest__/fixtures/api_analysis.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ApiAnalysisState } from '../../server/types'; + +export const apiAnalysisTestState: ApiAnalysisState = { + dataStreamName: 'testDataStream', + lastExecutedChain: 'testchain', + results: { test: 'testResults' }, + pathOptions: { '/path1': 'path1 description', '/path2': 'path2 description' }, + suggestedPaths: ['/path1'], +}; + +export const apiAnalysisPathSuggestionsMockedResponse = ['/path1', '/path2', '/path3', '/path4']; + +export const apiAnalysisExpectedResults = { + suggestedPaths: ['/path1', '/path2', '/path3', '/path4'], +}; diff --git a/x-pack/platform/plugins/shared/integration_assistant/__jest__/fixtures/cel.ts b/x-pack/platform/plugins/shared/integration_assistant/__jest__/fixtures/cel.ts index e13c4216fbcdd..ff29e575baf6c 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/__jest__/fixtures/cel.ts +++ b/x-pack/platform/plugins/shared/integration_assistant/__jest__/fixtures/cel.ts @@ -5,18 +5,25 @@ * 2.0. */ -export const celTestState = { +import { CelInputState } from '../../server/types'; + +export const celTestState: CelInputState = { dataStreamName: 'testDataStream', - apiDefinition: 'apiDefinition', lastExecutedChain: 'testchain', finalized: false, apiQuerySummary: 'testQuerySummary', - exampleCelPrograms: [], currentProgram: 'testProgram', stateVarNames: ['testVar'], stateSettings: { test: 'testDetails' }, + configFields: { test: { config1: 'config1testDetails' } }, redactVars: ['testRedact'], results: { test: 'testResults' }, + path: './testPath', + authType: 'basic', + openApiPathDetails: {}, + openApiSchemas: {}, + openApiAuthSchema: {}, + hasProgramHeaders: false, }; export const celQuerySummaryMockedResponse = `To cover all events in a chronological manner for the device_tasks endpoint, you should use the /v1/device_tasks GET route with pagination parameters. Specifically, use the pageSize and pageToken query parameters. Start with a large pageSize and use the nextPageToken from each response to fetch subsequent pages until all events are retrieved. @@ -83,16 +90,25 @@ export const celStateDetailsMockedResponse = [ name: 'config1', default: 50, redact: false, + configurable: true, + description: 'config1 description', + type: 'number', }, { name: 'config2', default: '', redact: true, + configurable: false, + description: 'config2 description', + type: 'string', }, { name: 'config3', default: 'event', redact: false, + configurable: false, + description: 'config3 description', + type: 'string', }, ]; @@ -102,6 +118,14 @@ export const celStateSettings = { config3: 'event', }; +export const celConfigFields = { + config1: { + default: 50, + type: 'number', + description: 'config1 description', + }, +}; + export const celRedact = ['config2']; export const celExpectedResults = { @@ -111,5 +135,13 @@ export const celExpectedResults = { config2: '', config3: 'event', }, + configFields: { + config1: { + default: 50, + type: 'number', + description: 'config1 description', + }, + }, + needsAuthConfigBlock: false, redactVars: ['config2'], }; diff --git a/x-pack/platform/plugins/shared/integration_assistant/__jest__/fixtures/index.ts b/x-pack/platform/plugins/shared/integration_assistant/__jest__/fixtures/index.ts index a25e3d6cf43a7..6bfb32a61d3d6 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/__jest__/fixtures/index.ts +++ b/x-pack/platform/plugins/shared/integration_assistant/__jest__/fixtures/index.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { Pipeline } from '../../common'; +import type { CelAuthType, Pipeline } from '../../common'; const currentPipelineMock: Pipeline = { description: 'Pipeline to process mysql_enterprise audit logs', processors: [ @@ -53,7 +53,16 @@ export const mockedRequestWithPipeline = { currentPipeline: currentPipelineMock, }; -export const mockedRequestWithApiDefinition = { - apiDefinition: '{ "openapi": "3.0.0" }', +export const mockedRequestWithCelDetails = { + dataStreamTitle: 'audit', + path: '/events', + authType: 'basic' as CelAuthType, + openApiDetails: {}, + openApiSchema: {}, + openApiAuthSchema: {}, +}; + +export const mockedApiAnalysisRequest = { dataStreamName: 'audit', + pathOptions: { '/path1': 'path1 description' }, }; diff --git a/x-pack/platform/plugins/shared/integration_assistant/common/api/analyze_api/analyze_api_route.gen.ts b/x-pack/platform/plugins/shared/integration_assistant/common/api/analyze_api/analyze_api_route.gen.ts new file mode 100644 index 0000000000000..1db062322e7b1 --- /dev/null +++ b/x-pack/platform/plugins/shared/integration_assistant/common/api/analyze_api/analyze_api_route.gen.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* + * NOTICE: Do not edit this file manually. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. + * + * info: + * title: Automatic Import Analyze API specifications API endpoint + * version: 1 + */ + +import { z } from '@kbn/zod'; + +import { DataStreamTitle, Connector, LangSmithOptions } from '../model/common_attributes.gen'; +import { PathOptions } from '../model/cel_input_attributes.gen'; +import { AnalyzeApiAPIResponse } from '../model/response_schemas.gen'; + +export type AnalyzeApiRequestBody = z.infer; +export const AnalyzeApiRequestBody = z.object({ + dataStreamTitle: DataStreamTitle, + pathOptions: PathOptions, + connectorId: Connector, + langSmithOptions: LangSmithOptions.optional(), +}); +export type AnalyzeApiRequestBodyInput = z.input; + +export type AnalyzeApiResponse = z.infer; +export const AnalyzeApiResponse = AnalyzeApiAPIResponse; diff --git a/x-pack/platform/plugins/shared/integration_assistant/common/api/analyze_api/analyze_api_route.schema.yaml b/x-pack/platform/plugins/shared/integration_assistant/common/api/analyze_api/analyze_api_route.schema.yaml new file mode 100644 index 0000000000000..1478355e4ce92 --- /dev/null +++ b/x-pack/platform/plugins/shared/integration_assistant/common/api/analyze_api/analyze_api_route.schema.yaml @@ -0,0 +1,39 @@ +openapi: 3.0.3 +info: + title: Automatic Import Analyze API specifications API endpoint + version: "1" +paths: + /internal/automatic_import/analyzeapi: + post: + summary: Analyzes API specifications. + operationId: AnalyzeApi + x-codegen-enabled: true + description: Analyzes API specifications. + tags: + - Analyze API spec + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - dataStreamTitle + - pathOptions + - connectorId + properties: + dataStreamTitle: + $ref: "../model/common_attributes.schema.yaml#/components/schemas/DataStreamTitle" + pathOptions: + $ref: "../model/cel_input_attributes.schema.yaml#/components/schemas/PathOptions" + connectorId: + $ref: "../model/common_attributes.schema.yaml#/components/schemas/Connector" + langSmithOptions: + $ref: "../model/common_attributes.schema.yaml#/components/schemas/LangSmithOptions" + responses: + 200: + description: Indicates a successful call. + content: + application/json: + schema: + $ref: "../model/response_schemas.schema.yaml#/components/schemas/AnalyzeApiAPIResponse" \ No newline at end of file diff --git a/x-pack/platform/plugins/shared/integration_assistant/common/api/analyze_api/analyze_api_route.test.ts b/x-pack/platform/plugins/shared/integration_assistant/common/api/analyze_api/analyze_api_route.test.ts new file mode 100644 index 0000000000000..4ea2ce6e3d84c --- /dev/null +++ b/x-pack/platform/plugins/shared/integration_assistant/common/api/analyze_api/analyze_api_route.test.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { expectParseSuccess } from '@kbn/zod-helpers'; +import { AnalyzeApiRequestBody } from './analyze_api_route.gen'; +import { getAnalyzeApiRequestBody } from '../model/api_test.mock'; + +describe('Analyze API request schema', () => { + test('full request validate', () => { + const payload: AnalyzeApiRequestBody = getAnalyzeApiRequestBody(); + + const result = AnalyzeApiRequestBody.safeParse(payload); + expectParseSuccess(result); + expect(result.data).toEqual(payload); + }); +}); diff --git a/x-pack/platform/plugins/shared/integration_assistant/common/api/cel/cel_input_route.gen.ts b/x-pack/platform/plugins/shared/integration_assistant/common/api/cel/cel_input_route.gen.ts index 276fd27072c98..78acca695dcbc 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/common/api/cel/cel_input_route.gen.ts +++ b/x-pack/platform/plugins/shared/integration_assistant/common/api/cel/cel_input_route.gen.ts @@ -16,14 +16,14 @@ import { z } from '@kbn/zod'; -import { DataStreamName, Connector, LangSmithOptions } from '../model/common_attributes.gen'; -import { ApiDefinition } from '../model/cel_input_attributes.gen'; +import { DataStreamTitle, Connector, LangSmithOptions } from '../model/common_attributes.gen'; +import { CelDetails } from '../model/cel_input_attributes.gen'; import { CelInputAPIResponse } from '../model/response_schemas.gen'; export type CelInputRequestBody = z.infer; export const CelInputRequestBody = z.object({ - dataStreamName: DataStreamName, - apiDefinition: ApiDefinition, + dataStreamTitle: DataStreamTitle, + celDetails: CelDetails, connectorId: Connector, langSmithOptions: LangSmithOptions.optional(), }); diff --git a/x-pack/platform/plugins/shared/integration_assistant/common/api/cel/cel_input_route.schema.yaml b/x-pack/platform/plugins/shared/integration_assistant/common/api/cel/cel_input_route.schema.yaml index dc33d9ac69e3e..3cf96994fee63 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/common/api/cel/cel_input_route.schema.yaml +++ b/x-pack/platform/plugins/shared/integration_assistant/common/api/cel/cel_input_route.schema.yaml @@ -18,14 +18,14 @@ paths: schema: type: object required: - - apiDefinition - - dataStreamName + - dataStreamTitle + - celDetails - connectorId properties: - dataStreamName: - $ref: "../model/common_attributes.schema.yaml#/components/schemas/DataStreamName" - apiDefinition: - $ref: "../model/cel_input_attributes.schema.yaml#/components/schemas/ApiDefinition" + dataStreamTitle: + $ref: "../model/common_attributes.schema.yaml#/components/schemas/DataStreamTitle" + celDetails: + $ref: "../model/cel_input_attributes.schema.yaml#/components/schemas/CelDetails" connectorId: $ref: "../model/common_attributes.schema.yaml#/components/schemas/Connector" langSmithOptions: diff --git a/x-pack/platform/plugins/shared/integration_assistant/common/api/model/api_test.mock.ts b/x-pack/platform/plugins/shared/integration_assistant/common/api/model/api_test.mock.ts index c8f6967503ac3..5eebe4db17f75 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/common/api/model/api_test.mock.ts +++ b/x-pack/platform/plugins/shared/integration_assistant/common/api/model/api_test.mock.ts @@ -5,6 +5,7 @@ * 2.0. */ +import type { AnalyzeApiRequestBody } from '../analyze_api/analyze_api_route.gen'; import type { AnalyzeLogsRequestBody } from '../analyze_logs/analyze_logs_route.gen'; import type { BuildIntegrationRequestBody } from '../build_integration/build_integration.gen'; import type { CategorizationRequestBody } from '../categorization/categorization_route.gen'; @@ -67,9 +68,17 @@ export const getCategorizationRequestMock = (): CategorizationRequestBody => ({ }); export const getCelRequestMock = (): CelInputRequestBody => ({ - dataStreamName: 'test-data-stream-name', - apiDefinition: 'test-api-definition', + dataStreamTitle: 'test-data-stream-title', connectorId: 'test-connector-id', + celDetails: { + path: 'test-cel-path', + auth: 'basic', + openApiDetails: { + operation: 'test-open-api-operation', + schemas: 'test-open-api-schemas', + auth: 'test-open-api-auth', + }, + }, }); export const getBuildIntegrationRequestMock = (): BuildIntegrationRequestBody => ({ @@ -101,3 +110,9 @@ export const getAnalyzeLogsRequestBody = (): AnalyzeLogsRequestBody => ({ connectorId: 'test-connector-id', logSamples: rawSamples, }); + +export const getAnalyzeApiRequestBody = (): AnalyzeApiRequestBody => ({ + connectorId: 'test-connector-id', + dataStreamTitle: 'test-data-stream-name', + pathOptions: { '/v1/events': 'the path for events', '/v1/logs': 'the path for logs' }, +}); diff --git a/x-pack/platform/plugins/shared/integration_assistant/common/api/model/cel_input_attributes.gen.ts b/x-pack/platform/plugins/shared/integration_assistant/common/api/model/cel_input_attributes.gen.ts index 9ee1ee2ed290f..ed73099f9e74c 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/common/api/model/cel_input_attributes.gen.ts +++ b/x-pack/platform/plugins/shared/integration_assistant/common/api/model/cel_input_attributes.gen.ts @@ -16,18 +16,59 @@ import { z } from '@kbn/zod'; +export type PathOptions = z.infer; +export const PathOptions = z.object({}).catchall(z.unknown()); + +/** + * The type of auth utilized for the input. + */ +export type CelAuthType = z.infer; +export const CelAuthType = z.enum(['basic', 'digest', 'oauth2', 'header']); +export type CelAuthTypeEnum = typeof CelAuthType.enum; +export const CelAuthTypeEnum = CelAuthType.enum; + +/** + * Necessary OpenAPI spec details for building a CEL program. + */ +export type OpenApiDetails = z.infer; +export const OpenApiDetails = z.object({ + operation: z.string(), + schemas: z.string(), + auth: z.string().optional(), +}); + /** - * String form of the Open API schema. + * Details for building a CEL program. */ -export type ApiDefinition = z.infer; -export const ApiDefinition = z.string(); +export type CelDetails = z.infer; +export const CelDetails = z.object({ + path: z.string(), + auth: CelAuthType, + openApiDetails: OpenApiDetails.optional(), +}); + +/** + * Generated CEL details. + */ +export type GeneratedCelDetails = z.infer; +export const GeneratedCelDetails = z.object({ + configFields: z.object({}).catchall(z.unknown()), + program: z.string(), + needsAuthConfigBlock: z.boolean(), + stateSettings: z.object({}).catchall(z.unknown()), + redactVars: z.array(z.string()), +}); /** * Optional CEL input details. */ export type CelInput = z.infer; export const CelInput = z.object({ + authType: CelAuthType, + configFields: z.object({}).catchall(z.unknown()), + needsAuthConfigBlock: z.boolean(), program: z.string(), stateSettings: z.object({}).catchall(z.unknown()), redactVars: z.array(z.string()), + url: z.string(), }); diff --git a/x-pack/platform/plugins/shared/integration_assistant/common/api/model/cel_input_attributes.schema.yaml b/x-pack/platform/plugins/shared/integration_assistant/common/api/model/cel_input_attributes.schema.yaml index cd05202ddfda0..a4d575927a106 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/common/api/model/cel_input_attributes.schema.yaml +++ b/x-pack/platform/plugins/shared/integration_assistant/common/api/model/cel_input_attributes.schema.yaml @@ -6,18 +6,82 @@ paths: {} components: x-codegen-enabled: true schemas: - ApiDefinition: - type: string - description: String form of the Open API schema. + PathOptions: + type: object + additionalProperties: true + + CelDetails: + type: object + description: Details for building a CEL program. + required: + - path + - auth + properties: + path: + type: string + auth: + $ref: "#/components/schemas/CelAuthType" + openApiDetails: + $ref: "#/components/schemas/OpenApiDetails" + + OpenApiDetails: + type: object + description: Necessary OpenAPI spec details for building a CEL program. + required: + - operation + - schemas + properties: + operation: + type: string + schemas: + type: string + auth: + type: string + GeneratedCelDetails: + type: object + description: Generated CEL details. + required: + - configFields + - program + - needsAuthConfigBlock + - stateSettings + - redactVars + properties: + configFields: + type: object + additionalProperties: true + program: + type: string + needsAuthConfigBlock: + type: boolean + stateSettings: + type: object + additionalProperties: true + redactVars: + type: array + items: + type: string + CelInput: type: object description: Optional CEL input details. required: + - authType + - configFields - program + - needsAuthConfigBlock - stateSettings - redactVars + - url properties: + authType: + $ref: "#/components/schemas/CelAuthType" + configFields: + type: object + additionalProperties: true + needsAuthConfigBlock: + type: boolean program: type: string stateSettings: @@ -27,4 +91,15 @@ components: type: array items: type: string + url: + type: string + + CelAuthType: + type: string + description: The type of auth utilized for the input. + enum: + - basic + - digest + - oauth2 + - header \ No newline at end of file diff --git a/x-pack/platform/plugins/shared/integration_assistant/common/api/model/response_schemas.gen.ts b/x-pack/platform/plugins/shared/integration_assistant/common/api/model/response_schemas.gen.ts index f13b6fc537235..407e865f3625a 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/common/api/model/response_schemas.gen.ts +++ b/x-pack/platform/plugins/shared/integration_assistant/common/api/model/response_schemas.gen.ts @@ -18,7 +18,7 @@ import { z } from '@kbn/zod'; import { Mapping, Pipeline, Docs, SamplesFormat } from './common_attributes.gen'; import { ESProcessorItem } from './processor_attributes.gen'; -import { CelInput } from './cel_input_attributes.gen'; +import { GeneratedCelDetails } from './cel_input_attributes.gen'; export type EcsMappingAPIResponse = z.infer; export const EcsMappingAPIResponse = z.object({ @@ -62,5 +62,12 @@ export const AnalyzeLogsAPIResponse = z.object({ export type CelInputAPIResponse = z.infer; export const CelInputAPIResponse = z.object({ - results: CelInput, + results: GeneratedCelDetails, +}); + +export type AnalyzeApiAPIResponse = z.infer; +export const AnalyzeApiAPIResponse = z.object({ + results: z.object({ + suggestedPaths: z.array(z.string()), + }), }); diff --git a/x-pack/platform/plugins/shared/integration_assistant/common/api/model/response_schemas.schema.yaml b/x-pack/platform/plugins/shared/integration_assistant/common/api/model/response_schemas.schema.yaml index 62776b9dc5c13..b784bda3e6a95 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/common/api/model/response_schemas.schema.yaml +++ b/x-pack/platform/plugins/shared/integration_assistant/common/api/model/response_schemas.schema.yaml @@ -95,4 +95,19 @@ components: - results properties: results: - $ref: "./cel_input_attributes.schema.yaml#/components/schemas/CelInput" \ No newline at end of file + $ref: "./cel_input_attributes.schema.yaml#/components/schemas/GeneratedCelDetails" + + AnalyzeApiAPIResponse: + type: object + required: + - results + properties: + results: + type: object + required: + - suggestedPaths + properties: + suggestedPaths: + type: array + items: + type: string \ No newline at end of file diff --git a/x-pack/platform/plugins/shared/integration_assistant/common/constants.ts b/x-pack/platform/plugins/shared/integration_assistant/common/constants.ts index e05692f4ac085..352a84a96eabf 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/common/constants.ts +++ b/x-pack/platform/plugins/shared/integration_assistant/common/constants.ts @@ -20,6 +20,7 @@ export const ECS_GRAPH_PATH = `${INTEGRATION_ASSISTANT_BASE_PATH}/ecs`; export const CATEGORIZATION_GRAPH_PATH = `${INTEGRATION_ASSISTANT_BASE_PATH}/categorization`; export const ANALYZE_LOGS_PATH = `${INTEGRATION_ASSISTANT_BASE_PATH}/analyzelogs`; export const RELATED_GRAPH_PATH = `${INTEGRATION_ASSISTANT_BASE_PATH}/related`; +export const ANALYZE_API_PATH = `${INTEGRATION_ASSISTANT_BASE_PATH}/analyzeapi`; export const CEL_INPUT_GRAPH_PATH = `${INTEGRATION_ASSISTANT_BASE_PATH}/cel`; export const CHECK_PIPELINE_PATH = `${INTEGRATION_ASSISTANT_BASE_PATH}/pipeline`; export const INTEGRATION_BUILDER_PATH = `${INTEGRATION_ASSISTANT_BASE_PATH}/build`; diff --git a/x-pack/platform/plugins/shared/integration_assistant/common/experimental_features.ts b/x-pack/platform/plugins/shared/integration_assistant/common/experimental_features.ts index 76b4ed6f28fee..d4c5a48b0e9ec 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/common/experimental_features.ts +++ b/x-pack/platform/plugins/shared/integration_assistant/common/experimental_features.ts @@ -9,6 +9,7 @@ export type ExperimentalFeatures = typeof allowedExperimentalValues; const _allowedExperimentalValues = { /** + * -- Deprecated -- * Enables whether the user is able to utilize the LLM to generate the CEL input configuration. */ generateCel: false, diff --git a/x-pack/platform/plugins/shared/integration_assistant/common/index.ts b/x-pack/platform/plugins/shared/integration_assistant/common/index.ts index 0b13f7f692695..60ee134cf9acf 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/common/index.ts +++ b/x-pack/platform/plugins/shared/integration_assistant/common/index.ts @@ -19,6 +19,7 @@ export { AnalyzeLogsRequestBody, AnalyzeLogsResponse, } from './api/analyze_logs/analyze_logs_route.gen'; +export { AnalyzeApiRequestBody, AnalyzeApiResponse } from './api/analyze_api/analyze_api_route.gen'; export { CelInputRequestBody, CelInputResponse } from './api/cel/cel_input_route.gen'; export { partialShuffleArray } from './utils'; @@ -33,7 +34,7 @@ export type { } from './api/model/common_attributes.gen'; export { SamplesFormat, SamplesFormatName } from './api/model/common_attributes.gen'; export type { ESProcessorItem } from './api/model/processor_attributes.gen'; -export type { CelInput } from './api/model/cel_input_attributes.gen'; +export type { CelInput, CelAuthType } from './api/model/cel_input_attributes.gen'; export { CATEGORIZATION_GRAPH_PATH, @@ -46,4 +47,5 @@ export { RELATED_GRAPH_PATH, CHECK_PIPELINE_PATH, ANALYZE_LOGS_PATH, + ANALYZE_API_PATH, } from './constants'; diff --git a/x-pack/platform/plugins/shared/integration_assistant/docs/imgs/analyze_api_graph.png b/x-pack/platform/plugins/shared/integration_assistant/docs/imgs/analyze_api_graph.png new file mode 100644 index 0000000000000000000000000000000000000000..085e4ae161c5411c25c953484a01a02d26db9c99 GIT binary patch literal 12498 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 X?y%Gkow|kRm|+d=e@zMl?xz12=dDwt literal 0 HcmV?d00001 diff --git a/x-pack/platform/plugins/shared/integration_assistant/docs/imgs/cel_graph.png b/x-pack/platform/plugins/shared/integration_assistant/docs/imgs/cel_graph.png index 8b339caa83798f06a7149b92f998fd9c2f409453..7ae98632553e99d3450e89bbe46abb6a8a840427 100644 GIT binary patch literal 75906 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 z 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 diff --git a/x-pack/platform/plugins/shared/integration_assistant/public/common/lib/api.ts b/x-pack/platform/plugins/shared/integration_assistant/public/common/lib/api.ts index 0a6d91375219e..3694715b4d31b 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/public/common/lib/api.ts +++ b/x-pack/platform/plugins/shared/integration_assistant/public/common/lib/api.ts @@ -20,6 +20,8 @@ import type { AnalyzeLogsResponse, CelInputRequestBody, CelInputResponse, + AnalyzeApiRequestBody, + AnalyzeApiResponse, } from '../../../common'; import { INTEGRATION_BUILDER_PATH, @@ -29,7 +31,11 @@ import { CEL_INPUT_GRAPH_PATH, CHECK_PIPELINE_PATH, } from '../../../common'; -import { ANALYZE_LOGS_PATH, FLEET_PACKAGES_PATH } from '../../../common/constants'; +import { + ANALYZE_API_PATH, + ANALYZE_LOGS_PATH, + FLEET_PACKAGES_PATH, +} from '../../../common/constants'; export interface EpmPackageResponse { items: [{ id: string; type: string }]; @@ -47,6 +53,16 @@ export interface RequestDeps { abortSignal: AbortSignal; } +export const runAnalyzeApiGraph = async ( + body: AnalyzeApiRequestBody, + { http, abortSignal }: RequestDeps +): Promise => + http.post(ANALYZE_API_PATH, { + headers: defaultHeaders, + body: JSON.stringify(body), + signal: abortSignal, + }); + export const runAnalyzeLogsGraph = async ( body: AnalyzeLogsRequestBody, { http, abortSignal }: RequestDeps diff --git a/x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/create_integration_assistant.test.tsx b/x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/create_integration_assistant.test.tsx index 133da383e4e99..5e40b2dcbc86a 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/create_integration_assistant.test.tsx +++ b/x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/create_integration_assistant.test.tsx @@ -10,7 +10,6 @@ import { render, act } from '@testing-library/react'; import { TestProvider } from '../../../mocks/test_provider'; import { CreateIntegrationAssistant } from './create_integration_assistant'; import type { State } from './state'; -import { ExperimentalFeaturesService } from '../../../services'; import { mockReportEvent } from '../../../services/telemetry/mocks/service'; import { TelemetryEventType } from '../../../services/telemetry/types'; @@ -19,8 +18,9 @@ export const defaultInitialState: State = { connector: undefined, integrationSettings: undefined, isGenerating: false, - hasCelInput: false, result: undefined, + showCelCreateFlyout: false, + isFlyoutGenerating: false, }; const mockInitialState = jest.fn((): State => defaultInitialState); @@ -31,23 +31,17 @@ jest.mock('./state', () => ({ }, })); -jest.mock('../../../services'); -const mockedExperimentalFeaturesService = jest.mocked(ExperimentalFeaturesService); - const mockConnectorStep = jest.fn(() =>
); const mockIntegrationStep = jest.fn(() =>
); const mockDataStreamStep = jest.fn(() =>
); +const mockCelCreateFlyout = jest.fn(() =>
); const mockReviewStep = jest.fn(() =>
); -const mockCelInputStep = jest.fn(() =>
); -const mockReviewCelStep = jest.fn(() =>
); const mockDeployStep = jest.fn(() =>
); const mockIsConnectorStepReadyToComplete = jest.fn(); const mockIsIntegrationStepReadyToComplete = jest.fn(); const mockIsDataStreamStepReadyToComplete = jest.fn(); const mockIsReviewStepReadyToComplete = jest.fn(); -const mockIsCelInputStepReadyToComplete = jest.fn(); -const mockIsCelReviewStepReadyToComplete = jest.fn(); jest.mock('./steps/connector_step', () => ({ ConnectorStep: () => mockConnectorStep(), @@ -61,18 +55,13 @@ jest.mock('./steps/data_stream_step', () => ({ DataStreamStep: () => mockDataStreamStep(), isDataStreamStepReadyToComplete: () => mockIsDataStreamStepReadyToComplete(), })); +jest.mock('./flyout/cel_configuration', () => ({ + CreateCelConfigFlyout: () => mockCelCreateFlyout(), +})); jest.mock('./steps/review_step', () => ({ ReviewStep: () => mockReviewStep(), isReviewStepReadyToComplete: () => mockIsReviewStepReadyToComplete(), })); -jest.mock('./steps/cel_input_step', () => ({ - CelInputStep: () => mockCelInputStep(), - isCelInputStepReadyToComplete: () => mockIsCelInputStepReadyToComplete(), -})); -jest.mock('./steps/review_cel_step', () => ({ - ReviewCelStep: () => mockReviewCelStep(), - isCelReviewStepReadyToComplete: () => mockIsCelReviewStepReadyToComplete(), -})); jest.mock('./steps/deploy_step', () => ({ DeployStep: () => mockDeployStep() })); const mockNavigate = jest.fn(); @@ -87,10 +76,6 @@ const renderIntegrationAssistant = () => describe('CreateIntegration', () => { beforeEach(() => { jest.clearAllMocks(); - - mockedExperimentalFeaturesService.get.mockReturnValue({ - generateCel: false, - } as never); }); describe('when step is 1', () => { @@ -440,6 +425,21 @@ describe('CreateIntegration', () => { }); }); + describe('when step is 3 and showCelCreateFlyout=true', () => { + beforeEach(() => { + mockInitialState.mockReturnValueOnce({ + ...defaultInitialState, + step: 3, + showCelCreateFlyout: true, + }); + }); + + it('should render cel creation flyout', () => { + const result = renderIntegrationAssistant(); + expect(result.queryByTestId('celCreateFlyoutMock')).toBeInTheDocument(); + }); + }); + describe('when step is 4', () => { beforeEach(() => { mockInitialState.mockReturnValueOnce({ ...defaultInitialState, step: 4 }); @@ -567,289 +567,3 @@ describe('CreateIntegration', () => { }); }); }); - -describe('CreateIntegration with generateCel enabled', () => { - beforeEach(() => { - jest.clearAllMocks(); - - mockedExperimentalFeaturesService.get.mockReturnValue({ - generateCel: true, - } as never); - }); - - describe('when step is 5 and has celInput', () => { - beforeEach(() => { - mockInitialState.mockReturnValueOnce({ ...defaultInitialState, step: 5, hasCelInput: true }); - }); - - it('should render cel input', () => { - const result = renderIntegrationAssistant(); - expect(result.queryByTestId('celInputStepMock')).toBeInTheDocument(); - }); - - it('should call isCelInputStepReadyToComplete', () => { - renderIntegrationAssistant(); - expect(mockIsCelInputStepReadyToComplete).toHaveBeenCalled(); - }); - - it('should show "Generate CEL input configuration" on the next button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('buttonsFooter-nextButton')).toHaveTextContent( - 'Generate CEL input configuration' - ); - }); - - it('should enable the back button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('buttonsFooter-backButton')).toBeEnabled(); - }); - - describe('when cel input step is not done', () => { - beforeEach(() => { - mockIsCelInputStepReadyToComplete.mockReturnValue(false); - }); - - it('should disable the next button', () => { - const result = renderIntegrationAssistant(); - // Not sure why there are two buttons when testing. - const nextButton = result - .getAllByTestId('buttonsFooter-nextButton') - .filter((button) => button.textContent !== 'Next')[0]; - expect(nextButton).toBeDisabled(); - }); - }); - - describe('when cel input step is done', () => { - beforeEach(() => { - mockIsCelInputStepReadyToComplete.mockReturnValue(true); - }); - - it('should enable the next button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('buttonsFooter-nextButton')).toBeEnabled(); - }); - - describe('when next button is clicked', () => { - beforeEach(() => { - const result = renderIntegrationAssistant(); - mockReportEvent.mockClear(); - act(() => { - result.getByTestId('buttonsFooter-nextButton').click(); - }); - }); - - it('should report telemetry for cel input step completion', () => { - expect(mockReportEvent).toHaveBeenCalledWith( - TelemetryEventType.IntegrationAssistantStepComplete, - { - sessionId: expect.any(String), - step: 5, - stepName: 'CEL Input Step', - durationMs: expect.any(Number), - sessionElapsedTime: expect.any(Number), - } - ); - }); - - it('should show loader on the next button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('generatingLoader')).toBeInTheDocument(); - }); - - it('should disable the next button', () => { - const result = renderIntegrationAssistant(); - // Not sure why there are two buttons when testing. - const nextButton = result - .getAllByTestId('buttonsFooter-nextButton') - .filter((button) => button.textContent !== 'Next')[0]; - expect(nextButton).toBeDisabled(); - }); - }); - }); - - describe('when back button is clicked', () => { - let result: ReturnType; - beforeEach(() => { - result = renderIntegrationAssistant(); - mockReportEvent.mockClear(); - act(() => { - result.getByTestId('buttonsFooter-backButton').click(); - }); - }); - - it('should not report telemetry', () => { - expect(mockReportEvent).not.toHaveBeenCalled(); - }); - - it('should show review step', () => { - expect(result.queryByTestId('reviewStepMock')).toBeInTheDocument(); - }); - - it('should enable the next button', () => { - expect(result.getByTestId('buttonsFooter-nextButton')).toBeEnabled(); - }); - }); - }); - - describe('when step is 5 and does not have celInput', () => { - beforeEach(() => { - mockInitialState.mockReturnValueOnce({ ...defaultInitialState, step: 5 }); - }); - - it('should render deploy', () => { - const result = renderIntegrationAssistant(); - expect(result.queryByTestId('deployStepMock')).toBeInTheDocument(); - }); - - it('should hide the back button', () => { - const result = renderIntegrationAssistant(); - expect(result.queryByTestId('buttonsFooter-backButton')).toBe(null); - }); - - it('should hide the next button', () => { - const result = renderIntegrationAssistant(); - expect(result.queryByTestId('buttonsFooter-backButton')).toBe(null); - }); - - it('should enable the cancel button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('buttonsFooter-cancelButton')).toBeEnabled(); - }); - - it('should show "Close" on the cancel button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('buttonsFooter-cancelButton')).toHaveTextContent('Close'); - }); - }); - - describe('when step is 6', () => { - beforeEach(() => { - mockInitialState.mockReturnValueOnce({ - ...defaultInitialState, - step: 6, - celInputResult: { program: 'program', stateSettings: {}, redactVars: [] }, - }); - }); - - it('should render review', () => { - const result = renderIntegrationAssistant(); - expect(result.queryByTestId('reviewCelStepMock')).toBeInTheDocument(); - }); - - it('should call isReviewCelStepReadyToComplete', () => { - renderIntegrationAssistant(); - expect(mockIsCelReviewStepReadyToComplete).toHaveBeenCalled(); - }); - - it('should show the "Add to Elastic" on the next button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('buttonsFooter-nextButton')).toHaveTextContent('Add to Elastic'); - }); - - describe('when cel review step is not done', () => { - beforeEach(() => { - mockIsCelReviewStepReadyToComplete.mockReturnValue(false); - }); - - it('should disable the next button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('buttonsFooter-nextButton')).toBeDisabled(); - }); - - it('should still enable the back button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('buttonsFooter-backButton')).toBeEnabled(); - }); - - it('should still enable the cancel button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('buttonsFooter-cancelButton')).toBeEnabled(); - }); - }); - - describe('when cel review step is done', () => { - beforeEach(() => { - mockIsCelReviewStepReadyToComplete.mockReturnValue(true); - }); - - it('should enable the next button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('buttonsFooter-nextButton')).toBeEnabled(); - }); - - it('should enable the back button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('buttonsFooter-backButton')).toBeEnabled(); - }); - - it('should enable the cancel button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('buttonsFooter-cancelButton')).toBeEnabled(); - }); - - describe('when next button is clicked', () => { - beforeEach(() => { - const result = renderIntegrationAssistant(); - mockReportEvent.mockClear(); - act(() => { - result.getByTestId('buttonsFooter-nextButton').click(); - }); - }); - - it('should report telemetry for review step completion', () => { - expect(mockReportEvent).toHaveBeenCalledWith( - TelemetryEventType.IntegrationAssistantStepComplete, - { - sessionId: expect.any(String), - step: 6, - stepName: 'CEL Review Step', - durationMs: expect.any(Number), - sessionElapsedTime: expect.any(Number), - } - ); - }); - - it('should show deploy step', () => { - const result = renderIntegrationAssistant(); - expect(result.queryByTestId('deployStepMock')).toBeInTheDocument(); - }); - - it('should enable the next button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('buttonsFooter-nextButton')).toBeEnabled(); - }); - }); - }); - }); - - describe('when step is 7', () => { - beforeEach(() => { - mockInitialState.mockReturnValueOnce({ ...defaultInitialState, step: 7 }); - }); - - it('should render deploy', () => { - const result = renderIntegrationAssistant(); - expect(result.queryByTestId('deployStepMock')).toBeInTheDocument(); - }); - - it('should hide the back button', () => { - const result = renderIntegrationAssistant(); - expect(result.queryByTestId('buttonsFooter-backButton')).toBe(null); - }); - - it('should hide the next button', () => { - const result = renderIntegrationAssistant(); - expect(result.queryByTestId('buttonsFooter-backButton')).toBe(null); - }); - - it('should enable the cancel button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('buttonsFooter-cancelButton')).toBeEnabled(); - }); - - it('should show "Close" on the cancel button', () => { - const result = renderIntegrationAssistant(); - expect(result.getByTestId('buttonsFooter-cancelButton')).toHaveTextContent('Close'); - }); - }); -}); diff --git a/x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/create_integration_assistant.tsx b/x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/create_integration_assistant.tsx index 81cb5a9b3b137..1f353f187bb2a 100644 --- a/x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/create_integration_assistant.tsx +++ b/x-pack/platform/plugins/shared/integration_assistant/public/components/create_integration/create_integration_assistant/create_integration_assistant.tsx @@ -9,48 +9,29 @@ import React, { useReducer, useMemo, useEffect, useCallback } from 'react'; import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import { Header } from './header'; import { Footer } from './footer'; +import { CreateCelConfigFlyout } from './flyout/cel_configuration'; import { useNavigate, Page } from '../../../common/hooks/use_navigate'; import { ConnectorStep, isConnectorStepReadyToComplete } from './steps/connector_step'; import { IntegrationStep, isIntegrationStepReadyToComplete } from './steps/integration_step'; import { DataStreamStep, isDataStreamStepReadyToComplete } from './steps/data_stream_step'; import { ReviewStep, isReviewStepReadyToComplete } from './steps/review_step'; -import { CelInputStep, isCelInputStepReadyToComplete } from './steps/cel_input_step'; -import { ReviewCelStep, isCelReviewStepReadyToComplete } from './steps/review_cel_step'; import { DeployStep } from './steps/deploy_step'; import { reducer, initialState, ActionsProvider, type Actions } from './state'; import { useTelemetry } from '../telemetry'; -import { ExperimentalFeaturesService } from '../../../services'; const stepNames: Record = { 1: 'Connector Step', 2: 'Integration Step', 3: 'DataStream Step', 4: 'Review Step', - cel_input: 'CEL Input Step', - cel_review: 'CEL Review Step', - deploy: 'Deploy Step', + 5: 'Deploy Step', }; export const CreateIntegrationAssistant = React.memo(() => { const [state, dispatch] = useReducer(reducer, initialState); const navigate = useNavigate(); - const { generateCel: isGenerateCelEnabled } = ExperimentalFeaturesService.get(); - const celInputStepIndex = isGenerateCelEnabled && state.hasCelInput ? 5 : null; - const celReviewStepIndex = isGenerateCelEnabled && state.celInputResult ? 6 : null; - const deployStepIndex = - celInputStepIndex !== null || celReviewStepIndex !== null || state.step === 7 ? 7 : 5; - - const stepName = - state.step === deployStepIndex - ? stepNames.deploy - : state.step === celReviewStepIndex - ? stepNames.cel_review - : state.step === celInputStepIndex - ? stepNames.cel_input - : state.step in stepNames - ? stepNames[state.step] - : 'Unknown Step'; + const stepName = stepNames[state.step]; const telemetry = useTelemetry(); useEffect(() => { @@ -66,13 +47,9 @@ export const CreateIntegrationAssistant = React.memo(() => { return isDataStreamStepReadyToComplete(state); } else if (state.step === 4) { return isReviewStepReadyToComplete(state); - } else if (isGenerateCelEnabled && state.step === 5) { - return isCelInputStepReadyToComplete(state); - } else if (isGenerateCelEnabled && state.step === 6) { - return isCelReviewStepReadyToComplete(state); } return false; - }, [state, isGenerateCelEnabled]); + }, [state]); const goBackStep = useCallback(() => { if (state.step === 1) { @@ -88,12 +65,12 @@ export const CreateIntegrationAssistant = React.memo(() => { return; } telemetry.reportAssistantStepComplete({ step: state.step, stepName }); - if (state.step === 3 || state.step === celInputStepIndex) { + if (state.step === 3) { dispatch({ type: 'SET_IS_GENERATING', payload: true }); } else { dispatch({ type: 'SET_STEP', payload: state.step + 1 }); } - }, [telemetry, state.step, stepName, celInputStepIndex, isThisStepReadyToComplete]); + }, [telemetry, state.step, stepName, isThisStepReadyToComplete]); const actions = useMemo( () => ({ @@ -109,8 +86,11 @@ export const CreateIntegrationAssistant = React.memo(() => { setIsGenerating: (payload) => { dispatch({ type: 'SET_IS_GENERATING', payload }); }, - setHasCelInput: (payload) => { - dispatch({ type: 'SET_HAS_CEL_INPUT', payload }); + setShowCelCreateFlyout: (payload) => { + dispatch({ type: 'SET_SHOW_CEL_CREATE_FLYOUT', payload }); + }, + setIsFlyoutGenerating: (payload) => { + dispatch({ type: 'SET_IS_FLYOUT_GENERATING', payload }); }, setResult: (payload) => { dispatch({ type: 'SET_GENERATED_RESULT', payload }); @@ -133,32 +113,26 @@ export const CreateIntegrationAssistant = React.memo(() => { {state.step === 3 && ( )} - {state.step === 4 && ( - - )} - {state.step === celInputStepIndex && ( - )} - {state.step === celReviewStepIndex && ( - )} - - {state.step === deployStepIndex && ( + {state.step === 5 && ( {