diff --git a/VERSION b/VERSION index 8a30e8f94..ade65226e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.4.0 +5.4.1 diff --git a/lib/api-base/fastApiContainer.ts b/lib/api-base/fastApiContainer.ts index 0ffca9d5a..b9d23c144 100644 --- a/lib/api-base/fastApiContainer.ts +++ b/lib/api-base/fastApiContainer.ts @@ -81,8 +81,8 @@ export class FastApiContainer extends Construct { }; // Add build config overrides if provided - if (config.restApiConfig.buildConfig?.NODEENV_CACHE_DIR) { - buildArgs.NODEENV_CACHE_DIR = config.restApiConfig.buildConfig.NODEENV_CACHE_DIR; + if (config.restApiConfig.buildConfig?.PRISMA_CACHE_DIR) { + buildArgs.PRISMA_CACHE_DIR = config.restApiConfig.buildConfig.PRISMA_CACHE_DIR; } // Add MCP Workbench build config overrides if provided diff --git a/lib/docs/admin/deploy.md b/lib/docs/admin/deploy.md index 888d15fa0..928db8044 100644 --- a/lib/docs/admin/deploy.md +++ b/lib/docs/admin/deploy.md @@ -294,10 +294,10 @@ npmConfig: # Use ADC-accessible base images for LISA-Serve and Batch Ingestion baseImage: /python:3.11 -# Configure offline build dependencies for REST API (nodeenv for prisma-client-py) +# Configure offline build dependencies for REST API (prisma-client-py dependencies) restApiConfig: buildConfig: - NODEENV_CACHE_DIR: "./nodeenv-cache" # Path relative to lib/serve/rest-api/ + PRISMA_CACHE_DIR: "./PRISMA_CACHE" # Path relative to lib/serve/rest-api/ # Configure offline build dependencies for MCP Workbench (S6 Overlay and rclone) mcpWorkbenchBuildConfig: @@ -311,12 +311,33 @@ You'll also want any model hosting base containers available, e.g. vllm/vllm-ope For environments without internet access during Docker builds, you can pre-cache required dependencies: -**REST API nodeenv cache** (required by prisma-client-py): +**REST API Prisma cache** (required by prisma-client-py): + +The `prisma-client-py` package requires platform-specific binaries and a Node.js environment to function. When Prisma runs for the first time, it downloads these dependencies to `~/.cache/prisma/` and `~/.cache/prisma-python/`. For offline deployments, you need to pre-populate this cache. + +Below is an example workflow using an Amazon Linux 2023 instance with Python 3.12: + ```bash -# Create the cache directory in the REST API build context -python -m nodeenv lib/serve/rest-api/nodeenv-cache +# Ensure Pip is up-to-date +pip3 install --upgrade pip + +# Install Prisma Python package +pip3 install prisma + +# Trigger Prisma to download all required binaries and create its Node.js environment +# This populates ~/.cache/prisma/ and ~/.cache/prisma-python/ +prisma version + +# Copy the complete Prisma cache to your build context +# The wildcard captures both 'prisma' and 'prisma-python' directories +cp -r ~/.cache/prisma* lib/serve/rest-api/PRISMA_CACHE/ ``` +**Important Notes:** +- The cache is platform-specific. Generate it on a system matching your Docker base image (e.g., for `python:3.13-slim` which is Debian-based, so you may want to use a Debian-based system) +- The `prisma version` command downloads binaries for your current platform +- Both `prisma/` and `prisma-python/` directories are required for offline operation + **MCP Workbench dependencies** (S6 Overlay and rclone): ```bash # Download S6 Overlay files diff --git a/lib/schema/configSchema.ts b/lib/schema/configSchema.ts index 7734d74f6..d81d66683 100644 --- a/lib/schema/configSchema.ts +++ b/lib/schema/configSchema.ts @@ -711,7 +711,7 @@ const FastApiContainerConfigSchema = z.object({ sslCertIamArn: z.string().nullish().default(null).describe('ARN of the self-signed cert to be used throughout the system'), imageConfig: ImageAssetSchema.optional().describe('Override image configuration for ECS FastAPI Containers'), buildConfig: z.object({ - NODEENV_CACHE_DIR: z.string().optional().describe('Override with a path relative to the build directory for a pre-cached nodeenv directory. Defaults to NODEENV_CACHE. For offline environments, populate using: python -m nodeenv PATH') + PRISMA_CACHE_DIR: z.string().optional().describe('Override with a path relative to the build directory for a pre-cached prisma directory. Defaults to PRISMA_CACHE.') }).default({}), rdsConfig: RdsInstanceConfig .default({ diff --git a/lib/serve/rest-api/Dockerfile b/lib/serve/rest-api/Dockerfile index 9681ce9bd..738647a44 100644 --- a/lib/serve/rest-api/Dockerfile +++ b/lib/serve/rest-api/Dockerfile @@ -1,8 +1,8 @@ ARG BASE_IMAGE=python:3.11 FROM ${BASE_IMAGE} -ARG NODEENV_CACHE_DIR=NODEENV_CACHE -ENV NODEENV_CACHE_DIR=$NODEENV_CACHE_DIR +ARG PRISMA_CACHE_DIR=PRISMA_CACHE +ENV PRISMA_CACHE_DIR=$PRISMA_CACHE_DIR # Install build dependencies for madoka package RUN apt-get update && apt-get install -y \ @@ -28,20 +28,20 @@ WORKDIR /app COPY src/requirements.txt . RUN pip install --no-cache-dir --upgrade -r requirements.txt -# Copy nodeenv cache directory (always exists, may be empty or populated) -COPY ${NODEENV_CACHE_DIR} /tmp/nodeenv-cache/ +# Copy prisma cache directory (always exists, may be empty or populated) +COPY ${PRISMA_CACHE_DIR} /tmp/prisma-cache/ -# Pre-cache nodeenv for prisma-client-py +# Pre-cache prisma for prisma-client-py # If the copied directory has content, use it (for offline environments) # Otherwise, download it during build (requires internet) -RUN mkdir -p /root/.cache/prisma-python && \ - if [ -d "/tmp/nodeenv-cache" ] && [ -n "$(ls /tmp/nodeenv-cache 2>/dev/null)" ]; then \ - echo "Using pre-cached nodeenv from host" && \ - cp -r /tmp/nodeenv-cache /root/.cache/prisma-python/nodeenv && \ - rm -rf /tmp/nodeenv-cache; \ +RUN mkdir -p /root/.cache && \ + if [ -d "/tmp/prisma-cache" ] && [ -n "$(ls /tmp/prisma-cache 2>/dev/null)" ]; then \ + echo "Using pre-cached Prisma dependencies from host" && \ + cp -r /tmp/prisma-cache/prisma* /root/.cache && \ + rm -rf /tmp/prisma-cache; \ else \ - echo "Downloading nodeenv (requires internet)" && \ - python -m nodeenv /root/.cache/prisma-python/nodeenv; \ + echo "Fetching Prisma Dependencies (requires internet)" && \ + prisma version; \ fi # Copy the source code into the container diff --git a/lib/serve/rest-api/NODEENV_CACHE/.gitkeep b/lib/serve/rest-api/NODEENV_CACHE/.gitkeep deleted file mode 100644 index b098f0c35..000000000 --- a/lib/serve/rest-api/NODEENV_CACHE/.gitkeep +++ /dev/null @@ -1,2 +0,0 @@ -# Placeholder to ensure NODEENV_CACHE directory exists in build context -# For offline builds, populate this directory using: python -m nodeenv NODEENV_CACHE diff --git a/lib/serve/rest-api/PRISMA_CACHE/.gitkeep b/lib/serve/rest-api/PRISMA_CACHE/.gitkeep new file mode 100644 index 000000000..ad102e091 --- /dev/null +++ b/lib/serve/rest-api/PRISMA_CACHE/.gitkeep @@ -0,0 +1,5 @@ +# Placeholder to ensure PRISMA_CACHE directory exists in build context +# For offline builds, populate this directory by copying the complete Prisma cache: +# 1. Install prisma: pip3 install prisma +# 2. Generate cache: prisma version +# 3. Copy cache: cp -r ~/.cache/prisma* lib/serve/rest-api/PRISMA_CACHE/ diff --git a/lib/user-interface/react/package.json b/lib/user-interface/react/package.json index 90f8a8715..da6ade9f2 100644 --- a/lib/user-interface/react/package.json +++ b/lib/user-interface/react/package.json @@ -1,7 +1,7 @@ { "name": "lisa-web", "private": true, - "version": "5.4.0", + "version": "5.4.1", "type": "module", "scripts": { "dev": "vite", diff --git a/lib/user-interface/react/src/shared/reducers/configuration.reducer.ts b/lib/user-interface/react/src/shared/reducers/configuration.reducer.ts index 72ad7e724..53b81044c 100644 --- a/lib/user-interface/react/src/shared/reducers/configuration.reducer.ts +++ b/lib/user-interface/react/src/shared/reducers/configuration.reducer.ts @@ -23,7 +23,7 @@ export const configurationApi = createApi({ baseQuery: lisaBaseQuery(), tagTypes: ['configuration'], refetchOnFocus: true, - refetchOnReconnect: true, + refetchOnMountOrArgChange: true, endpoints: (builder) => ({ getConfiguration: builder.query({ query: (configScope) => ({ diff --git a/lib/user-interface/react/src/shared/reducers/mcp-server.reducer.ts b/lib/user-interface/react/src/shared/reducers/mcp-server.reducer.ts index b3aca527f..92eaa7f77 100644 --- a/lib/user-interface/react/src/shared/reducers/mcp-server.reducer.ts +++ b/lib/user-interface/react/src/shared/reducers/mcp-server.reducer.ts @@ -62,7 +62,7 @@ export const mcpServerApi = createApi({ baseQuery: lisaBaseQuery(), tagTypes: ['mcpServers'], refetchOnFocus: true, - refetchOnReconnect: true, + refetchOnMountOrArgChange: true, endpoints: (builder) => ({ createMcpServer: builder.mutation({ query: (mcpServer) => ({ diff --git a/lib/user-interface/react/src/shared/reducers/mcp-tools.reducer.ts b/lib/user-interface/react/src/shared/reducers/mcp-tools.reducer.ts index 5d41461b1..2a64f5282 100644 --- a/lib/user-interface/react/src/shared/reducers/mcp-tools.reducer.ts +++ b/lib/user-interface/react/src/shared/reducers/mcp-tools.reducer.ts @@ -31,7 +31,7 @@ export const mcpToolsApi = createApi({ baseQuery: lisaBaseQuery(), tagTypes: ['mcpTools'], refetchOnFocus: true, - refetchOnReconnect: true, + refetchOnMountOrArgChange: true, endpoints: (builder) => ({ listMcpTools: builder.query({ query: () => ({ diff --git a/lib/user-interface/react/src/shared/reducers/model-management.reducer.ts b/lib/user-interface/react/src/shared/reducers/model-management.reducer.ts index 55de56c4d..80f70b291 100644 --- a/lib/user-interface/react/src/shared/reducers/model-management.reducer.ts +++ b/lib/user-interface/react/src/shared/reducers/model-management.reducer.ts @@ -23,7 +23,7 @@ export const modelManagementApi = createApi({ baseQuery: lisaBaseQuery(), tagTypes: ['models'], refetchOnFocus: true, - refetchOnReconnect: true, + refetchOnMountOrArgChange: true, endpoints: (builder) => ({ getAllModels: builder.query({ query: () => ({ diff --git a/lib/user-interface/react/src/shared/reducers/prompt-templates.reducer.ts b/lib/user-interface/react/src/shared/reducers/prompt-templates.reducer.ts index 26afbcf47..58ebe58cd 100644 --- a/lib/user-interface/react/src/shared/reducers/prompt-templates.reducer.ts +++ b/lib/user-interface/react/src/shared/reducers/prompt-templates.reducer.ts @@ -54,7 +54,7 @@ export const promptTemplateApi = createApi({ baseQuery: lisaBaseQuery(), tagTypes: ['promptTemplates'], refetchOnFocus: true, - refetchOnReconnect: true, + refetchOnMountOrArgChange: true, endpoints: (builder) => ({ createPromptTemplate: builder.mutation({ query: (promptTemplate) => ({ diff --git a/lib/user-interface/react/src/shared/reducers/rag.reducer.ts b/lib/user-interface/react/src/shared/reducers/rag.reducer.ts index 7d88ce66c..5f3f0c318 100644 --- a/lib/user-interface/react/src/shared/reducers/rag.reducer.ts +++ b/lib/user-interface/react/src/shared/reducers/rag.reducer.ts @@ -101,7 +101,7 @@ export const ragApi = createApi({ baseQuery: lisaBaseQuery(), tagTypes: ['repositories', 'docs', 'repository-status', 'jobs'], refetchOnFocus: true, - refetchOnReconnect: true, + refetchOnMountOrArgChange: true, endpoints: (builder) => ({ listRagRepositories: builder.query({ query: () => ({ diff --git a/lib/user-interface/react/src/shared/reducers/session.reducer.ts b/lib/user-interface/react/src/shared/reducers/session.reducer.ts index a0276fbc0..035835e45 100644 --- a/lib/user-interface/react/src/shared/reducers/session.reducer.ts +++ b/lib/user-interface/react/src/shared/reducers/session.reducer.ts @@ -29,7 +29,7 @@ export const sessionApi = createApi({ baseQuery: lisaBaseQuery(), tagTypes: ['sessions'], refetchOnFocus: true, - refetchOnReconnect: true, + refetchOnMountOrArgChange: true, endpoints: (builder) => ({ getSessionById: builder.query({ query: (sessionId: string) => ({ diff --git a/lib/user-interface/react/src/shared/reducers/user-preferences.reducer.ts b/lib/user-interface/react/src/shared/reducers/user-preferences.reducer.ts index 8440dcc66..f43b8f0e2 100644 --- a/lib/user-interface/react/src/shared/reducers/user-preferences.reducer.ts +++ b/lib/user-interface/react/src/shared/reducers/user-preferences.reducer.ts @@ -50,7 +50,7 @@ export const userPreferencesApi = createApi({ baseQuery: lisaBaseQuery(), tagTypes: ['user-preferences'], refetchOnFocus: true, - refetchOnReconnect: true, + refetchOnMountOrArgChange: true, endpoints: (builder) => ({ updateUserPreferences: builder.mutation({ query: (userPreferences) => ({ diff --git a/lisa-sdk/pyproject.toml b/lisa-sdk/pyproject.toml index f669c4602..9d408dfc3 100644 --- a/lisa-sdk/pyproject.toml +++ b/lisa-sdk/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "lisapy" -version = "5.4.0" +version = "5.4.1" description = "A simple SDK to help you interact with LISA. LISA is an LLM hosting solution for AWS dedicated clouds or ADCs." readme = "README.md" requires-python = ">=3.11" @@ -15,7 +15,7 @@ dependencies = [ [tool.poetry] name = "lisapy" -version = "5.4.0" +version = "5.4.1" description = "A simple SDK to help you interact with LISA. LISA is an LLM hosting solution for AWS dedicated clouds or ADCs." authors = ["Steve Goley "] readme = "README.md" diff --git a/package.json b/package.json index f5a2cbe71..508a300ba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@awslabs/lisa", - "version": "5.4.0", + "version": "5.4.1", "description": "A scalable infrastructure-as-code solution for self-hosting and orchestrating LLM inference with RAG capabilities, providing low-latency access to generative AI and embedding models across multiple providers.", "homepage": "https://awslabs.github.io/LISA/", "license": "Apache-2.0",