-
Notifications
You must be signed in to change notification settings - Fork 268
feat: add n8n, langchain and copilot-studio connector functionality #3704
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+1,313
−4
Merged
Changes from all commits
Commits
Show all changes
64 commits
Select commit
Hold shift + click to select a range
c3ab792
feat: add n8n import UI
abhijeet-akto f3350c4
feat: add API for N8N import
abhijeet-akto 4718440
chore: add database integration
abhijeet-akto 0ee9315
chore: change collection name to generic
abhijeet-akto aca1368
fix: config structure
abhijeet-akto 3a9f9a1
feat: add cron to schedule jobs
abhijeet-akto 471d8e5
fix: issues with cron scheduler
abhijeet-akto d1913b9
feat: add langchain support
abhijeet-akto d1ab9b6
feat: add copilot studio support
abhijeet-akto 9a7695f
chore: remove log statements
abhijeet-akto 2b7a174
chore: add langchain logo
abhijeet-akto a9b2de6
feat: add cron support for AI agent
abhijeet-akto a02217e
feat: new implementation for scheduling ai agents jobs
abhijeet-akto ca1213b
feat: add azure download functionality
abhijeet-akto 22861a8
chore: change job intervals
abhijeet-akto 23cc09e
feat: add implementation for copilot and langchain
abhijeet-akto f92d6b5
fix: security valunerability
abhijeet-akto 93008d0
fix: security valunerability
abhijeet-akto 1c64776
fix: security valunerability
abhijeet-akto 331e349
fix: security valunerability
abhijeet-akto 9b8337c
fix: security valunerability
abhijeet-akto d785e77
fix: security valunerability
abhijeet-akto aad391c
fix: security valunerability
abhijeet-akto b5e5e69
Merge pull request #3720 from akto-api-security/abhi/feat/ai-agent-cr…
abhijeet-akto b682f0c
fix: security valunerability
abhijeet-akto dd68849
fix: security valunerability
abhijeet-akto a312c47
fix: security valunerability
abhijeet-akto bfe84eb
fix: security valunerability
abhijeet-akto 722fe0e
fix: security valunerability
abhijeet-akto 458dd0f
fix: security valunerability
abhijeet-akto 548c056
fix: security valunerability
abhijeet-akto da4e570
fix: security valunerability
abhijeet-akto fd5c566
fix: security valunerability
abhijeet-akto f699ed2
fix: security valunerability
abhijeet-akto 34caefe
fix: security valunerability
abhijeet-akto 92cacc0
fix: security valunerability
abhijeet-akto 1716090
fix: security valunerability
abhijeet-akto 1a2b100
fix: security valunerability
abhijeet-akto b472977
Update libs/utils/src/main/java/com/akto/jobs/executors/AIAgentConnec…
abhijeet-akto 2c85780
Update libs/utils/src/main/java/com/akto/jobs/executors/AIAgentConnec…
abhijeet-akto dd7ab2f
Update libs/utils/src/main/java/com/akto/jobs/executors/AIAgentConnec…
abhijeet-akto a494869
Update libs/utils/src/main/java/com/akto/jobs/executors/AIAgentConnec…
abhijeet-akto dce6fd1
Update libs/utils/src/main/java/com/akto/jobs/executors/AIAgentConnec…
abhijeet-akto a8879bf
Update libs/utils/src/main/java/com/akto/jobs/executors/AIAgentConnec…
abhijeet-akto 246a0c6
Update libs/utils/src/main/java/com/akto/jobs/executors/AIAgentConnec…
abhijeet-akto a7b04f6
Update libs/utils/src/main/java/com/akto/jobs/executors/AIAgentConnec…
abhijeet-akto 2980494
Update libs/utils/src/main/java/com/akto/jobs/executors/AIAgentConnec…
abhijeet-akto 7a3ea6a
Update libs/utils/src/main/java/com/akto/jobs/executors/AIAgentConnec…
abhijeet-akto 3c71b16
Update libs/utils/src/main/java/com/akto/jobs/executors/AIAgentConnec…
abhijeet-akto ea9214a
fix: security valunerability
abhijeet-akto f5dab11
fix: security valunerability
abhijeet-akto 7efb3b4
fix: security valunerability
abhijeet-akto eae8e77
Merge pull request #3729 from akto-api-security/abhi/feat/ai-agent-cr…
abhijeet-akto d1c7d4e
chore: resolve pr comments
abhijeet-akto d44e07c
chore: code cleaning
abhijeet-akto 43c703f
chore: remove unused code
abhijeet-akto 58cd439
chore: resolved pr comments
abhijeet-akto 152733b
chore: resolved pr comments
abhijeet-akto 197daac
feat: add auth support for api key
abhijeet-akto 9737cd7
feat: add auth logic
abhijeet-akto 47adc21
chore: remove auth logic
abhijeet-akto d3dd787
chore: remove auth logic
abhijeet-akto f0c164e
feat: add jwt auth logic
abhijeet-akto 8742fbf
chore: updated documentation
abhijeet-akto File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
143 changes: 143 additions & 0 deletions
143
apps/dashboard/src/main/java/com/akto/action/AIAgentConnectorImportAction.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| package com.akto.action; | ||
|
|
||
| import com.akto.dao.context.Context; | ||
| import com.akto.dto.jobs.AIAgentConnectorSyncJobParams; | ||
| import com.akto.dto.jobs.Job; | ||
| import com.akto.dto.jobs.JobExecutorType; | ||
| import com.akto.jobs.JobScheduler; | ||
| import com.akto.log.LoggerMaker; | ||
| import com.akto.log.LoggerMaker.LogDb; | ||
| import com.opensymphony.xwork2.Action; | ||
| import lombok.Getter; | ||
| import lombok.Setter; | ||
|
|
||
| import java.util.HashMap; | ||
| import java.util.Map; | ||
|
|
||
| import static com.akto.jobs.executors.AIAgentConnectorConstants.*; | ||
| import static com.akto.jobs.executors.AIAgentConnectorUtils.*; | ||
|
|
||
| /** | ||
| * Unified action for importing AI Agent Connector data (N8N, Langchain, Copilot Studio). | ||
| * This action schedules recurring jobs to sync data from various AI agent platforms. | ||
| */ | ||
| @Getter | ||
| @Setter | ||
| public class AIAgentConnectorImportAction extends UserAction { | ||
|
|
||
| private static final LoggerMaker loggerMaker = new LoggerMaker(AIAgentConnectorImportAction.class, LogDb.DASHBOARD); | ||
|
|
||
| // Action parameters | ||
| private String connectorType; | ||
| private String dataIngestionUrl; | ||
| private String jobId; | ||
| private Integer recurringIntervalSeconds; | ||
|
|
||
| // N8N-specific parameters | ||
| private String n8nUrl; | ||
| private String n8nApiKey; | ||
|
|
||
| // Langchain-specific parameters | ||
| private String langsmithUrl; | ||
| private String langsmithApiKey; | ||
|
|
||
| // Copilot Studio-specific parameters | ||
| private String appInsightsAppId; | ||
| private String appInsightsApiKey; | ||
|
|
||
| /** | ||
| * Unified method to initiate import for any AI Agent Connector. | ||
| * The connector type is determined by the connectorType parameter. | ||
| */ | ||
| public String initiateImport() { | ||
| try { | ||
| loggerMaker.info("Initiating import for connector type: " + connectorType, LogDb.DASHBOARD); | ||
|
|
||
| // Validate connector type | ||
| if (!isValidConnectorType(connectorType)) { | ||
| loggerMaker.error("Invalid connector type: " + connectorType, LogDb.DASHBOARD); | ||
| return Action.ERROR.toUpperCase(); | ||
| } | ||
|
|
||
| // Build configuration based on connector type | ||
| Map<String, String> config = buildConfig(); | ||
| if (config == null) { | ||
| return Action.ERROR.toUpperCase(); | ||
| } | ||
|
|
||
| // Determine recurring interval (use provided value or default) | ||
| int interval = (recurringIntervalSeconds != null && recurringIntervalSeconds > 0) | ||
| ? recurringIntervalSeconds | ||
| : DEFAULT_RECURRING_INTERVAL_SECONDS; | ||
|
|
||
| // Schedule recurring job using JobScheduler | ||
| Job job = JobScheduler.scheduleRecurringJob( | ||
| Context.accountId.get(), | ||
| new AIAgentConnectorSyncJobParams( | ||
| connectorType, | ||
| config, | ||
| Context.now() | ||
| ), | ||
| JobExecutorType.DASHBOARD, | ||
| interval | ||
| ); | ||
|
|
||
| if (job == null) { | ||
| loggerMaker.error("Failed to schedule recurring job for " + connectorType + " connector", LogDb.DASHBOARD); | ||
| return Action.ERROR.toUpperCase(); | ||
| } | ||
|
|
||
| this.jobId = job.getId().toHexString(); | ||
| loggerMaker.info("Successfully scheduled recurring job for " + connectorType + " connector with job ID: " + this.jobId + ", interval: " + interval + "s", LogDb.DASHBOARD); | ||
|
|
||
| return Action.SUCCESS.toUpperCase(); | ||
|
|
||
| } catch (Exception e) { | ||
| loggerMaker.error("Error initiating " + connectorType + " import: " + e.getMessage(), LogDb.DASHBOARD); | ||
| return Action.ERROR.toUpperCase(); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Builds configuration map based on connector type. | ||
| */ | ||
| private Map<String, String> buildConfig() { | ||
| Map<String, String> config = new HashMap<>(); | ||
| config.put(CONFIG_DATA_INGESTION_SERVICE_URL, dataIngestionUrl); | ||
|
|
||
| switch (connectorType) { | ||
| case CONNECTOR_TYPE_N8N: | ||
| if (n8nUrl == null || n8nUrl.isEmpty() || n8nApiKey == null || n8nApiKey.isEmpty()) { | ||
| loggerMaker.error("Missing required N8N configuration", LogDb.DASHBOARD); | ||
| return null; | ||
| } | ||
| config.put(CONFIG_N8N_BASE_URL, n8nUrl); | ||
| config.put(CONFIG_N8N_API_KEY, n8nApiKey); | ||
| break; | ||
|
|
||
| case CONNECTOR_TYPE_LANGCHAIN: | ||
| if (langsmithUrl == null || langsmithUrl.isEmpty() || langsmithApiKey == null || langsmithApiKey.isEmpty()) { | ||
| loggerMaker.error("Missing required Langchain configuration", LogDb.DASHBOARD); | ||
| return null; | ||
| } | ||
| config.put(CONFIG_LANGSMITH_BASE_URL, langsmithUrl); | ||
| config.put(CONFIG_LANGSMITH_API_KEY, langsmithApiKey); | ||
| break; | ||
|
|
||
| case CONNECTOR_TYPE_COPILOT_STUDIO: | ||
| if (appInsightsAppId == null || appInsightsAppId.isEmpty() || appInsightsApiKey == null || appInsightsApiKey.isEmpty()) { | ||
| loggerMaker.error("Missing required Copilot Studio configuration", LogDb.DASHBOARD); | ||
| return null; | ||
| } | ||
| config.put(CONFIG_APPINSIGHTS_APP_ID, appInsightsAppId); | ||
| config.put(CONFIG_APPINSIGHTS_API_KEY, appInsightsApiKey); | ||
| break; | ||
|
|
||
| default: | ||
| loggerMaker.error("Unsupported connector type: " + connectorType, LogDb.DASHBOARD); | ||
| return null; | ||
| } | ||
|
|
||
| return config; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
...olaris_web/web/src/apps/dashboard/pages/quick_start/components/AIAgentConnectorImport.jsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| import { Box, Button, ButtonGroup, Divider, Text, TextField, VerticalStack } from '@shopify/polaris'; | ||
| import React, { useState } from 'react'; | ||
| import api from '../api'; | ||
| import func from "@/util/func"; | ||
| import PasswordTextField from '../../../components/layouts/PasswordTextField'; | ||
|
|
||
| /** | ||
| * Common component for AI Agent Connector imports (N8N, Langchain, Copilot Studio) | ||
| */ | ||
| const AIAgentConnectorImport = ({ | ||
| connectorType, | ||
| connectorName, | ||
| description, | ||
| fields, | ||
| docsUrl, | ||
| recurringIntervalSeconds = 300, | ||
| onSuccess | ||
| }) => { | ||
| const [loading, setLoading] = useState(false); | ||
| const [formData, setFormData] = useState( | ||
| fields.reduce((acc, field) => ({ ...acc, [field.name]: '' }), {}) | ||
| ); | ||
|
|
||
| const goToDocs = () => { | ||
| window.open(docsUrl); | ||
| }; | ||
|
|
||
| const validateForm = () => { | ||
| for (const field of fields) { | ||
| const value = formData[field.name]; | ||
| if (!value || value.length === 0) { | ||
| func.setToast(true, true, `Please enter a valid ${field.label}.`); | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| }; | ||
|
|
||
| const buildConnectorConfig = () => { | ||
| const config = {}; | ||
| fields.forEach(field => { | ||
| if (field.configKey) { | ||
| config[field.configKey] = formData[field.name]; | ||
| } | ||
| }); | ||
| return config; | ||
| }; | ||
|
|
||
| const primaryAction = () => { | ||
| if (!validateForm()) { | ||
| return; | ||
| } | ||
|
|
||
| setLoading(true); | ||
| const connectorConfig = buildConnectorConfig(); | ||
| const dataIngestionUrl = formData.dataIngestionUrl; | ||
|
|
||
| api.initiateAIAgentConnectorImport( | ||
| connectorType, | ||
| connectorConfig, | ||
| dataIngestionUrl, | ||
| recurringIntervalSeconds | ||
| ).then((res) => { | ||
| func.setToast(true, false, `${connectorName} Import initiated successfully. Please check your dashboard for updates.`); | ||
| if (onSuccess) { | ||
| onSuccess(res); | ||
| } | ||
| }).catch((err) => { | ||
| console.error(`Error initiating ${connectorName} import:`, err); | ||
| func.setToast(true, true, `Ensure that you have added the correct ${connectorName} credentials.`); | ||
| }).finally(() => { | ||
| setLoading(false); | ||
| // Reset form | ||
| setFormData(fields.reduce((acc, field) => ({ ...acc, [field.name]: '' }), {})); | ||
| }); | ||
| }; | ||
|
|
||
| const isFormValid = () => { | ||
| return fields.every(field => formData[field.name]?.length > 0); | ||
| }; | ||
|
|
||
| const updateField = (fieldName, value) => { | ||
| setFormData(prev => ({ ...prev, [fieldName]: value })); | ||
| }; | ||
|
|
||
| return ( | ||
| <div className='card-items'> | ||
| <Text variant='bodyMd'> | ||
| {description} | ||
| </Text> | ||
|
|
||
| <Box paddingBlockStart={3}><Divider /></Box> | ||
|
|
||
| <VerticalStack gap="2"> | ||
| {fields.map((field) => { | ||
| if (field.type === 'password') { | ||
| return ( | ||
| <PasswordTextField | ||
| key={field.name} | ||
| label={field.label} | ||
| setField={(value) => updateField(field.name, value)} | ||
| onFunc={true} | ||
| field={formData[field.name]} | ||
| placeholder={field.placeholder} | ||
| /> | ||
| ); | ||
| } | ||
|
|
||
| return ( | ||
| <TextField | ||
| key={field.name} | ||
| label={field.label} | ||
| value={formData[field.name]} | ||
| type={field.type || 'text'} | ||
| onChange={(value) => updateField(field.name, value)} | ||
| placeholder={field.placeholder} | ||
| /> | ||
| ); | ||
| })} | ||
|
|
||
| <ButtonGroup> | ||
| <Button | ||
| onClick={primaryAction} | ||
| primary | ||
| disabled={!isFormValid()} | ||
| loading={loading} | ||
| > | ||
| Import | ||
| </Button> | ||
| <Button onClick={goToDocs}>Go to docs</Button> | ||
| </ButtonGroup> | ||
| </VerticalStack> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default AIAgentConnectorImport; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a get API as well ?? Where are we going to show the connected agents and their api keys etc ..?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not currently on the UI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a release blocker but we should show that somewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure