Skip to content

Commit

Permalink
Merge pull request #4 from tomkat-cr/GS-66_fix_lcel_issues
Browse files Browse the repository at this point in the history
GS-66 - Fix LCEL issues
  • Loading branch information
tomkat-cr authored Jul 19, 2024
2 parents 4eee91f + 811ecbe commit f8c50c3
Show file tree
Hide file tree
Showing 12 changed files with 975 additions and 768 deletions.
88 changes: 79 additions & 9 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ DEFAULT_LANG=en
# Application debug (0,1)
APP_DEBUG=1
# Application environment: dev, qa, staging, prod
APP_STAGE=dev
# APP_STAGE=dev
# Application super admin email
APP_SUPERADMIN_EMAIL=xxxx
# Application secret ket (to set password encryption)
Expand Down Expand Up @@ -96,16 +96,55 @@ FRONTEND_PATH=../exampleapp_frontend
# Local python version
PYTHON_VERSION=3.11.5
#
# IAAS Cloud provider
# Available options: `aws`, `gcp`, `azure`
CLOUD_PROVIDER=aws
#
# Enable/disable Cloud Provider secrets (instead of environment variables).
# Available options: `1` to enable, `0` to disable. Defaults to: 1
# GET_SECRETS_ENABLED=0
#
# Fine grained Cloud Provider secrets management:
#
# Enable/disable Cloud Provider envvars.
# Available options: `1` to enable, `0` to disable. Defaults to: 1
# Set to "0" in local development environment so envvars like APP_CORS_ORIGIN can be
# set by the scripts and .env file and access QA resources from DEV.
# GET_SECRETS_ENVVARS=0
#
# Enable/disable Cloud Provider critical secrets.
# Available options: `1` to enable, `0` to disable. Defaults to: 1
# Set to "0" in local development environment so envvars like APP_DB_URI can be
# set by the scripts and .env file and access QA resources from DEV.
# GET_SECRETS_CRITICAL=0
#
# AWS Configuration
# https://console.aws.amazon.com
AWS_S3_BUCKET_NAME_FE=aws-s3-bucket-name
#
# Region for this App all AWS services
AWS_REGION=aws-region
AWS_API_GATEWAY_STAGE=aws-api-gateway-stage
#
# AWS Deployment type
# Available options: `lambda`, `fargate`, `ec2`. Defaults to: lambda
AWS_DEPLOYMENT_TYPE=lambda
#
# AWS base name for Lambda Functions, API Gateway, EC2, ELB, etc.
AWS_LAMBDA_FUNCTION_NAME=aws-lambda-function-name
AWS_LAMBDA_FUNCTION_ROLE=aws-lambda-function-role
AWS_SSL_CERTIFICATE_ARN=arn:aws:acm:AWS-REGION:AWS-ACCOUNT:certificate/AWS-CERTIFICATE-UUD
#
# Development URL masking external hostname (storage URL encryption)
# AWS Lambda function role:
# These variables are used only if deploy without AWS SAM (deploy_without_sam) in big_lambdas_manager.sh. SAM generates this role automatically
AWS_LAMBDA_FUNCTION_ROLE_QA=exampleapp-api_handler-role-qa
AWS_LAMBDA_FUNCTION_ROLE_STAGING=exampleapp-api_handler-role-staging
AWS_LAMBDA_FUNCTION_ROLE_DEMO=exampleapp-api_handler-role-demo
AWS_LAMBDA_FUNCTION_ROLE_PROD=exampleapp-api_handler-role-prod
#
# AWS SSL certificate ARN (used by big_lambdas_manager.sh)
AWS_SSL_CERTIFICATE_ARN=arn:aws:acm:AWS-REGION:AWS-ACCOUNT:certificate/AWS-CERTIFICATE-UUID
#
# AWS S3 bucket name (used by set_fe_cloudfront_domain.sh to set the CloudFront domain name in the frontend for the CORS config)
AWS_S3_BUCKET_NAME_FE=aws-s3-bucket-name
#
# Development URL masking external hostname (for features like AI Vision)
URL_MASK_EXTERNAL_HOSTNAME=app-dev.exampleapp.com
#
# SMTP Mail configuration
Expand All @@ -119,28 +158,58 @@ SMTP_DEFAULT_SENDER=sender_email
DOCKER_ACCOUNT=docker_account_username
#
# Local development environment run configuration
#
# Options are: uvicorn, gunicorn, chalice, chalice_docker
#
# Chalice case: "chalice" to use http (running without docker) or "chalice_docker" to use https (with docker)
# http:
# RUN_METHOD="chalice"
# https:
RUN_METHOD="chalice_docker"
#
# Tests configuration
#
# Testing enndpoint
TEST_APP_URL=http://app.exampleapp.local:5002
#
# Default App main code directory
# for Chalice:
# https://aws.github.io/chalice/topics/packaging.html
# APP_DIR='.'
# for FastAPI:
# https://fastapi.tiangolo.com/tutorial/bigger-applications/?h=directory+structure#an-example-file-structure
# APP_DIR='app'
# for Flask:
# https://flask.palletsprojects.com/en/2.3.x/tutorial/layout/
# APP_DIR='flaskr'
#
# Default App entry point code file
# for Chalice:
# https://aws.github.io/chalice/topics/packaging.html
# APP_MAIN_FILE='app'
# for FastAPI:
# https://fastapi.tiangolo.com/tutorial/bigger-applications/?h=directory+structure#an-example-file-structure
# APP_MAIN_FILE='main'
# for Flask:
# https://flask.palletsprojects.com/en/2.3.x/tutorial/factory/
# APP_MAIN_FILE='__init__'
#
# Flask configuration
FLASK_APP=index.py
#
# AI technology (openai/langchain APIs)
# AI_TECHNOLOGY="openai"
AI_TECHNOLOGY="langchain"
# Local frontend port (defautls to 3000)
FRONTEND_LOCAL_PORT=3000
# Local backend API port (defaults to 5001)
BACKEND_LOCAL_PORT=5001
#
####################
# AI Configuration #
####################
#
# AI technology (openai/langchain APIs)
# AI_TECHNOLOGY="openai"
AI_TECHNOLOGY="langchain"
#
# Google configuration
# https://console.cloud.google.com/apis/credentials
GOOGLE_API_KEY=google_console_api_key
Expand All @@ -150,6 +219,7 @@ GOOGLE_CSE_ID=google_console_cse_key
# OpenAI configuration
# https://platform.openai.com/api-keys
OPENAI_API_KEY=openai_api_key
# https://openai.com/api/pricing/
OPENAI_MODEL=gpt-3.5-turbo
OPENAI_TEMPERATURE=0.7
#
Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@ This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a Ch
### Breaks


## 0.1.8 (2024-07-18)

### New
Add "langchain-google-community" due to a deprecation notice about GoogleSearchAPIWrapper [GS-66].
Add Langchain Tools description length validation, to avoid descriptions > 1024 chars.

### Changes
Update dependecies "langchain" (from ^0.1.20 to ^0.2.3), "langchain-core", "langchain-openai" (from ^0.1.6 to ^0.1.8), "tiktoken" (from 0.6 to ^0.7.0) to be able to add "langchain-google-community" [GS-66].
Update env.example. to have the GS BE Core latest updates.
AWS_API_GATEWAY_STAGE env. var. removed from env.example.
All DEBUGs turned off to save logs/AWS Cloudwatch space.

### Fixes
Fix audio processing issues in FastAPI due to AWS API Gateway limitations, sending the base64 encoded files back [GS-95].
Change: minor linting changes.


## 0.1.7 (2024-06-06)

### New
Expand Down
52 changes: 45 additions & 7 deletions genericsuite_ai/fastapilib/endpoints/ai_chatbot_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,14 @@
from fastapi.security import HTTPBasic

# from genericsuite.util.framework_abs_layer import Response, BlueprintOne
from genericsuite.fastapilib.framework_abstraction import Response, BlueprintOne
from genericsuite.fastapilib.framework_abstraction import (
Response,
BlueprintOne,
)
from genericsuite.util.app_logger import log_debug
from genericsuite.util.utilities import (
send_file_text_text,
)

from genericsuite.fastapilib.util.parse_multipart import download_file_fa
from genericsuite.fastapilib.util.dependencies import (
Expand All @@ -33,6 +39,7 @@
# assign_app_gpt_functions
# )


class VisionImageAnalyzerRequest(BaseModel):
"""
This class is used to parse the query parameters for the
Expand All @@ -53,7 +60,10 @@ class TranscribeAudioRequest(BaseModel):
other: str


DEBUG = True
DEBUG = False

# send_file_fa() mode
SEND_FILE_AS_BINARY = False

# Set FastAPI router
# router = APIRouter()
Expand All @@ -75,6 +85,18 @@ def remove_temp_file(file_path: str) -> None:
def send_file_fa(
file_to_send: str,
background_tasks: BackgroundTasks,
) -> Any:
"""
Send the file back, the FastAPI way
"""
if SEND_FILE_AS_BINARY:
return send_binary_file_fa(file_to_send, background_tasks)
return send_base64_file_fa(file_to_send, background_tasks)


def send_binary_file_fa(
file_to_send: str,
background_tasks: BackgroundTasks,
) -> FileResponse:
"""
Send the file back, the FastAPI way
Expand All @@ -87,6 +109,19 @@ def send_file_fa(
return FileResponse(file_to_send)


def send_base64_file_fa(
file_to_send: str,
background_tasks: BackgroundTasks,
) -> Any:
"""
Return the file content as GenericSuite way, Base64 encoded.
This approach worked for audio file and the ai_chatbot in Chalice
because AWS API Gateway won't allow binary responses.
"""
_ = DEBUG and log_debug("Returning file content the Genericsuite way")
return send_file_text_text(file_to_send)


@router.post('/chatbot', tags='chatbot')
async def ai_chatbot_endpoint(
request: FaRequest,
Expand Down Expand Up @@ -129,7 +164,7 @@ async def ai_chatbot_endpoint(
async def vision_image_analyzer_endpoint(
request: FaRequest,
file: UploadFile = File(...),
# file: Annotated[UploadFile, File(...)] = None,
# file: Annotated[UploadFile, File(...)] = None,
current_user: str = Depends(get_current_user),
query_params: VisionImageAnalyzerRequest = Depends(),
) -> Response:
Expand All @@ -142,15 +177,17 @@ async def vision_image_analyzer_endpoint(
:return: The text with the image analysis.
"""
_ = DEBUG and \
log_debug('1) vision_image_analyzer_endpoint | query_params:' +
log_debug(
'1) vision_image_analyzer_endpoint | query_params:' +
f' {request.query_params}')
gs_request, other_params = get_default_fa_request(
current_user=current_user, query_params=query_params.dict(),
preserve_nones=True)
router.set_current_request(request, gs_request)
uploaded_file_path = await download_file_fa(file)
_ = DEBUG and \
log_debug('2) vision_image_analyzer_endpoint | uploaded_file_path:' +
log_debug(
'2) vision_image_analyzer_endpoint | uploaded_file_path:' +
f' {uploaded_file_path} | request: {request}')
return vision_image_analyzer_endpoint_model(
request=gs_request,
Expand All @@ -165,7 +202,7 @@ async def vision_image_analyzer_endpoint(
async def transcribe_audio_endpoint(
request: FaRequest,
file: UploadFile = File(...),
# file: Annotated[UploadFile, File()] = None,
# file: Annotated[UploadFile, File()] = None,
current_user: str = Depends(get_current_user),
query_params: TranscribeAudioRequest = Depends(),
) -> Response:
Expand All @@ -178,7 +215,8 @@ async def transcribe_audio_endpoint(
:return: The transcription result.
"""
_ = DEBUG and \
log_debug('transcribe_audio_endpoint | query_params:' +
log_debug(
'transcribe_audio_endpoint | query_params:' +
f' {request.query_params}')
gs_request, other_params = get_default_fa_request(
current_user=current_user, query_params=query_params.dict(),
Expand Down
2 changes: 1 addition & 1 deletion genericsuite_ai/lib/ai_chatbot_commons.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
get_current_date_time
)

DEBUG = True
DEBUG = False


def get_role(v):
Expand Down
6 changes: 4 additions & 2 deletions genericsuite_ai/lib/ai_chatbot_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
)
from genericsuite_ai.models.billing.billing_utilities import BillingUtilities

DEBUG = True
DEBUG = False


def ai_chatbot_endpoint(
Expand Down Expand Up @@ -92,6 +92,7 @@ def ai_chatbot_endpoint(
# after the app_context_and_set_env(request)
settings = Config(app_context)
billing = BillingUtilities(app_context)

def get_model_engine():
model_engine = \
f'\n | AI_TECHNOLOGY: {settings.AI_TECHNOLOGY}'
Expand Down Expand Up @@ -137,7 +138,8 @@ def get_sub_model_name():

if '[SEND_FILE_BACK]' in ai_chatbot_response.get('response'):
file_to_send = ai_chatbot_response['response'].split('=')[1]
_ = DEBUG and log_debug('AICBEP-3) AI_CHATBOT_ENDPOINT' +
_ = DEBUG and log_debug(
'AICBEP-3) AI_CHATBOT_ENDPOINT' +
f' - Sending file: {file_to_send}')
if sendfile_callable:
return sendfile_callable(
Expand Down
27 changes: 26 additions & 1 deletion genericsuite_ai/lib/ai_chatbot_main_langchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
from genericsuite_ai.models.billing.billing_utilities import BillingUtilities


DEBUG = True
DEBUG = False

NON_AI_TRANSLATOR = 'google_translate'
NON_AGENT_PROMPT = 'mediabros/gs_non_agent_lcel'
Expand Down Expand Up @@ -532,6 +532,30 @@ def run_lcel_chain(
return exec_result


def verify_tools(tools, conv_response):
"""
Verify if the tools are valid, checking the Tool description lenght.
"""
if conv_response["error"]:
return conv_response
bad_tools = [
(tuple(
[index, f"Lenght: {len(tools[index].description)}", tools[index]]
))
for index in range(len(tools))
if len(tools[index].description) > 1024
]
_ = DEBUG and \
log_debug('>>> VERIFY_TOOLS | LONG DESC tools[list]:' +
f' {bad_tools}')
if len(bad_tools) > 0:
conv_response["error"] = True
conv_response["error_message"] = \
"ERROR: Too long Tool description(s): " + \
', '.join([f'{v[2].name} ({v[1]})' for v in bad_tools])
return conv_response


def run_assistant(
conv_response: dict,
llm: Any,
Expand All @@ -547,6 +571,7 @@ def run_assistant(
log_debug('>>> 1) RUN_ASSISTANT | LANGCHAIN_AGENT_TYPE:' +
f' {settings.LANGCHAIN_AGENT_TYPE}')

conv_response = verify_tools(tools, conv_response)
if conv_response["error"]:
return conv_response

Expand Down
2 changes: 1 addition & 1 deletion genericsuite_ai/lib/ai_vision.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
)
from genericsuite_ai.models.billing.billing_utilities import BillingUtilities

DEBUG = True
DEBUG = False
cac = CommonAppContext()


Expand Down
2 changes: 1 addition & 1 deletion genericsuite_ai/lib/web_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
)
from genericsuite_ai.config.config import Config

DEBUG = True
DEBUG = False

cac = CommonAppContext()

Expand Down
Loading

0 comments on commit f8c50c3

Please sign in to comment.