-
Notifications
You must be signed in to change notification settings - Fork 233
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into AGE-207/-Move-copy-message-button-in-the-pla…
…yground-to-the-text-input
- Loading branch information
Showing
9 changed files
with
226 additions
and
32 deletions.
There are no files selected for viewing
This file contains 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 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 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 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
162 changes: 162 additions & 0 deletions
162
agenta-backend/agenta_backend/tests/unit/test_llm_apps_service.py
This file contains 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,162 @@ | ||
import pytest | ||
from unittest.mock import patch, AsyncMock | ||
import asyncio | ||
import aiohttp | ||
|
||
from agenta_backend.services.llm_apps_service import ( | ||
batch_invoke, | ||
InvokationResult, | ||
Result, | ||
Error, | ||
) | ||
|
||
|
||
@pytest.mark.asyncio | ||
async def test_batch_invoke_success(): | ||
""" | ||
Test the successful invocation of batch_invoke function. | ||
This test mocks the get_parameters_from_openapi and invoke_app functions | ||
to simulate successful invocations. It verifies that the batch_invoke | ||
function correctly returns the expected results for the given test data. | ||
""" | ||
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(): | ||
""" | ||
Test the batch_invoke function with retries and eventual failure. | ||
This test mocks the get_parameters_from_openapi and invoke_app functions | ||
to simulate failures that trigger retries. It verifies that the batch_invoke | ||
function correctly retries the specified number of times and returns an error | ||
result after reaching the maximum retries. | ||
""" | ||
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_generic_exception(): | ||
""" | ||
Test the batch_invoke function with a generic exception. | ||
This test mocks the get_parameters_from_openapi and invoke_app functions | ||
to simulate a generic exception during invocation. It verifies that the | ||
batch_invoke function correctly handles the exception and returns an error | ||
result with the appropriate error message. | ||
""" | ||
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 results[0].result.error.message == "Max retries reached" |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains 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 |
---|---|---|
@@ -1,47 +1,49 @@ | ||
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 . | ||
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 | ||
|
This file contains 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 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 |
---|---|---|
|
@@ -167,3 +167,4 @@ networks: | |
volumes: | ||
mongodb_data: | ||
redis_data: | ||
nextjs_cache: |