From 471b5004d2064a14b0f95b35db2a7beb24ba05d0 Mon Sep 17 00:00:00 2001 From: aakrem Date: Tue, 14 May 2024 16:08:34 +0200 Subject: [PATCH 01/43] enhance dockerfiles and introduce stages --- agenta-web/dev.Dockerfile | 46 ++++++++++++++++++++------------------ agenta-web/prod.Dockerfile | 25 +++++++++++++++++---- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/agenta-web/dev.Dockerfile b/agenta-web/dev.Dockerfile index c155bc07db..1e5e0c16f5 100644 --- a/agenta-web/dev.Dockerfile +++ b/agenta-web/dev.Dockerfile @@ -1,21 +1,17 @@ -FROM node:18-alpine +FROM node:22-alpine3.18 AS base WORKDIR /app # Install dependencies based on the preferred package manager COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ RUN \ - # echo "Standalone: $NEXT_PUBLIC_STANDALONE"; \ - # if [[ ! $NEXT_PUBLIC_STANDALONE == "true" ]]; then \ - if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ - elif [ -f package-lock.json ]; then npm i; \ - elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i; \ - # Allow install without lockfile, so example works even without Node.js installed locally - else echo "Warning: Lockfile not found. It is recommended to commit lockfiles to version control." && yarn install; \ + if [ -f yarn.lock ]; then yarn install --frozen-lockfile; \ + elif [ -f package-lock.json ]; then npm install; \ + elif [ -f pnpm-lock.yaml ]; then npm install -g pnpm && pnpm install; \ + else yarn install; \ fi -# else echo "NEXT_PUBLIC_STANDALONE is set, skipping install"; \ -# fi +# Copy only the necessary files for development COPY src ./src COPY public ./public COPY next.config.js . @@ -23,25 +19,31 @@ COPY tsconfig.json . COPY postcss.config.js . COPY tailwind.config.ts . COPY .env . -RUN if [ -f .env.local ]; then cp .env.local .; fi -# RUN if [ -f tailwind.config.ts ]; then cp tailwind.config.ts .; fi -# # used in cloud COPY sentry.* . -# Next.js collects completely anonymous telemetry data about general usage. Learn more here: https://nextjs.org/telemetry -# Uncomment the following line to disable telemetry at run time -# ENV NEXT_TELEMETRY_DISABLED 1 -# Note: Don't expose ports here, Compose will handle that for us +# Stage 2: Development Stage +FROM node:22-alpine3.18 AS dev + +WORKDIR /app + +# Copy dependencies and application files from the base stage +COPY --from=base /app /app + +# Install development dependencies +RUN \ + if [ -f yarn.lock ]; then yarn install; \ + elif [ -f package-lock.json ]; then npm install; \ + elif [ -f pnpm-lock.yaml ]; then pnpm install; \ + else yarn install; \ + fi + +# Expose the necessary ports +EXPOSE 3000 # Start Next.js in development mode based on the preferred package manager CMD \ - # echo "Standalone: $NEXT_PUBLIC_STANDALONE"; \ - # if [[ ! $NEXT_PUBLIC_STANDALONE == "true" ]]; then \ if [ -f yarn.lock ]; then yarn dev; \ elif [ -f package-lock.json ]; then npm run dev; \ elif [ -f pnpm-lock.yaml ]; then pnpm dev; \ else yarn dev; \ fi -# else echo "NEXT_PUBLIC_STANDALONE is set, skipping run"; \ -# fi - diff --git a/agenta-web/prod.Dockerfile b/agenta-web/prod.Dockerfile index dbe9b9da3c..a2b8e55c60 100644 --- a/agenta-web/prod.Dockerfile +++ b/agenta-web/prod.Dockerfile @@ -1,11 +1,11 @@ -FROM node:18-alpine +# Stage 1: Build Stage +FROM node:22-alpine3.18 AS builder WORKDIR /app # Install only production dependencies COPY package.json package-lock.json* ./ -RUN npm ci --omit=dev - +RUN npm ci # Copy only necessary files COPY src ./src COPY public ./public @@ -14,10 +14,27 @@ COPY tsconfig.json . COPY postcss.config.js . COPY tailwind.config.ts . COPY .env.production . -# used in cloud COPY sentry.* . + # Build the Next.js app for production RUN npm run build +# Stage 2: Production Stage +FROM node:22-alpine3.18 AS prod + +WORKDIR /app + +# Copy only the necessary files from the build stage +COPY --from=builder /app/package.json /app/package-lock.json* /app +COPY --from=builder /app/.next /app/.next +COPY --from=builder /app/public /app/public +COPY --from=builder /app/next.config.js /app/tsconfig.json /app/postcss.config.js /app/tailwind.config.ts /app/.env.production /app/sentry.* /app/ + +# Install only production dependencies +RUN npm ci --omit=dev + +# Expose the necessary port +EXPOSE 3000 + # Start the production server CMD ["npm", "start"] From 0f14a1cf5c5d276b8296d8c20c4ccbac7a80d886 Mon Sep 17 00:00:00 2001 From: aakrem Date: Sun, 19 May 2024 17:21:33 +0200 Subject: [PATCH 02/43] add resources limits --- docker-compose.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 476dede0cd..0d749287d5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -63,6 +63,11 @@ services: mongo: condition: service_healthy restart: always + deploy: + resources: + limits: + cpus: "2.00" + memory: "4G" agenta-web: build: @@ -83,6 +88,11 @@ services: environment: - NEXT_PUBLIC_POSTHOG_API_KEY=phc_hmVSxIjTW1REBHXgj2aw4HW9X6CXb6FzerBgP9XenC7 restart: always + deploy: + resources: + limits: + cpus: "2.00" + memory: "4G" mongo: image: mongo:5.0 From 0e6cc6c88564bbf27fdf37523fc05f6696427880 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 03:56:29 +0000 Subject: [PATCH 03/43] Bump pytest from 8.2.0 to 8.2.1 in /agenta-cli Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.2.0 to 8.2.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.2.0...8.2.1) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- agenta-cli/poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/agenta-cli/poetry.lock b/agenta-cli/poetry.lock index bd5e2add4f..d5b5e30f23 100644 --- a/agenta-cli/poetry.lock +++ b/agenta-cli/poetry.lock @@ -1088,13 +1088,13 @@ zstd = ["zstandard"] [[package]] name = "pytest" -version = "8.2.0" +version = "8.2.1" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.2.0-py3-none-any.whl", hash = "sha256:1733f0620f6cda4095bbf0d9ff8022486e91892245bb9e7d5542c018f612f233"}, - {file = "pytest-8.2.0.tar.gz", hash = "sha256:d507d4482197eac0ba2bae2e9babf0672eb333017bcedaa5fb1a3d42c1174b3f"}, + {file = "pytest-8.2.1-py3-none-any.whl", hash = "sha256:faccc5d332b8c3719f40283d0d44aa5cf101cec36f88cde9ed8f2bc0538612b1"}, + {file = "pytest-8.2.1.tar.gz", hash = "sha256:5046e5b46d8e4cac199c373041f26be56fdb81eb4e67dc11d4e10811fc3408fd"}, ] [package.dependencies] From 466e701f58beb1b2ef54a5e84d41a231624b706d Mon Sep 17 00:00:00 2001 From: aakrem Date: Mon, 20 May 2024 13:39:33 +0200 Subject: [PATCH 04/43] fix potential infinit loop scenarios --- .../services/llm_apps_service.py | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/agenta-backend/agenta_backend/services/llm_apps_service.py b/agenta-backend/agenta_backend/services/llm_apps_service.py index 4e7ab1a9c5..8ec564bebc 100644 --- a/agenta-backend/agenta_backend/services/llm_apps_service.py +++ b/agenta-backend/agenta_backend/services/llm_apps_service.py @@ -165,28 +165,47 @@ async def run_with_retry( return result except aiohttp.ClientError as e: last_exception = e - print(f"Error in evaluation. Retrying in {retry_delay} seconds:", e) + error_message = f"HTTP error occurred during request: {str(e)}" + logger.error(error_message) + await asyncio.sleep(retry_delay) + retries += 1 + except asyncio.TimeoutError as e: + last_exception = e + error_message = f"Request timed out: {str(e)}" + logger.error(error_message) await asyncio.sleep(retry_delay) retries += 1 + except aiohttp.ClientConnectionError as e: + last_exception = e + error_message = f"Connection error: {str(e)}" + logger.error(error_message) + await asyncio.sleep(retry_delay) + retries += 1 + except json.JSONDecodeError as e: + last_exception = e + error_message = f"Failed to decode JSON from response: {str(e)}" + logger.error(error_message) + common.capture_exception_in_sentry(e) + break # Exit the loop for non-retriable exceptions except Exception as e: last_exception = e - logger.info(f"Error processing datapoint: {input_data}. {str(e)}") - logger.info("".join(traceback.format_exception_only(type(e), e))) + error_message = ( + f"Error processing datapoint: {input_data}. Exception: {str(e)}" + ) + logger.error(error_message) + logger.error("".join(traceback.format_exception_only(type(e), e))) common.capture_exception_in_sentry(e) + break # Exit the loop for non-ClientError exceptions - # If max retries is reached or an exception that isn't in the second block, - # update & return the last exception - logging.info("Max retries reached") + logger.info("Max retries reached or a critical error occurred") exception_message = ( - "Max retries reached" - if retries == max_retry_count - else f"Error processing {input_data} datapoint" + "Max retries reached" if retries == max_retry_count else error_message ) return InvokationResult( result=Result( type="error", value=None, - error=Error(message=exception_message, stacktrace=last_exception), + error=Error(message=exception_message, stacktrace=str(last_exception)), ) ) From 5d3e4fa7c1b2a40c1687182edf6cf95ef55329ab Mon Sep 17 00:00:00 2001 From: aakrem Date: Mon, 20 May 2024 13:39:55 +0200 Subject: [PATCH 05/43] add tests for the llm apps service --- .../tests/unit/test_llm_apps_service.py | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 agenta-backend/agenta_backend/tests/unit/test_llm_apps_service.py diff --git a/agenta-backend/agenta_backend/tests/unit/test_llm_apps_service.py b/agenta-backend/agenta_backend/tests/unit/test_llm_apps_service.py new file mode 100644 index 0000000000..6562ce39b6 --- /dev/null +++ b/agenta-backend/agenta_backend/tests/unit/test_llm_apps_service.py @@ -0,0 +1,178 @@ +import pytest +from unittest.mock import patch, AsyncMock +import asyncio +import aiohttp +import json + +from agenta_backend.services.llm_apps_service import ( + batch_invoke, + InvokationResult, + Result, + Error, +) + + +@pytest.mark.asyncio +async def test_batch_invoke_success(): + with patch( + "agenta_backend.services.llm_apps_service.get_parameters_from_openapi", + new_callable=AsyncMock, + ) as mock_get_parameters_from_openapi, patch( + "agenta_backend.services.llm_apps_service.invoke_app", new_callable=AsyncMock + ) as mock_invoke_app, patch( + "asyncio.sleep", new_callable=AsyncMock + ) as mock_sleep: + mock_get_parameters_from_openapi.return_value = [ + {"name": "param1", "type": "input"}, + {"name": "param2", "type": "input"}, + ] + + # Mock the response of invoke_app to always succeed + def invoke_app_side_effect(uri, datapoint, parameters, openapi_parameters): + return InvokationResult( + result=Result(type="text", value="Success", error=None), + latency=0.1, + cost=0.01, + ) + + mock_invoke_app.side_effect = invoke_app_side_effect + + uri = "http://example.com" + testset_data = [ + {"id": 1, "param1": "value1", "param2": "value2"}, + {"id": 2, "param1": "value1", "param2": "value2"}, + ] + parameters = {} + rate_limit_config = { + "batch_size": 10, + "max_retries": 3, + "retry_delay": 3, + "delay_between_batches": 5, + } + + results = await batch_invoke(uri, testset_data, parameters, rate_limit_config) + + assert len(results) == 2 + assert results[0].result.type == "text" + assert results[0].result.value == "Success" + assert results[1].result.type == "text" + assert results[1].result.value == "Success" + + +@pytest.mark.asyncio +async def test_batch_invoke_retries_and_failure(): + with patch( + "agenta_backend.services.llm_apps_service.get_parameters_from_openapi", + new_callable=AsyncMock, + ) as mock_get_parameters_from_openapi, patch( + "agenta_backend.services.llm_apps_service.invoke_app", new_callable=AsyncMock + ) as mock_invoke_app, patch( + "asyncio.sleep", new_callable=AsyncMock + ) as mock_sleep: + mock_get_parameters_from_openapi.return_value = [ + {"name": "param1", "type": "input"}, + {"name": "param2", "type": "input"}, + ] + + # Mock the response of invoke_app to always fail + def invoke_app_side_effect(uri, datapoint, parameters, openapi_parameters): + raise aiohttp.ClientError("Test Error") + + mock_invoke_app.side_effect = invoke_app_side_effect + + uri = "http://example.com" + testset_data = [ + {"id": 1, "param1": "value1", "param2": "value2"}, + {"id": 2, "param1": "value1", "param2": "value2"}, + ] + parameters = {} + rate_limit_config = { + "batch_size": 10, + "max_retries": 3, + "retry_delay": 3, + "delay_between_batches": 5, + } + + results = await batch_invoke(uri, testset_data, parameters, rate_limit_config) + + assert len(results) == 2 + assert results[0].result.type == "error" + assert results[0].result.error.message == "Max retries reached" + assert results[1].result.type == "error" + assert results[1].result.error.message == "Max retries reached" + + +@pytest.mark.asyncio +async def test_batch_invoke_json_decode_error(): + with patch( + "agenta_backend.services.llm_apps_service.get_parameters_from_openapi", + new_callable=AsyncMock, + ) as mock_get_parameters_from_openapi, patch( + "agenta_backend.services.llm_apps_service.invoke_app", new_callable=AsyncMock + ) as mock_invoke_app, patch( + "asyncio.sleep", new_callable=AsyncMock + ) as mock_sleep: + mock_get_parameters_from_openapi.return_value = [ + {"name": "param1", "type": "input"}, + {"name": "param2", "type": "input"}, + ] + + # Mock the response of invoke_app to raise json.JSONDecodeError + def invoke_app_side_effect(uri, datapoint, parameters, openapi_parameters): + raise json.JSONDecodeError("Expecting value", "", 0) + + mock_invoke_app.side_effect = invoke_app_side_effect + + uri = "http://example.com" + testset_data = [{"id": 1, "param1": "value1", "param2": "value2"}] + parameters = {} + rate_limit_config = { + "batch_size": 1, + "max_retries": 3, + "retry_delay": 1, + "delay_between_batches": 1, + } + + results = await batch_invoke(uri, testset_data, parameters, rate_limit_config) + + assert len(results) == 1 + assert results[0].result.type == "error" + assert "Failed to decode JSON from response" in results[0].result.error.message + + +@pytest.mark.asyncio +async def test_batch_invoke_generic_exception(): + with patch( + "agenta_backend.services.llm_apps_service.get_parameters_from_openapi", + new_callable=AsyncMock, + ) as mock_get_parameters_from_openapi, patch( + "agenta_backend.services.llm_apps_service.invoke_app", new_callable=AsyncMock + ) as mock_invoke_app, patch( + "asyncio.sleep", new_callable=AsyncMock + ) as mock_sleep: + mock_get_parameters_from_openapi.return_value = [ + {"name": "param1", "type": "input"}, + {"name": "param2", "type": "input"}, + ] + + # Mock the response of invoke_app to raise a generic exception + def invoke_app_side_effect(uri, datapoint, parameters, openapi_parameters): + raise Exception("Generic Error") + + mock_invoke_app.side_effect = invoke_app_side_effect + + uri = "http://example.com" + testset_data = [{"id": 1, "param1": "value1", "param2": "value2"}] + parameters = {} + rate_limit_config = { + "batch_size": 1, + "max_retries": 3, + "retry_delay": 1, + "delay_between_batches": 1, + } + + results = await batch_invoke(uri, testset_data, parameters, rate_limit_config) + + assert len(results) == 1 + assert results[0].result.type == "error" + assert "Generic Error" in results[0].result.error.message From 78e9452d96ca9ad20e107d5d8fc4dabeb51de2c8 Mon Sep 17 00:00:00 2001 From: Kaosiso Ezealigo Date: Mon, 20 May 2024 17:27:10 +0100 Subject: [PATCH 06/43] enhancement: added button to cancel operation and show logs --- .../components/Playground/ViewNavigation.tsx | 65 ++++++++++++++++--- agenta-web/src/lib/services/api.ts | 12 +++- 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/agenta-web/src/components/Playground/ViewNavigation.tsx b/agenta-web/src/components/Playground/ViewNavigation.tsx index 902dbdbecc..da5a9840c6 100644 --- a/agenta-web/src/components/Playground/ViewNavigation.tsx +++ b/agenta-web/src/components/Playground/ViewNavigation.tsx @@ -81,6 +81,8 @@ const ViewNavigation: React.FC = ({ const retriedOnce = useRef(false) const netWorkError = (error as any)?.code === "ERR_NETWORK" const [isDrawerOpen, setIsDrawerOpen] = useState(false) + const stopperRef = useRef(null) + const [isDelayed, setIsDelayed] = useState(false) let prevKey = "" const showNotification = (config: Parameters[0]) => { @@ -93,9 +95,23 @@ const ViewNavigation: React.FC = ({ if (netWorkError) { retriedOnce.current = true setRetrying(true) - waitForAppToStart({appId, variant, timeout: isDemo() ? 40000 : 6000}) - .then(() => { - refetch() + const waitForAppPromise = waitForAppToStart({ + appId, + variant, + timeout: isDemo() ? 40000 : 6000, + }) + waitForAppPromise + .then((result) => { + if (result) { + stopperRef.current = result.stopper + return result.promise + } + return null + }) + .then((promise: any) => { + if (promise) { + return promise.then(() => refetch()) + } }) .catch(() => { showNotification({ @@ -106,6 +122,7 @@ const ViewNavigation: React.FC = ({ }) .finally(() => { setRetrying(false) + setIsDelayed(false) }) } @@ -118,13 +135,45 @@ const ViewNavigation: React.FC = ({ } }, [netWorkError, isError, variant.variantId]) + useEffect(() => { + if (retrying) { + const timeout = setTimeout(() => { + setIsDelayed(true) + }, 6000) + return () => clearTimeout(timeout) + } + }, [retrying]) + + const handleStopPolling = () => { + if (stopperRef.current) { + stopperRef.current() + } + } + if (retrying || (!retriedOnce.current && netWorkError)) { return ( - + <> + {isDelayed ? ( + <> +
+ + +
+ + ) : ( + + )} + ) } diff --git a/agenta-web/src/lib/services/api.ts b/agenta-web/src/lib/services/api.ts index 9bdcc66189..d9b1ee2fed 100644 --- a/agenta-web/src/lib/services/api.ts +++ b/agenta-web/src/lib/services/api.ts @@ -580,6 +580,8 @@ export const waitForAppToStart = async ({ }) => { const _variant = variant || (await fetchVariants(appId, true))[0] if (_variant) { + let stopperFunc: Function | null = null + const {stopper, promise} = shortPoll( () => getVariantParametersFromOpenAPI( @@ -587,10 +589,16 @@ export const waitForAppToStart = async ({ _variant.variantId, _variant.baseId, true, - ).then(() => stopper()), + ).then(() => { + if (stopperFunc) stopperFunc() + stopper() + }), {delayMs: interval, timeoutMs: timeout}, ) - await promise + + stopperFunc = stopper + + return {stopper: stopperFunc, promise} } } From 94970210b8a51748215d5a5cda1e1136f972dd24 Mon Sep 17 00:00:00 2001 From: aakrem Date: Mon, 20 May 2024 18:46:28 +0200 Subject: [PATCH 07/43] add action to check the app accessibility after serving --- .../check-app-accessibility/action.yml | 30 +++++++++++++++++++ .github/workflows/cli-commands-tests.yml | 16 ++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 .github/actions/check-app-accessibility/action.yml diff --git a/.github/actions/check-app-accessibility/action.yml b/.github/actions/check-app-accessibility/action.yml new file mode 100644 index 0000000000..04de567617 --- /dev/null +++ b/.github/actions/check-app-accessibility/action.yml @@ -0,0 +1,30 @@ +name: 'Check App Accessibility' +description: 'Parse logs and check if the app is running' +inputs: + log-file: + description: 'The path to the log file containing the serve output' + required: true +runs: + using: "composite" + steps: + - name: Parse logs and check if app is running + id: check-app + shell: bash + run: | + echo "Serve output:" + cat ${{ inputs.log-file }} + APP_URL=$(grep -oP 'You can access it here: \K.+' ${{ inputs.log-file }} | head -n 1) + echo "Extracted app URL: $APP_URL" + if [ -z "$APP_URL" ]; then + echo "Error: Failed to extract app URL from logs." + exit 1 + fi + APP_URL="${APP_URL%/}/openapi.json" + echo "Checking if $APP_URL is accessible" + status_code=$(curl --write-out %{http_code} --silent --output /dev/null $APP_URL) + if [ "$status_code" -ne 200 ]; then + echo "Error: $APP_URL is not accessible" + exit 1 + else + echo "$APP_URL is accessible" + fi diff --git a/.github/workflows/cli-commands-tests.yml b/.github/workflows/cli-commands-tests.yml index 3740c2e72a..d84819d891 100644 --- a/.github/workflows/cli-commands-tests.yml +++ b/.github/workflows/cli-commands-tests.yml @@ -43,10 +43,16 @@ jobs: - name: Run agenta variant serve run: | cd examples/baby_name_generator - agenta variant serve --file_name app.py + agenta variant serve --file_name app.py 2>&1 | tee ../../serve_output.log shell: bash continue-on-error: false + - name: Check if app is running + uses: ./.github/actions/check-app-accessibility + with: + log-file: serve_output.log + continue-on-error: false + - name: Run agenta variant serve with overwrite run: | cd examples/baby_name_generator @@ -90,10 +96,16 @@ jobs: - name: Run agenta variant serve run: | cd examples/baby_name_generator - agenta variant serve --file_name app.py + agenta variant serve --file_name app.py 2>&1 | tee ../../serve_output.log shell: bash continue-on-error: false + - name: Check if app is running + uses: ./.github/actions/check-app + with: + log-file: serve_output.log + continue-on-error: false + - name: Run agenta variant serve with overwrite run: | cd examples/baby_name_generator From 49492f34834d0c5977f0a168001aacc28fa4fc9c Mon Sep 17 00:00:00 2001 From: aakrem Date: Mon, 20 May 2024 19:13:17 +0200 Subject: [PATCH 08/43] test --- .github/workflows/cli-commands-tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cli-commands-tests.yml b/.github/workflows/cli-commands-tests.yml index d84819d891..817b608fcf 100644 --- a/.github/workflows/cli-commands-tests.yml +++ b/.github/workflows/cli-commands-tests.yml @@ -2,9 +2,9 @@ name: cli commands tests on: pull_request: - paths: - - "agenta-backend/**" - - "agenta-cli/**" + # paths: + # - "agenta-backend/**" + # - "agenta-cli/**" jobs: serve-to-oss: From e18433312a01fc23a39ee7f42410753655d82d04 Mon Sep 17 00:00:00 2001 From: aakrem Date: Mon, 20 May 2024 19:24:08 +0200 Subject: [PATCH 09/43] fix cloud --- .github/workflows/cli-commands-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cli-commands-tests.yml b/.github/workflows/cli-commands-tests.yml index 817b608fcf..f79685dccd 100644 --- a/.github/workflows/cli-commands-tests.yml +++ b/.github/workflows/cli-commands-tests.yml @@ -101,7 +101,7 @@ jobs: continue-on-error: false - name: Check if app is running - uses: ./.github/actions/check-app + uses: ./.github/actions/check-app-accessibility with: log-file: serve_output.log continue-on-error: false From e9c2efbb92a526ce99f2af7f7d816fafe0c926df Mon Sep 17 00:00:00 2001 From: aakrem Date: Mon, 20 May 2024 19:29:00 +0200 Subject: [PATCH 10/43] add a wait for the app to start --- .github/actions/check-app-accessibility/action.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/actions/check-app-accessibility/action.yml b/.github/actions/check-app-accessibility/action.yml index 04de567617..5eb510d933 100644 --- a/.github/actions/check-app-accessibility/action.yml +++ b/.github/actions/check-app-accessibility/action.yml @@ -11,6 +11,7 @@ runs: id: check-app shell: bash run: | + echo "Serve output:" cat ${{ inputs.log-file }} APP_URL=$(grep -oP 'You can access it here: \K.+' ${{ inputs.log-file }} | head -n 1) @@ -20,6 +21,9 @@ runs: exit 1 fi APP_URL="${APP_URL%/}/openapi.json" + + sleep 5 # Wait for the app to start + echo "Checking if $APP_URL is accessible" status_code=$(curl --write-out %{http_code} --silent --output /dev/null $APP_URL) if [ "$status_code" -ne 200 ]; then From 97f77ab93b1fcae38e6f058590cb21260befef3c Mon Sep 17 00:00:00 2001 From: aakrem Date: Mon, 20 May 2024 19:38:42 +0200 Subject: [PATCH 11/43] add timeout for cloud --- .github/actions/check-app-accessibility/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/check-app-accessibility/action.yml b/.github/actions/check-app-accessibility/action.yml index 5eb510d933..0df6c2459f 100644 --- a/.github/actions/check-app-accessibility/action.yml +++ b/.github/actions/check-app-accessibility/action.yml @@ -25,7 +25,7 @@ runs: sleep 5 # Wait for the app to start echo "Checking if $APP_URL is accessible" - status_code=$(curl --write-out %{http_code} --silent --output /dev/null $APP_URL) + status_code=$(curl --max-time 10 --write-out %{http_code} --silent --output /dev/null $APP_URL) if [ "$status_code" -ne 200 ]; then echo "Error: $APP_URL is not accessible" exit 1 From 2069c6b4c6b5c12a8c6874dc4f6c328f6739fc88 Mon Sep 17 00:00:00 2001 From: aakrem Date: Mon, 20 May 2024 19:42:54 +0200 Subject: [PATCH 12/43] increase timeout to 40 --- .github/actions/check-app-accessibility/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/check-app-accessibility/action.yml b/.github/actions/check-app-accessibility/action.yml index 0df6c2459f..2c2884bb5e 100644 --- a/.github/actions/check-app-accessibility/action.yml +++ b/.github/actions/check-app-accessibility/action.yml @@ -25,7 +25,7 @@ runs: sleep 5 # Wait for the app to start echo "Checking if $APP_URL is accessible" - status_code=$(curl --max-time 10 --write-out %{http_code} --silent --output /dev/null $APP_URL) + status_code=$(curl --max-time 40 --write-out %{http_code} --silent --output /dev/null $APP_URL) if [ "$status_code" -ne 200 ]; then echo "Error: $APP_URL is not accessible" exit 1 From d0fc13a0e407ee1fbef6c145a0adc50e49a3a5d0 Mon Sep 17 00:00:00 2001 From: Kaosiso Ezealigo Date: Mon, 20 May 2024 22:51:13 +0100 Subject: [PATCH 13/43] improved logic --- agenta-web/src/components/Playground/ViewNavigation.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/agenta-web/src/components/Playground/ViewNavigation.tsx b/agenta-web/src/components/Playground/ViewNavigation.tsx index da5a9840c6..59dfaff055 100644 --- a/agenta-web/src/components/Playground/ViewNavigation.tsx +++ b/agenta-web/src/components/Playground/ViewNavigation.tsx @@ -83,6 +83,7 @@ const ViewNavigation: React.FC = ({ const [isDrawerOpen, setIsDrawerOpen] = useState(false) const stopperRef = useRef(null) const [isDelayed, setIsDelayed] = useState(false) + const [loading, setLoading] = useState(false) let prevKey = "" const showNotification = (config: Parameters[0]) => { @@ -136,15 +137,16 @@ const ViewNavigation: React.FC = ({ }, [netWorkError, isError, variant.variantId]) useEffect(() => { - if (retrying) { + if (retrying && variantErrorLogs) { const timeout = setTimeout(() => { setIsDelayed(true) }, 6000) return () => clearTimeout(timeout) } - }, [retrying]) + }, [retrying, variantErrorLogs]) const handleStopPolling = () => { + setLoading(true) if (stopperRef.current) { stopperRef.current() } @@ -161,7 +163,7 @@ const ViewNavigation: React.FC = ({ title="This is taking longer than expected" spinner={retrying} /> - From 22471c034651bd965a83a8dd73a954634e812479 Mon Sep 17 00:00:00 2001 From: Kaosiso Ezealigo Date: Mon, 20 May 2024 23:01:41 +0100 Subject: [PATCH 14/43] improved loading UI --- .../components/Playground/ViewNavigation.tsx | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/agenta-web/src/components/Playground/ViewNavigation.tsx b/agenta-web/src/components/Playground/ViewNavigation.tsx index 59dfaff055..730ba8f90f 100644 --- a/agenta-web/src/components/Playground/ViewNavigation.tsx +++ b/agenta-web/src/components/Playground/ViewNavigation.tsx @@ -155,26 +155,19 @@ const ViewNavigation: React.FC = ({ if (retrying || (!retriedOnce.current && netWorkError)) { return ( <> - {isDelayed ? ( - <> -
- - -
- - ) : ( +
- )} + {isDelayed && ( + + )} +
) } From 868a39bff4feff416ce98324fe3c9b3f9c48f733 Mon Sep 17 00:00:00 2001 From: Kaosiso Ezealigo Date: Mon, 20 May 2024 23:10:54 +0100 Subject: [PATCH 15/43] removed redundant code --- agenta-web/src/components/Playground/ViewNavigation.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/agenta-web/src/components/Playground/ViewNavigation.tsx b/agenta-web/src/components/Playground/ViewNavigation.tsx index 730ba8f90f..489ebd2c17 100644 --- a/agenta-web/src/components/Playground/ViewNavigation.tsx +++ b/agenta-web/src/components/Playground/ViewNavigation.tsx @@ -96,12 +96,7 @@ const ViewNavigation: React.FC = ({ if (netWorkError) { retriedOnce.current = true setRetrying(true) - const waitForAppPromise = waitForAppToStart({ - appId, - variant, - timeout: isDemo() ? 40000 : 6000, - }) - waitForAppPromise + waitForAppToStart({appId, variant, timeout: isDemo() ? 40000 : 6000}) .then((result) => { if (result) { stopperRef.current = result.stopper From c3f299d4f62887a9d38c5a5ea394416887b0ce74 Mon Sep 17 00:00:00 2001 From: Kaosiso Ezealigo Date: Tue, 21 May 2024 00:07:57 +0100 Subject: [PATCH 16/43] fixed trailing 0 in testset timestamp --- agenta-web/src/lib/helpers/dateTimeHelper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agenta-web/src/lib/helpers/dateTimeHelper.ts b/agenta-web/src/lib/helpers/dateTimeHelper.ts index 434badbbf7..a28c9e0c60 100644 --- a/agenta-web/src/lib/helpers/dateTimeHelper.ts +++ b/agenta-web/src/lib/helpers/dateTimeHelper.ts @@ -1,7 +1,7 @@ import dayjs from "dayjs" export const formatDate = (date: dayjs.ConfigType): string => { - return dayjs(date).format("DD MMM YYYY | h:m a") + return dayjs(date).format("DD MMM YYYY | h:mm a") } export const formatDate24 = (date: dayjs.ConfigType, includeSeconds = false): string => { From dd52fd32f0d37365459a72c015550cf681dfd751 Mon Sep 17 00:00:00 2001 From: aakrem Date: Tue, 21 May 2024 11:14:17 +0200 Subject: [PATCH 17/43] add retry mechanism --- .../check-app-accessibility/action.yml | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/.github/actions/check-app-accessibility/action.yml b/.github/actions/check-app-accessibility/action.yml index 2c2884bb5e..ed50d56450 100644 --- a/.github/actions/check-app-accessibility/action.yml +++ b/.github/actions/check-app-accessibility/action.yml @@ -22,13 +22,19 @@ runs: fi APP_URL="${APP_URL%/}/openapi.json" - sleep 5 # Wait for the app to start - echo "Checking if $APP_URL is accessible" - status_code=$(curl --max-time 40 --write-out %{http_code} --silent --output /dev/null $APP_URL) - if [ "$status_code" -ne 200 ]; then - echo "Error: $APP_URL is not accessible" - exit 1 - else - echo "$APP_URL is accessible" - fi + retries=5 + for i in $(seq 1 $retries); do + status_code=$(curl --max-time 60 --write-out %{http_code} --silent --output /dev/null --verbose $APP_URL) + echo "Attempt $i: Status code: $status_code" + if [ "$status_code" -eq 200 ]; then + echo "$APP_URL is accessible" + exit 0 + else + echo "Attempt $i failed: $APP_URL is not accessible" + sleep 10 # Wait before retrying + fi + done + + echo "Error: $APP_URL is not accessible after $retries attempts" + exit 1 From 8fc7a3874ade03f27ad349dbd9046593b14ca0d1 Mon Sep 17 00:00:00 2001 From: aakrem Date: Tue, 21 May 2024 11:21:00 +0200 Subject: [PATCH 18/43] increase retries num --- .github/actions/check-app-accessibility/action.yml | 2 +- .github/workflows/cli-commands-tests.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/check-app-accessibility/action.yml b/.github/actions/check-app-accessibility/action.yml index ed50d56450..76d1ce90f8 100644 --- a/.github/actions/check-app-accessibility/action.yml +++ b/.github/actions/check-app-accessibility/action.yml @@ -23,7 +23,7 @@ runs: APP_URL="${APP_URL%/}/openapi.json" echo "Checking if $APP_URL is accessible" - retries=5 + retries=6 for i in $(seq 1 $retries); do status_code=$(curl --max-time 60 --write-out %{http_code} --silent --output /dev/null --verbose $APP_URL) echo "Attempt $i: Status code: $status_code" diff --git a/.github/workflows/cli-commands-tests.yml b/.github/workflows/cli-commands-tests.yml index f79685dccd..5c43ef79ff 100644 --- a/.github/workflows/cli-commands-tests.yml +++ b/.github/workflows/cli-commands-tests.yml @@ -2,9 +2,9 @@ name: cli commands tests on: pull_request: - # paths: - # - "agenta-backend/**" - # - "agenta-cli/**" + paths: + - "agenta-backend/**" + - "agenta-cli/**" jobs: serve-to-oss: From e0d3c4bd5a3fba3b1e36d2dae4995e0dad3de6a9 Mon Sep 17 00:00:00 2001 From: LucasTrg <47852577+LucasTrg@users.noreply.github.com> Date: Tue, 21 May 2024 13:21:53 +0200 Subject: [PATCH 19/43] Fixes argument order for custom code evaluator --- agenta-backend/agenta_backend/services/security/sandbox.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agenta-backend/agenta_backend/services/security/sandbox.py b/agenta-backend/agenta_backend/services/security/sandbox.py index 58a58f0d35..6a6988daa7 100644 --- a/agenta-backend/agenta_backend/services/security/sandbox.py +++ b/agenta-backend/agenta_backend/services/security/sandbox.py @@ -91,7 +91,7 @@ def execute_code_safely( # Call the evaluation function, extract the result if it exists # and is a float between 0 and 1 - result = environment["evaluate"](app_params, inputs, correct_answer, output) + result = environment["evaluate"](app_params, inputs, output, correct_answer) if isinstance(result, float) and 0 <= result <= 1: return result return None From 59cbf715358a3cb3bfb6da509765de10f86a375c Mon Sep 17 00:00:00 2001 From: Kaosiso Ezealigo Date: Tue, 21 May 2024 15:25:17 +0100 Subject: [PATCH 20/43] moved copy button into the input textarea --- .../src/components/Playground/Views/TestView.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/agenta-web/src/components/Playground/Views/TestView.tsx b/agenta-web/src/components/Playground/Views/TestView.tsx index 58dba68ab2..c45cd812c6 100644 --- a/agenta-web/src/components/Playground/Views/TestView.tsx +++ b/agenta-web/src/components/Playground/Views/TestView.tsx @@ -68,6 +68,7 @@ const useStylesBox = createUseStyles({ }, row3: { margin: "16px 0", + position: "relative", "& textarea": { height: "100%", width: "100%", @@ -211,6 +212,7 @@ const BoxComponent: React.FC = ({ form={form} imageSize="large" isPlaygroundComponent={true} + isLoading={loading} /> {additionalData?.cost || additionalData?.latency ? ( @@ -247,12 +249,6 @@ const BoxComponent: React.FC = ({ > Add to Test Set - {loading ? ( - ) : null} + )} ) } From 5b6fde2fdf5de4bc0ff7dd17a57a96f1fe77250d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 May 2024 03:20:51 +0000 Subject: [PATCH 28/43] --- updated-dependencies: - dependency-name: setuptools dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- agenta-cli/poetry.lock | 14 +++++++------- agenta-cli/pyproject.toml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/agenta-cli/poetry.lock b/agenta-cli/poetry.lock index ef3818ea17..a9f22d6139 100644 --- a/agenta-cli/poetry.lock +++ b/agenta-cli/poetry.lock @@ -1129,6 +1129,7 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -1218,19 +1219,18 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "setuptools" -version = "69.5.1" +version = "70.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.5.1-py3-none-any.whl", hash = "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32"}, - {file = "setuptools-69.5.1.tar.gz", hash = "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987"}, + {file = "setuptools-70.0.0-py3-none-any.whl", hash = "sha256:54faa7f2e8d2d11bcd2c07bed282eef1046b5c080d1c32add737d7b5817b1ad4"}, + {file = "setuptools-70.0.0.tar.gz", hash = "sha256:f211a66637b8fa059bb28183da127d4e86396c991a942b028c6650d4319c3fd0"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "shellingham" @@ -1738,4 +1738,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "ac397fd560d9b1bfa5d8ebbbb82b96c7948c345b24ffb0a54b59251db5b65815" +content-hash = "08fb5e49d58c11148a96f9832200277304ec48e23ef6c0233a34ffc6c13d8a79" diff --git a/agenta-cli/pyproject.toml b/agenta-cli/pyproject.toml index 478ea1aea5..1f0ce43731 100644 --- a/agenta-cli/pyproject.toml +++ b/agenta-cli/pyproject.toml @@ -34,7 +34,7 @@ cachetools = "^5.3.3" [tool.poetry.dev-dependencies] pytest = "^8.2" -setuptools = "^69.5.1" +setuptools = "^70.0.0" [build-system] requires = ["poetry-core"] From af3a81bb13e8b96728ccb2955938a5aa658f0c61 Mon Sep 17 00:00:00 2001 From: Kaosiso Ezealigo Date: Wed, 22 May 2024 05:17:55 +0100 Subject: [PATCH 29/43] updated logic to copy chat inputs --- .../src/components/ChatInputs/ChatInputs.tsx | 40 ++++++++++++++----- .../Playground/ParamsForm/ParamsForm.tsx | 3 ++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/agenta-web/src/components/ChatInputs/ChatInputs.tsx b/agenta-web/src/components/ChatInputs/ChatInputs.tsx index 04946020a2..27abc81d8a 100644 --- a/agenta-web/src/components/ChatInputs/ChatInputs.tsx +++ b/agenta-web/src/components/ChatInputs/ChatInputs.tsx @@ -7,6 +7,7 @@ import {createUseStyles} from "react-jss" import {useUpdateEffect} from "usehooks-ts" import {v4 as uuidv4} from "uuid" import {useAppTheme} from "../Layout/ThemeContextProvider" +import CopyButton from "../CopyButton/CopyButton" const useStyles = createUseStyles({ root: { @@ -50,6 +51,7 @@ interface Props { disableEditRole?: boolean disableEditContent?: boolean readonly?: boolean + isLoading?: boolean } const ChatInputs: React.FC = ({ @@ -62,6 +64,7 @@ const ChatInputs: React.FC = ({ disableEditRole, disableEditContent, readonly, + isLoading, }) => { const {appTheme} = useAppTheme() const classes = useStyles() @@ -126,6 +129,8 @@ const ChatInputs: React.FC = ({ if (Array.isArray(value)) setMessages(cloneDeep(value)) }, [JSON.stringify(value)]) + const lastAssistantMsg = messages.filter((msg) => msg.role === ChatRole.Assistant) + return (
{messages.map((msg, ix) => ( @@ -160,16 +165,33 @@ const ChatInputs: React.FC = ({ onChange={(e) => handleInputChange(ix, e)} readOnly={readonly} /> - {messages.length > 1 && !disableRemove && ( - -
))} diff --git a/agenta-web/src/components/Playground/ParamsForm/ParamsForm.tsx b/agenta-web/src/components/Playground/ParamsForm/ParamsForm.tsx index 51a0df7133..b213497e93 100644 --- a/agenta-web/src/components/Playground/ParamsForm/ParamsForm.tsx +++ b/agenta-web/src/components/Playground/ParamsForm/ParamsForm.tsx @@ -48,6 +48,7 @@ interface Props { form?: FormInstance imageSize?: "small" | "large" isPlaygroundComponent?: boolean + isLoading?: boolean } const ParamsForm: React.FC = ({ @@ -59,6 +60,7 @@ const ParamsForm: React.FC = ({ form, imageSize = "small", isPlaygroundComponent = false, + isLoading, }) => { const classes = useStyles() const imgHeight = imageSize === "small" ? 90 : 120 @@ -70,6 +72,7 @@ const ParamsForm: React.FC = ({ value={useChatDefaultValue ? undefined : chat} defaultValue={useChatDefaultValue ? chat : undefined} onChange={(val) => onParamChange?.("chat", val)} + isLoading={isLoading} /> ) : (
From 6165b90cb7a4406c4f7fceb0db37960e3e7de164 Mon Sep 17 00:00:00 2001 From: aakrem Date: Wed, 22 May 2024 11:52:51 +0200 Subject: [PATCH 30/43] add gemini model --- agenta-backend/agenta_backend/models/api/evaluation_model.py | 1 + agenta-backend/agenta_backend/routers/app_router.py | 1 + agenta-web/src/components/Playground/Views/GroupedSelect.tsx | 2 ++ agenta-web/src/lib/Types.ts | 1 + agenta-web/src/lib/helpers/llmProviders.ts | 1 + 5 files changed, 6 insertions(+) diff --git a/agenta-backend/agenta_backend/models/api/evaluation_model.py b/agenta-backend/agenta_backend/models/api/evaluation_model.py index 2016d49bc2..cce2d7db7e 100644 --- a/agenta-backend/agenta_backend/models/api/evaluation_model.py +++ b/agenta-backend/agenta_backend/models/api/evaluation_model.py @@ -247,6 +247,7 @@ class LMProvidersEnum(str, Enum): alephalpha = "ALEPHALPHA_API_KEY" openrouter = "OPENROUTER_API_KEY" groq = "GROQ_API_KEY" + gemini = "GEMINI_API_KEY" class NewEvaluation(BaseModel): diff --git a/agenta-backend/agenta_backend/routers/app_router.py b/agenta-backend/agenta_backend/routers/app_router.py index 57c27e3f94..9fd85fc0da 100644 --- a/agenta-backend/agenta_backend/routers/app_router.py +++ b/agenta-backend/agenta_backend/routers/app_router.py @@ -578,6 +578,7 @@ async def create_app_and_variant_from_template( "ALEPHALPHA_API_KEY", "OPENROUTER_API_KEY", "GROQ_API_KEY", + "GEMINI_API_KEY", ] missing_keys = [ key for key in supported_llm_prodviders_keys if not os.environ.get(key) diff --git a/agenta-web/src/components/Playground/Views/GroupedSelect.tsx b/agenta-web/src/components/Playground/Views/GroupedSelect.tsx index 67770d8ea5..b5e802acb0 100644 --- a/agenta-web/src/components/Playground/Views/GroupedSelect.tsx +++ b/agenta-web/src/components/Playground/Views/GroupedSelect.tsx @@ -13,6 +13,7 @@ import { OpenRouter, Fireworks, Groq, + Gemini, } from "@lobehub/icons" const useStyles = createUseStyles({ @@ -45,6 +46,7 @@ const iconMap: {[key: string]: React.ComponentType} = { "Together AI": Together.Color, OpenRouter: OpenRouter, Groq: Groq, + Gemini: Gemini, } const getTextContent = (element: React.ReactNode): string => { diff --git a/agenta-web/src/lib/Types.ts b/agenta-web/src/lib/Types.ts index a5d9bb95f1..93915a99cb 100644 --- a/agenta-web/src/lib/Types.ts +++ b/agenta-web/src/lib/Types.ts @@ -264,6 +264,7 @@ export interface LlmProvidersKeys { TOGETHERAI_API_KEY: string MISTRAL_API_KEY: string GROQ_API_KEY: string + GEMINI_API_KEY: string } export interface AppTemplate { diff --git a/agenta-web/src/lib/helpers/llmProviders.ts b/agenta-web/src/lib/helpers/llmProviders.ts index 92f3d41773..7afc6a1881 100644 --- a/agenta-web/src/lib/helpers/llmProviders.ts +++ b/agenta-web/src/lib/helpers/llmProviders.ts @@ -21,6 +21,7 @@ export const llmAvailableProviders: LlmProvider[] = [ {title: "Aleph Alpha", key: "", name: "ALEPHALPHA_API_KEY"}, {title: "OpenRouter", key: "", name: "OPENROUTER_API_KEY"}, {title: "Groq", key: "", name: "GROQ_API_KEY"}, + {title: "Gemini", key: "", name: "GEMINI_API_KEY"}, ] export const getApikeys = () => { From 58b4ba56ceb285d19290a51fdd6ede9032e8854d Mon Sep 17 00:00:00 2001 From: aakrem Date: Wed, 22 May 2024 12:25:30 +0200 Subject: [PATCH 31/43] Revert "add gemini model" This reverts commit 6165b90cb7a4406c4f7fceb0db37960e3e7de164. --- agenta-backend/agenta_backend/models/api/evaluation_model.py | 1 - agenta-backend/agenta_backend/routers/app_router.py | 1 - agenta-web/src/components/Playground/Views/GroupedSelect.tsx | 2 -- agenta-web/src/lib/Types.ts | 1 - agenta-web/src/lib/helpers/llmProviders.ts | 1 - 5 files changed, 6 deletions(-) diff --git a/agenta-backend/agenta_backend/models/api/evaluation_model.py b/agenta-backend/agenta_backend/models/api/evaluation_model.py index cce2d7db7e..2016d49bc2 100644 --- a/agenta-backend/agenta_backend/models/api/evaluation_model.py +++ b/agenta-backend/agenta_backend/models/api/evaluation_model.py @@ -247,7 +247,6 @@ class LMProvidersEnum(str, Enum): alephalpha = "ALEPHALPHA_API_KEY" openrouter = "OPENROUTER_API_KEY" groq = "GROQ_API_KEY" - gemini = "GEMINI_API_KEY" class NewEvaluation(BaseModel): diff --git a/agenta-backend/agenta_backend/routers/app_router.py b/agenta-backend/agenta_backend/routers/app_router.py index 9fd85fc0da..57c27e3f94 100644 --- a/agenta-backend/agenta_backend/routers/app_router.py +++ b/agenta-backend/agenta_backend/routers/app_router.py @@ -578,7 +578,6 @@ async def create_app_and_variant_from_template( "ALEPHALPHA_API_KEY", "OPENROUTER_API_KEY", "GROQ_API_KEY", - "GEMINI_API_KEY", ] missing_keys = [ key for key in supported_llm_prodviders_keys if not os.environ.get(key) diff --git a/agenta-web/src/components/Playground/Views/GroupedSelect.tsx b/agenta-web/src/components/Playground/Views/GroupedSelect.tsx index b5e802acb0..67770d8ea5 100644 --- a/agenta-web/src/components/Playground/Views/GroupedSelect.tsx +++ b/agenta-web/src/components/Playground/Views/GroupedSelect.tsx @@ -13,7 +13,6 @@ import { OpenRouter, Fireworks, Groq, - Gemini, } from "@lobehub/icons" const useStyles = createUseStyles({ @@ -46,7 +45,6 @@ const iconMap: {[key: string]: React.ComponentType} = { "Together AI": Together.Color, OpenRouter: OpenRouter, Groq: Groq, - Gemini: Gemini, } const getTextContent = (element: React.ReactNode): string => { diff --git a/agenta-web/src/lib/Types.ts b/agenta-web/src/lib/Types.ts index 93915a99cb..a5d9bb95f1 100644 --- a/agenta-web/src/lib/Types.ts +++ b/agenta-web/src/lib/Types.ts @@ -264,7 +264,6 @@ export interface LlmProvidersKeys { TOGETHERAI_API_KEY: string MISTRAL_API_KEY: string GROQ_API_KEY: string - GEMINI_API_KEY: string } export interface AppTemplate { diff --git a/agenta-web/src/lib/helpers/llmProviders.ts b/agenta-web/src/lib/helpers/llmProviders.ts index 7afc6a1881..92f3d41773 100644 --- a/agenta-web/src/lib/helpers/llmProviders.ts +++ b/agenta-web/src/lib/helpers/llmProviders.ts @@ -21,7 +21,6 @@ export const llmAvailableProviders: LlmProvider[] = [ {title: "Aleph Alpha", key: "", name: "ALEPHALPHA_API_KEY"}, {title: "OpenRouter", key: "", name: "OPENROUTER_API_KEY"}, {title: "Groq", key: "", name: "GROQ_API_KEY"}, - {title: "Gemini", key: "", name: "GEMINI_API_KEY"}, ] export const getApikeys = () => { From 79eeacd3c53774bac9aaca0e5da2a2caf715001c Mon Sep 17 00:00:00 2001 From: Kaosiso Ezealigo Date: Wed, 22 May 2024 11:25:40 +0100 Subject: [PATCH 32/43] moved copy button into chat input and improved styles --- .../src/components/ChatInputs/ChatInputs.tsx | 63 ++++++++++--------- .../src/components/CopyButton/CopyButton.tsx | 1 + .../components/Playground/Views/TestView.tsx | 2 +- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/agenta-web/src/components/ChatInputs/ChatInputs.tsx b/agenta-web/src/components/ChatInputs/ChatInputs.tsx index 27abc81d8a..ce5b8202a0 100644 --- a/agenta-web/src/components/ChatInputs/ChatInputs.tsx +++ b/agenta-web/src/components/ChatInputs/ChatInputs.tsx @@ -145,27 +145,27 @@ const ChatInputs: React.FC = ({ value={msg.role} onChange={(newRole) => handleRoleChange(ix, newRole)} /> - handleInputChange(ix, e)} - readOnly={readonly} - /> -
+
+ handleInputChange(ix, e)} + readOnly={readonly} + /> {lastAssistantMsg[lastAssistantMsg.length - 1]?.id === msg.id && ( = ({ !lastAssistantMsg[lastAssistantMsg.length - 1]?.content } icon={true} + className="absolute right-2 border-0 h-[30px] opacity-50 bottom-0" /> )} - {messages.length > 1 && !disableRemove && ( - -
+ {messages.length > 1 && !disableRemove && ( + +
))} diff --git a/agenta-web/src/components/CopyButton/CopyButton.tsx b/agenta-web/src/components/CopyButton/CopyButton.tsx index e3fcf6e509..82f105a13c 100644 --- a/agenta-web/src/components/CopyButton/CopyButton.tsx +++ b/agenta-web/src/components/CopyButton/CopyButton.tsx @@ -20,6 +20,7 @@ const CopyButton: React.FC> = ({ return ( - )} - - + ) } @@ -229,11 +176,7 @@ const ViewNavigation: React.FC = ({ const apiAddress = `${containerURI}/openapi.json` return (
- {!error ? null : isLogsLoading || !variantErrorLogs ? ( -
- -
- ) : ( + {error ? (

Error connecting to the variant {variant.variantName}.{" "} @@ -294,7 +237,7 @@ const ViewNavigation: React.FC = ({

- )} + ) : null}
) } diff --git a/agenta-web/src/lib/services/api.ts b/agenta-web/src/lib/services/api.ts index d9b1ee2fed..9bdcc66189 100644 --- a/agenta-web/src/lib/services/api.ts +++ b/agenta-web/src/lib/services/api.ts @@ -580,8 +580,6 @@ export const waitForAppToStart = async ({ }) => { const _variant = variant || (await fetchVariants(appId, true))[0] if (_variant) { - let stopperFunc: Function | null = null - const {stopper, promise} = shortPoll( () => getVariantParametersFromOpenAPI( @@ -589,16 +587,10 @@ export const waitForAppToStart = async ({ _variant.variantId, _variant.baseId, true, - ).then(() => { - if (stopperFunc) stopperFunc() - stopper() - }), + ).then(() => stopper()), {delayMs: interval, timeoutMs: timeout}, ) - - stopperFunc = stopper - - return {stopper: stopperFunc, promise} + await promise } } From 5da50bedccdc163ddfb0eeb8829f069b5899ae0d Mon Sep 17 00:00:00 2001 From: aakrem <6608260+aakrem@users.noreply.github.com> Date: Fri, 24 May 2024 22:35:05 +0000 Subject: [PATCH 43/43] Bump versions --- agenta-backend/pyproject.toml | 2 +- agenta-cli/pyproject.toml | 2 +- agenta-web/package-lock.json | 4 ++-- agenta-web/package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/agenta-backend/pyproject.toml b/agenta-backend/pyproject.toml index 0e2360ed6f..bb0be6a2ee 100644 --- a/agenta-backend/pyproject.toml +++ b/agenta-backend/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "agenta_backend" -version = "0.14.13" +version = "0.14.14" description = "" authors = ["Mahmoud Mabrouk "] readme = "README.md" diff --git a/agenta-cli/pyproject.toml b/agenta-cli/pyproject.toml index 182fd64d57..b284d037f4 100644 --- a/agenta-cli/pyproject.toml +++ b/agenta-cli/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "agenta" -version = "0.14.13" +version = "0.14.14" description = "The SDK for agenta is an open-source LLMOps platform." readme = "README.md" authors = ["Mahmoud Mabrouk "] diff --git a/agenta-web/package-lock.json b/agenta-web/package-lock.json index edac0499d1..903fc58db5 100644 --- a/agenta-web/package-lock.json +++ b/agenta-web/package-lock.json @@ -1,12 +1,12 @@ { "name": "agenta", - "version": "0.14.13", + "version": "0.14.14", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "agenta", - "version": "0.14.13", + "version": "0.14.14", "dependencies": { "@ant-design/colors": "^7.0.0", "@ant-design/icons": "^5.0.1", diff --git a/agenta-web/package.json b/agenta-web/package.json index 3dbf0c0e21..faa801c1a9 100644 --- a/agenta-web/package.json +++ b/agenta-web/package.json @@ -1,6 +1,6 @@ { "name": "agenta", - "version": "0.14.13", + "version": "0.14.14", "private": true, "engines": { "node": ">=18"