= {};
if (name === 'sorting') {
// Handle sorting format - no conversion needed, use snake_case directly
@@ -84,32 +93,14 @@ const LLMConnections: FC = () => {
sortBy: sortBy,
sortOrder: sortOrder as 'asc' | 'desc'
};
-
- productionFilterUpdate = {
- sortBy: sortBy,
- sortOrder: sortOrder as 'asc' | 'desc'
- };
} else {
filterUpdate = { [name]: value };
-
- // Update production filters for relevant fields
- if (name === 'llmPlatform' || name === 'llmModel') {
- productionFilterUpdate = { [name]: value as string };
- }
}
- setFilters((prevFilters) => ({
- ...prevFilters,
+ setFilters({
+ ...filters,
...filterUpdate,
- }));
-
- // Update production filters if relevant
- if (Object.keys(productionFilterUpdate).length > 0) {
- setProductionFilters((prevFilters) => ({
- ...prevFilters,
- ...productionFilterUpdate,
- }));
- }
+ });
// Reset to first page when filters change
if (name !== 'pageNumber') {
@@ -219,24 +210,7 @@ const LLMConnections: FC = () => {
@@ -278,6 +256,10 @@ const LLMConnections: FC = () => {
budgetStatus={llmConnection.budgetStatus}
platform={llmConnection.llmPlatform}
model={llmConnection.llmModel}
+ usedBudget={llmConnection.usedBudget}
+ monthlyBudget={llmConnection.monthlyBudget}
+ stopBudgetThreshold={llmConnection.stopBudgetThreshold}
+ disconnectOnBudgetExceed={llmConnection.disconnectOnBudgetExceed}
/>
);
})}
@@ -286,12 +268,7 @@ const LLMConnections: FC = () => {
) : !productionConnection ? (
) : null}
-
- {(error as any) && (
-
-
Error loading LLM connections. Please try again.
-
- )}
+
{
);
};
-export default LLMConnections;
+export default LLMConnections;
\ No newline at end of file
diff --git a/GUI/src/pages/PromptConfigurations/PromptConfigurations.scss b/GUI/src/pages/PromptConfigurations/PromptConfigurations.scss
new file mode 100644
index 00000000..edbeba13
--- /dev/null
+++ b/GUI/src/pages/PromptConfigurations/PromptConfigurations.scss
@@ -0,0 +1,39 @@
+.prompt-configurations {
+ padding: 2rem;
+
+ .container {
+ max-width: 1200px;
+ margin: 0 auto;
+ }
+
+ .title-container {
+ margin-bottom: 2rem;
+
+ .title {
+ font-size: 2rem;
+ font-weight: 600;
+ margin-bottom: 0.5rem;
+ color: #1a1a1a;
+ }
+
+ .subtitle {
+ font-size: 1rem;
+ color: #666;
+ margin: 0;
+ }
+ }
+
+ .prompt-form {
+ background: #fff;
+ border-radius: 8px;
+ padding: 2rem;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+
+ .form-actions {
+ margin-top: 1.5rem;
+ display: flex;
+ justify-content: flex-end;
+ gap: 1rem;
+ }
+ }
+}
diff --git a/GUI/src/pages/PromptConfigurations/index.tsx b/GUI/src/pages/PromptConfigurations/index.tsx
new file mode 100644
index 00000000..0c7b5113
--- /dev/null
+++ b/GUI/src/pages/PromptConfigurations/index.tsx
@@ -0,0 +1,100 @@
+import { FC, useState, useEffect } from 'react';
+import { useTranslation } from 'react-i18next';
+import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
+import { Button, FormTextarea } from 'components';
+import { ButtonAppearanceTypes, ToastTypes } from 'enums/commonEnums';
+import CircularSpinner from 'components/molecules/CircularSpinner/CircularSpinner';
+import { getPromptConfiguration, savePromptConfiguration } from 'services/promptConfiguration';
+import { promptConfigurationQueryKeys } from 'utils/queryKeys';
+import { useToast } from 'hooks/useToast';
+import './PromptConfigurations.scss';
+
+const PromptConfigurations: FC = () => {
+ const { t } = useTranslation();
+ const toast = useToast();
+ const queryClient = useQueryClient();
+ const [promptText, setPromptText] = useState('');
+ const [isUpdating, setIsUpdating] = useState(false);
+
+ // Fetch prompt configuration
+ const { data: promptConfig, isLoading } = useQuery({
+ queryKey: promptConfigurationQueryKeys.current(),
+ queryFn: getPromptConfiguration,
+ });
+
+
+ // Update promptText when data is loaded
+ useEffect(() => {
+ if (promptConfig && promptConfig.length > 0) {
+ setPromptText(promptConfig[0].prompt || '');
+ setIsUpdating(true);
+ }
+ }, [promptConfig]);
+
+ // Save prompt mutation
+ const saveMutation = useMutation({
+ mutationFn: savePromptConfiguration,
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: promptConfigurationQueryKeys.current() });
+ toast.open({
+ type: ToastTypes.SUCCESS,
+ title: t('toast.success.title'),
+ message: t('promptConfigurations.submitSuccess'),
+ });
+ },
+ onError: (error: any) => {
+ console.error('Error saving prompt:', error);
+ toast.open({
+ type: ToastTypes.ERROR,
+ title: t('toast.error.title'),
+ message: t('promptConfigurations.submitError'),
+ });
+ },
+ });
+
+ const handleSubmit = () => {
+ if (!promptText.trim()) {
+ return;
+ }
+ saveMutation.mutate(promptText);
+ };
+
+ if (isLoading) {
+ return ;
+ }
+
+ return (
+
+
+
+
{t('promptConfigurations.title')}
+
+
+
+
setPromptText(e.target.value)}
+ minRows={10}
+ />
+
+
+
+
+
+
+
+ );
+};
+
+export default PromptConfigurations;
diff --git a/GUI/src/pages/TestModel/index.tsx b/GUI/src/pages/TestModel/index.tsx
index b6e66e76..c00c3ae1 100644
--- a/GUI/src/pages/TestModel/index.tsx
+++ b/GUI/src/pages/TestModel/index.tsx
@@ -75,6 +75,10 @@ const TestLLM: FC = () => {
};
const handleChange = (key: string, value: string | number) => {
+ // Prevent changes while inference is loading
+ if (inferenceMutation.isLoading) {
+ return;
+ }
setTestLLM((prev) => ({
...prev,
[key]: value,
@@ -104,6 +108,7 @@ const TestLLM: FC = () => {
}}
value={testLLM?.connectionId === null ? t('testModels.connectionNotExist') || 'Connection does not exist' : undefined}
defaultValue={testLLM?.connectionId ?? undefined}
+ disabled={inferenceMutation.isLoading}
/>
diff --git a/GUI/src/services/promptConfiguration.ts b/GUI/src/services/promptConfiguration.ts
new file mode 100644
index 00000000..09dc6d45
--- /dev/null
+++ b/GUI/src/services/promptConfiguration.ts
@@ -0,0 +1,23 @@
+import apiDev from './api-dev';
+import { promptConfigurationEndpoints } from 'utils/endpoints';
+
+export interface PromptConfiguration {
+ id: number | null;
+ prompt: string;
+}
+
+export interface PromptConfigurationResponse {
+ response: PromptConfiguration[];
+}
+
+export const getPromptConfiguration = async (): Promise => {
+ const { data } = await apiDev.get(promptConfigurationEndpoints.GET_PROMPT_CONFIGURATION());
+ return data?.response || [];
+};
+
+export const savePromptConfiguration = async (prompt: string): Promise => {
+ const { data } = await apiDev.post(promptConfigurationEndpoints.SAVE_PROMPT_CONFIGURATION(), {
+ prompt,
+ });
+ return data?.response;
+};
diff --git a/GUI/src/store/index.ts b/GUI/src/store/index.ts
index 564d3215..c5fe37db 100644
--- a/GUI/src/store/index.ts
+++ b/GUI/src/store/index.ts
@@ -1,16 +1,49 @@
import { create } from 'zustand';
import { UserInfo } from 'types/userInfo';
+import { LLMConnectionFilters, ProductionConnectionFilters } from 'services/llmConnections';
interface StoreState {
userInfo: UserInfo | null;
userId: string;
setUserInfo: (info: UserInfo) => void;
+ llmConnectionFilters: LLMConnectionFilters;
+ llmConnectionPageIndex: number;
+ productionConnectionFilters: ProductionConnectionFilters;
+ setLLMConnectionFilters: (filters: LLMConnectionFilters) => void;
+ setLLMConnectionPageIndex: (pageIndex: number) => void;
+ setProductionConnectionFilters: (filters: ProductionConnectionFilters) => void;
+ resetLLMConnectionFilters: () => void;
}
+const defaultLLMConnectionFilters: LLMConnectionFilters = {
+ pageNumber: 1,
+ pageSize: 10,
+ sortBy: 'created_at',
+ sortOrder: 'desc',
+};
+
+const defaultProductionConnectionFilters: ProductionConnectionFilters = {
+ sortBy: 'created_at',
+ sortOrder: 'desc',
+ llmPlatform: '',
+ llmModel: '',
+};
+
const useStore = create((set) => ({
userInfo: null,
userId: '',
setUserInfo: (data) => set({ userInfo: data, userId: data?.userIdCode || '' }),
+ llmConnectionFilters: defaultLLMConnectionFilters,
+ llmConnectionPageIndex: 1,
+ productionConnectionFilters: defaultProductionConnectionFilters,
+ setLLMConnectionFilters: (filters) => set({ llmConnectionFilters: filters }),
+ setLLMConnectionPageIndex: (pageIndex) => set({ llmConnectionPageIndex: pageIndex }),
+ setProductionConnectionFilters: (filters) => set({ productionConnectionFilters: filters }),
+ resetLLMConnectionFilters: () => set({
+ llmConnectionFilters: defaultLLMConnectionFilters,
+ llmConnectionPageIndex: 1,
+ productionConnectionFilters: defaultProductionConnectionFilters,
+ }),
}));
-export default useStore;
+export default useStore;
\ No newline at end of file
diff --git a/GUI/src/utils/endpoints.ts b/GUI/src/utils/endpoints.ts
index a6b203d8..386db296 100644
--- a/GUI/src/utils/endpoints.ts
+++ b/GUI/src/utils/endpoints.ts
@@ -34,3 +34,8 @@ export const vaultEndpoints = {
CREATE_VAULT_SECRET: (): string => `/rag-search/vault/secret/create`,
DELETE_VAULT_SECRET: (): string => `/rag-search/vault/secret/delete`,
}
+
+export const promptConfigurationEndpoints = {
+ GET_PROMPT_CONFIGURATION: (): string => `/rag-search/prompt-configuration/get`,
+ SAVE_PROMPT_CONFIGURATION: (): string => `/rag-search/prompt-configuration/save`,
+}
diff --git a/GUI/src/utils/queryKeys.ts b/GUI/src/utils/queryKeys.ts
index e10462e8..ebc3c1a4 100644
--- a/GUI/src/utils/queryKeys.ts
+++ b/GUI/src/utils/queryKeys.ts
@@ -38,3 +38,8 @@ export const inferenceQueryKeys = {
results: () => [...inferenceQueryKeys.all(), 'results'] as const,
result: (request: InferenceRequest) => [...inferenceQueryKeys.results(), request] as const,
};
+
+export const promptConfigurationQueryKeys = {
+ all: () => ['prompt-configuration'] as const,
+ current: () => [...promptConfigurationQueryKeys.all(), 'current'] as const,
+};
diff --git a/GUI/translations/en/common.json b/GUI/translations/en/common.json
index 0341108e..8c2cac8a 100644
--- a/GUI/translations/en/common.json
+++ b/GUI/translations/en/common.json
@@ -62,7 +62,12 @@
"menu": {
"userManagement": "User management",
"testLLM": "Test LLM",
- "llmConnections": "LLM connections"
+ "testProductionLLM": "Test Production LLM",
+ "llmConnections": {
+ "_self": "LLM connections",
+ "overview": "Overview",
+ "promptConfigurations": "Prompt Configurations"
+ }
},
"userManagement": {
"title": "User management",
@@ -122,6 +127,7 @@
"settings": "Settings",
"dataModels": "LLM connections",
"noModels": "No LLM connections found",
+ "errorLoadingConnections": "Error loading LLM connections",
"createModel": "Create LLM connection",
"productionConnections": "Production LLM connection",
"otherConnections": "Other LLM connections",
@@ -158,6 +164,7 @@
"testing": "Testing",
"production": "Production"
},
+ "budgetUsage": "Budget usage",
"budgetStatus": {
"withinBudget": "Within budget",
"overBudget": "Over budget",
@@ -294,6 +301,7 @@
},
"validationMessages": {
"connectionNameRequired": "Connection name is required",
+ "connectionNameMaxLength": "Connection name must not exceed 100 characters",
"llmPlatformRequired": "LLM platform is required",
"llmModelRequired": "LLM model is required",
"embeddingPlatformRequired": "Embedding model platform is required",
@@ -322,7 +330,13 @@
"embeddingApiKeyRequired": "Embedding API key is required",
"invalidUrl": "Please enter a valid URL starting with http:// or https://",
"failedToLoadPlatforms": "Failed to load platforms",
- "failedToLoadModels": "Failed to load models"
+ "failedToLoadModels": "Failed to load models",
+ "invalidAccessKey": "Access Key cannot contain spaces",
+ "invalidSecretKey": "Secret Key cannot contain spaces",
+ "invalidApiKey": "API Key cannot contain spaces",
+ "invalidEmbeddingAccessKey": "Embedding Access Key cannot contain spaces",
+ "invalidEmbeddingSecretKey": "Embedding Secret Key cannot contain spaces",
+ "invalidEmbeddingApiKey": "Embedding API Key cannot contain spaces"
},
"buttons": {
"deleteConnection": "Delete connection",
@@ -342,7 +356,7 @@
"errorDialogMessage": "The connection couldn't be established either due to invalid API credentials or misconfiguration in the deployment platform",
"goBackButton": "Go back",
"replaceProductionDialogTitle": "Replace production connection",
- "replaceProductionDialogMessage": "A production connection \"{connectionName}\" already exists.",
+ "replaceProductionDialogMessage": "A production connection \"{{connectionName}}\" already exists.",
"replaceProductionDialogWarning": "Creating this new production connection will replace the current one. Are you sure you want to proceed?",
"cancelButton": "Cancel",
"confirmReplaceButton": "Yes, replace production connection"
@@ -360,7 +374,7 @@
"goBackButton": "Go back",
"confirmEnvironmentChangeTitle": "Confirm production environment change",
"confirmEnvironmentChangeMessage": "You are about to change a production connection to testing environment.",
- "confirmEnvironmentChangeWarning": "This will affect the current production setup. Are you sure you want to proceed?",
+ "confirmTestingToProductionEnvironmentChangeMessage": "You are about to change a testing connection to production environment.",
"cancelButton": "Cancel",
"confirmChangeButton": "Yes, change environment",
"cannotDeleteProductionTitle": "Cannot delete production connection",
@@ -399,5 +413,17 @@
"aws": "AWS Bedrock",
"azure": "Azure OpenAI"
}
+ },
+ "promptConfigurations": {
+ "title": "Prompt Configurations",
+ "subtitle": "Configure and manage your prompt templates",
+ "promptLabel": "Prompt Template",
+ "promptPlaceholder": "Enter your prompt template here...",
+ "submitButton": "Save",
+ "updateButton": "Update",
+ "saving": "Saving...",
+ "updating": "Updating...",
+ "submitSuccess": "Prompt configuration saved successfully",
+ "submitError": "Failed to save prompt configuration. Please try again."
}
}
\ No newline at end of file
diff --git a/GUI/translations/et/common.json b/GUI/translations/et/common.json
index bd2d5504..1c093b6f 100644
--- a/GUI/translations/et/common.json
+++ b/GUI/translations/et/common.json
@@ -62,7 +62,12 @@
"menu": {
"userManagement": "Kasutajate haldus",
"testLLM": "Testi mudelit",
- "llmConnections": "Mudelite ühendused"
+ "testProductionLLM": "Testi toodangu mudelit",
+ "llmConnections": {
+ "_self": "Mudelite ühendused",
+ "overview": "Ülevaade",
+ "promptConfigurations": "Viiba Seaded"
+ }
},
"userManagement": {
"title": "Kasutajate haldus",
@@ -122,6 +127,7 @@
"settings": "Seaded",
"dataModels": "Mudelite ühendused",
"noModels": "Mudelite ühendusi ei leitud",
+ "errorLoadingConnections": "Viga mudeli ühenduste laadimisel",
"createModel": "Loo mudeli ühendus",
"productionConnections": "Mudel toodangukeskkonnas",
"otherConnections": "Muud mudeli ühendused",
@@ -158,6 +164,7 @@
"testing": "Testimine",
"production": "Toodang"
},
+ "budgetUsage": "Eelarve kasutamine",
"budgetStatus": {
"withinBudget": "Eelarve piires",
"overBudget": "Eelarve ületatud",
@@ -294,6 +301,7 @@
},
"validationMessages": {
"connectionNameRequired": "Ühenduse nimi on kohustuslik",
+ "connectionNameMaxLength": "Ühenduse nimi ei tohi ületada 100 märki",
"llmPlatformRequired": "LLM platvorm on kohustuslik",
"llmModelRequired": "LLM mudel on kohustuslik",
"embeddingPlatformRequired": "Vektor-teisendusmudeli platvorm on kohustuslik",
@@ -322,7 +330,13 @@
"embeddingApiKeyRequired": "Vektor-teisenduse API võti on kohustuslik",
"invalidUrl": "Palun sisesta kehtiv URL, mis algab http:// või https://",
"failedToLoadPlatforms": "Platvormide laadimine ebaõnnestus",
- "failedToLoadModels": "Mudelite laadimine ebaõnnestus"
+ "failedToLoadModels": "Mudelite laadimine ebaõnnestus",
+ "invalidAccessKey": "Juurdepääsuvõti ei tohi sisaldada tühikuid",
+ "invalidSecretKey": "Salavõti ei tohi sisaldada tühikuid",
+ "invalidApiKey": "API võti ei tohi sisaldada tühikuid",
+ "invalidEmbeddingAccessKey": "Vektor-teisenduse juurdepääsuvõti ei tohi sisaldada tühikuid",
+ "invalidEmbeddingSecretKey": "Vektor-teisenduse salavõti ei tohi sisaldada tühikuid",
+ "invalidEmbeddingApiKey": "Vektor-teisenduse API võti ei tohi sisaldada tühikuid"
},
"buttons": {
"deleteConnection": "Kustuta ühendus",
@@ -360,6 +374,7 @@
"goBackButton": "Mine tagasi",
"confirmEnvironmentChangeTitle": "Kinnita toodangukeskkonna muutus",
"confirmEnvironmentChangeMessage": "Oled toodanguühendust muutmas testimiskeskkonnaks.",
+ "confirmTestingToProductionEnvironmentChangeMessage": "Oled testimiskeskkonna ühendust muutmas toodangukeskkonnaks.",
"confirmEnvironmentChangeWarning": "See mõjutab praegust toodanguseadistust. Kas oled kindel, et soovid jätkata?",
"cancelButton": "Tühista",
"confirmChangeButton": "Jah, muuda keskkonda",
@@ -399,5 +414,17 @@
"aws": "AWS Bedrock",
"azure": "Azure OpenAI"
}
+ },
+ "promptConfigurations": {
+ "title": "Viiba Seaded",
+ "subtitle": "Seadista ja halda oma viiba malle",
+ "promptLabel": "Viiba Mall",
+ "promptPlaceholder": "Sisesta siia oma viiba mall...",
+ "submitButton": "Salvesta",
+ "updateButton": "Uuenda",
+ "saving": "Salvestan...",
+ "updating": "Uuendan...",
+ "submitSuccess": "Viiba seadistus salvestati edukalt",
+ "submitError": "Viiba seadistuse salvestamine ebaõnnestus. Palun proovi uuesti."
}
}
\ No newline at end of file
diff --git a/README.md b/README.md
index 9e7dd82b..ad5edce9 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ The **BYK-RAG Module** is part of the Burokratt ecosystem, designed to provide *
- Models searchable via dropdown with cache-enabled indicators.
- **Enhanced Security with RSA Encryption**
- - LLM credentials encrypted with RSA-2048 asymmetric encryption before storage.
+ - LLM credentials encrypted with RSA-2048 asymmetric encryption before storage.
- GUI encrypts using public key; CronManager decrypts with private key.
- Additional security layer beyond HashiCorp Vault's encryption.
diff --git a/docker-compose-ec2.yml b/docker-compose-ec2.yml
index 130a3484..26c19068 100644
--- a/docker-compose-ec2.yml
+++ b/docker-compose-ec2.yml
@@ -128,7 +128,7 @@ services:
- REACT_APP_RUUTER_API_URL=https://est-rag-rtc.rootcode.software/ruuter-public
- REACT_APP_RUUTER_PRIVATE_API_URL=https://est-rag-rtc.rootcode.software/ruuter-private
- REACT_APP_CUSTOMER_SERVICE_LOGIN=https://est-rag-rtc.rootcode.software/authentication-layer/et/dev-auth
- - REACT_APP_CSP=upgrade-insecure-requests; default-src 'self'; font-src 'self' data:; img-src 'self' data:; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; object-src 'none'; connect-src 'self' http://localhost:8086 http://localhost:8088 http://localhost:3004 http://localhost:3005 ws://localhost https://est-rag-rtc.rootcode.software;
+ - REACT_APP_CSP=upgrade-insecure-requests; default-src 'self'; font-src 'self' data:; img-src 'self' data:; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; object-src 'none'; connect-src 'self' http://localhost:8086 http://localhost:8088 http://localhost:3004 http://localhost:3005 ws://localhost https://vault-agent-gui:8202 https://est-rag-rtc.rootcode.software;
- DEBUG_ENABLED=true
- CHOKIDAR_USEPOLLING=true
- PORT=3001
@@ -174,25 +174,25 @@ services:
cron-manager:
container_name: cron-manager
image: cron-manager-python:latest
- user: "root"
+ user: root
volumes:
- ./DSL/CronManager/DSL:/DSL
- ./DSL/CronManager/script:/app/scripts
- ./src/vector_indexer:/app/src/vector_indexer
+ - ./src/utils/decrypt_vault_secrets.py:/app/src/utils/decrypt_vault_secrets.py:ro # Decryption utility (read-only)
- cron_data:/app/data
- shared-volume:/app/shared # Access to shared resources for cross-container coordination
- ./datasets:/app/datasets # Direct access to datasets folder for diff identifier operations
- ./grafana-configs/loki_logger.py:/app/src/vector_indexer/loki_logger.py
- ./.env:/app/.env:ro
- - vault-agent-token:/agent/out:ro # Mount vault token for accessing vault secrets
environment:
- server.port=9010
- PYTHONPATH=/app:/app/src/vector_indexer
- - VAULT_ADDR=http://vault:8200
+ - VAULT_AGENT_URL=http://vault-agent-cron:8203
ports:
- 9010:8080
depends_on:
- - vault-agent-llm
+ - vault-agent-cron
networks:
- bykstack
@@ -496,10 +496,8 @@ services:
- vault-data:/vault/file
- ./vault/config:/vault/config:ro
- ./vault/logs:/vault/logs
- expose:
- - "8200"
networks:
- - bykstack
+ - vault-network # Only on vault-network for security
restart: unless-stopped
healthcheck:
test: ["CMD", "sh", "-c", "wget -q -O- http://127.0.0.1:8200/v1/sys/health || exit 0"]
@@ -520,14 +518,74 @@ services:
volumes:
- vault-data:/vault/data
- vault-agent-creds:/agent/credentials
- - vault-agent-token:/agent/out
+ - vault-agent-gui-token:/agent/gui-token
+ - vault-agent-cron-token:/agent/cron-token
+ - vault-agent-llm-token:/agent/llm-token
- ./vault-init.sh:/vault-init.sh:ro
networks:
- - bykstack
+ - vault-network # Access vault
+ - bykstack # Access to write agent tokens
entrypoint: ["/bin/sh"]
- command: ["-c", "apk add --no-cache curl jq && chmod -R 755 /agent/credentials && chmod -R 770 /agent/out && chown -R vault:vault /agent/credentials /agent/out && su vault -s /bin/sh /vault-init.sh"]
+ command:
+ - -c
+ - |
+ apk add --no-cache curl jq uuidgen openssl
+ # Create and set permissions for all agent directories
+ mkdir -p /agent/credentials /agent/gui-token /agent/cron-token /agent/llm-token /agent/out
+ chown -R vault:vault /agent/credentials /agent/gui-token /agent/cron-token /agent/llm-token /agent/out
+ chmod 755 /agent/credentials /agent/gui-token /agent/cron-token /agent/llm-token /agent/out
+ # Run vault initialization as vault user
+ su vault -s /bin/sh /vault-init.sh
restart: "no"
+ vault-agent-gui:
+ image: hashicorp/vault:1.20.3
+ container_name: vault-agent-gui
+ command: ["vault", "agent", "-config=/agent/config/gui-agent.hcl", "-log-level=info"]
+ depends_on:
+ vault-init:
+ condition: service_completed_successfully
+ cap_add:
+ - IPC_LOCK
+ volumes:
+ - ./vault/agents/gui/gui-agent.hcl:/agent/config/gui-agent.hcl:ro
+ - vault-agent-creds:/agent/credentials:ro
+ - vault-agent-gui-token:/agent/gui-token
+ networks:
+ - vault-network # Access vault
+ - bykstack # Accessible by GUI service
+ restart: unless-stopped
+ healthcheck:
+ test: ["CMD", "sh", "-c", "test -f /agent/gui-token/token && test -s /agent/gui-token/token"]
+ interval: 10s
+ timeout: 3s
+ retries: 3
+ start_period: 5s
+
+ vault-agent-cron:
+ image: hashicorp/vault:1.20.3
+ container_name: vault-agent-cron
+ command: ["vault", "agent", "-config=/agent/config/cron-agent.hcl", "-log-level=info"]
+ depends_on:
+ vault-init:
+ condition: service_completed_successfully
+ cap_add:
+ - IPC_LOCK
+ volumes:
+ - ./vault/agents/cron/cron-agent.hcl:/agent/config/cron-agent.hcl:ro
+ - vault-agent-creds:/agent/credentials:ro
+ - vault-agent-cron-token:/agent/cron-token
+ networks:
+ - vault-network # Access vault
+ - bykstack # Accessible by CronManager service
+ restart: unless-stopped
+ healthcheck:
+ test: ["CMD", "sh", "-c", "test -f /agent/cron-token/token && test -s /agent/cron-token/token"]
+ interval: 10s
+ timeout: 3s
+ retries: 3
+ start_period: 5s
+
vault-agent-llm:
image: hashicorp/vault:1.20.3
container_name: vault-agent-llm
@@ -540,10 +598,17 @@ services:
volumes:
- ./vault/agents/llm/agent.hcl:/agent/config/agent.hcl:ro
- vault-agent-creds:/agent/credentials:ro
- - vault-agent-token:/agent/out
+ - vault-agent-llm-token:/agent/llm-token
networks:
- - bykstack
+ - vault-network # Access vault
+ - bykstack # Accessible by LLM service
restart: unless-stopped
+ healthcheck:
+ test: ["CMD", "sh", "-c", "test -f /agent/llm-token/token && test -s /agent/llm-token/token"]
+ interval: 10s
+ timeout: 3s
+ retries: 3
+ start_period: 5s
# LLM Orchestration Service
llm-orchestration-service:
@@ -558,24 +623,22 @@ services:
- .env
environment:
- ENVIRONMENT=production
- - VAULT_ADDR=http://vault:8200
- - VAULT_TOKEN=/agent/out/token
+ - VAULT_ADDR=http://vault-agent-llm:8201
+ # VAULT_TOKEN not set - vault-agent-llm proxy handles authentication
volumes:
- ./src/llm_config_module/config:/app/src/llm_config_module/config:ro
- ./src/optimization/optimized_modules:/app/src/optimization/optimized_modules
- llm_orchestration_logs:/app/logs
- - vault-agent-token:/agent/out:ro
networks:
- bykstack
depends_on:
- - vault
- vault-agent-llm
- # healthcheck:
- # test: ["CMD", "curl", "-f", "http://llm-orchestration-service:8100/health"]
- # interval: 30s
- # timeout: 10s
- # start_period: 40s
- # retries: 3
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://llm-orchestration-service:8100/health"]
+ interval: 30s
+ timeout: 10s
+ start_period: 40s
+ retries: 3
volumes:
loki-data:
@@ -602,8 +665,12 @@ volumes:
name: cron_data
vault-agent-creds:
name: vault-agent-creds
- vault-agent-token:
- name: vault-agent-token
+ vault-agent-gui-token:
+ name: vault-agent-gui-token
+ vault-agent-cron-token:
+ name: vault-agent-cron-token
+ vault-agent-llm-token:
+ name: vault-agent-llm-token
opensearch-data:
name: opensearch-data
@@ -611,3 +678,7 @@ networks:
bykstack:
name: bykstack
driver: bridge
+ vault-network:
+ name: vault-network
+ driver: bridge
+ internal: true # No external access - isolated network
\ No newline at end of file