├── .github └── workflows │ └── docs.yml ├── .gitignore ├── Blogs └── Customer-Support │ ├── Customer_Support_Automation_with_Bedrock_and_LangGraph.ipynb │ ├── cs_bedrock.py │ ├── cs_cust_support_flow.py │ ├── cs_db.py │ ├── cs_jira_sm.py │ ├── cs_util.py │ ├── data │ ├── AS-10-before.png │ ├── AS-10-updated.png │ ├── AS-11-before.png │ ├── AS-11-updated.png │ ├── AS-4-before.png │ ├── AS-4-updated.png │ ├── AS-5-before.png │ ├── AS-5-updated.png │ ├── AS-6-before.png │ ├── AS-6-updated.png │ ├── AS-7-before.png │ ├── AS-7-updated.png │ ├── AS-8-before.png │ ├── AS-8-updated.png │ ├── AS-9-before.png │ ├── AS-9-updated.png │ ├── customer-support-tech-stack.png │ ├── customers.json │ ├── listed-bottle.jpg │ ├── listed_product.jpg │ ├── orders.json │ ├── refunds.json │ └── transactions.json │ ├── main.py │ └── requirements.txt ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Converse API └── Tool-Use │ ├── HCLS_Tool_Use_HealthAgent.ipynb │ ├── Mistral_Large_2_JSON_Mode.ipynb │ ├── Payments_Tool_Use_with_Mistral.ipynb │ └── Tool_Use_with_Mistral.ipynb ├── Deployment ├── Bedrock Marketplace │ ├── Deploy-Mistral-NeMo-from-Bedrock-Marketplace-and-its-Capabilities.ipynb │ └── Deploy-Pixtral12B-from-Bedrock-Marketplace.ipynb ├── Bedrock │ └── mistral-bedrock-guardrails.ipynb ├── CMI │ └── Import_Mistral_NeMo_to_Bedrock_CMI.ipynb ├── EC2 │ ├── Pixtral-ec2-deploy+inf .ipynb │ └── mistral-small-3-0-nxdi-guide.ipynb └── SageMaker │ ├── Mistral-Nemo-Instruct-2407_deploy_sample.ipynb │ ├── Pixtral-12b-LMI-SageMaker-realtime-inference.ipynb │ ├── imgs │ ├── image-mistral.webp │ ├── img │ └── mistral-instruct-knowledge.webp │ └── mistral-small-3-1-LMI.ipynb ├── LICENSE ├── MCP ├── AirbnbFinder.ipynb ├── Location_based_recommendations.ipynb ├── MCP_Mistral_app_demo │ ├── .gradio │ │ └── certificate.pem │ ├── README.md │ ├── gradio_app.py │ ├── requirements.txt │ └── src │ │ ├── README.md │ │ ├── agent.py │ │ ├── chat.py │ │ ├── config.py │ │ ├── mcpclient.py │ │ ├── server_configs.py │ │ └── utility.py └── MCP_Mistral_app_demo_with_Strands │ ├── README.md │ ├── chat.py │ ├── config.py │ ├── gradio_app.py │ ├── requirements.txt │ └── server_configs.py ├── Mistral Large 2 ├── Abstract Document Summarization with Langchain using Mistral Large on Bedrock.ipynb ├── Introduction_to_prompt_chaining_Mistral_Large.ipynb ├── Language_Comparison_Large_1_2.ipynb ├── Large_2_Release_Highlights.ipynb ├── Mistral_Large_2_Capabilities.ipynb ├── ReAct_LlamaIndex_Large 2.py └── mistral_large_getting_started_101.ipynb ├── Mistral NeMo └── NeMo_comparative_analysis.ipynb ├── Mistral OCR └── Mistral-OCR-SageMaker-Deployment-example.ipynb ├── Mistral Small 3 └── Mistral_small_3.ipynb ├── Pixtral-samples ├── Pixtral Large (25.02) │ ├── .gitignore │ ├── README.md │ ├── app.py │ └── requirements.txt ├── Pixtral-12b-Performance-Benchmarking.ipynb ├── Pixtral-v1-notebook.ipynb ├── Pixtral_Large_Capabilities.ipynb ├── Pixtral_benchmarking_data │ └── .gitignore ├── Pixtral_capabilities.ipynb ├── Pixtral_comparative_analysis.ipynb ├── Pixtral_data │ ├── 29IYUhRytF5g4wGBCxFm7A.jpg │ ├── 3a1SR_oZI0-dCEvLG7US5g.jpg │ ├── 3agipTLldLEBe7JIvhnv9g.jpg │ ├── 40_Year_Net_Present_Value_of_4-Year_Colleges_by_Tuition_in_the_United_States.png │ ├── AMZN-Q2-2024-Earning-High-Quality.png │ ├── AMZN-Q2-2024-Earnings-Release.jpg │ ├── Amazon_Chart.png │ ├── Amazon_Chart_resize.png │ ├── Crosstab_of_Cola_Preference_by_Age_and_Gender.png │ ├── DNNIYVEp62blavqxGKLX5A.jpg │ ├── Iconographic_navigation_comparison.png │ ├── Map_Motorcycles_vs_cars_by_population_millions_2002.png │ ├── Stevens_Field_VFR_Map_(2022).jpeg │ ├── a01-000u-02.png │ ├── a01-000u-03.png │ ├── a01-000u-04.png │ ├── a01-082u-00.png │ ├── a01-082u-01.png │ ├── a01-082u-02.png │ ├── a01-082u-03.png │ ├── a01-082u-04.png │ ├── airport_lanes.jpeg │ ├── amazon_gloves.jpg │ ├── amazon_s1.jpg │ ├── amazon_s1_2.jpg │ ├── br_marketplace_delete_endpoint.jpg │ ├── br_marketplace_deploy.jpg │ ├── br_marketplace_model_card.jpg │ ├── br_marketplace_model_endpoint.jpg │ ├── br_model_catalog.jpg │ ├── cap.png │ ├── car_image_after.png │ ├── car_image_before.png │ ├── chair.jpeg │ ├── cleaner.jpeg │ ├── coffee.jpeg │ ├── database-schema.png │ ├── dog_bag.jpg │ ├── dresser.jpg │ ├── er-diagram.jpeg │ ├── gdp.png │ ├── handwriting_low_res_2_resize.jpg │ ├── hindi_teaser.jpeg │ ├── insurance_90degree.pdf │ ├── jxOrwCQTTDt9Uvu_c3br5w.jpg │ ├── logical_reasoning.jpg │ ├── luggage.jpg │ ├── org_hierarchy.jpeg │ ├── portfolio-website.png │ ├── restaurant-receipt-brazil.jpeg │ ├── scene.jpg │ ├── texas_noaa_image.jpeg │ ├── trig-equations-from-context.png │ ├── trimmed_green_beans.jpg │ ├── whiteboard.png │ ├── xQdHJOV6XXIRRuFpNVIojw.jpg │ └── xqHNkPl7rohq7_R7f1nAUA.jpg └── Vision_QA_Agent_with_Pixtral_and_LlamaIndex.ipynb ├── README.md ├── Use Cases ├── Agents │ ├── Advanced_Multi-Chain_Routing_With_LangChain.ipynb │ ├── LangChainToolUse_Mistral_Bedrock.ipynb │ └── Mistral_Large2_agentic_rag_with_llamaindex.ipynb ├── Code Generation │ └── Text-2-SQL-Mistral-Nemo-12B-SageMaker.ipynb ├── Fine-tuning │ ├── finetune-mistral-7b-with-dolly-and-qlora.ipynb │ └── mixtral-8x7b-qlora-finetune.ipynb ├── RAG │ └── Mistral_model_RAG_pipeline_evaluation.ipynb └── mistral_usecases.ipynb ├── Workshops ├── London-enablement-workshop │ ├── 1. Mistral_prompting_capabilities.ipynb │ ├── 2 Mistral_small_3.ipynb │ ├── 3. Mistral_Pixtral12B.ipynb │ ├── 4. Mistral_Large2_agentic_rag_with_llamaindex.ipynb │ ├── README.md │ ├── docs │ │ ├── genai_on_aws.pdf │ │ └── ml_on_aws.pdf │ ├── images │ │ ├── a01-000u-04.png │ │ ├── br_marketplace_delete_endpoint.jpg │ │ ├── br_marketplace_deploy.jpg │ │ ├── br_marketplace_model_card.jpg │ │ ├── br_marketplace_model_endpoint.jpg │ │ ├── br_model_catalog.jpg │ │ ├── cap.png │ │ ├── car_image_after.png │ │ ├── car_image_before.png │ │ ├── endpoint-delete.png │ │ ├── gdp.png │ │ ├── llamaindex-agentic-rag-mistral-large2-arch.png │ │ ├── logical_reasoning.jpg │ │ ├── model-configuration.png │ │ ├── model-endpoint.png │ │ ├── model-information.png │ │ └── search-model.png │ └── requirements.txt ├── NY_Bedrock_Workshop │ ├── AWS-security-whitepaper.pdf │ ├── Data_Gen_Large_2.ipynb │ ├── long_context_mistral_large_2.ipynb │ └── requirements.txt └── aws-summit-paris-2025-agentic │ ├── .gitignore │ ├── README.md │ ├── assets │ ├── event_venue.jpeg │ └── velib_stations.json │ ├── aws_llm.py │ ├── notebook.ipynb │ ├── pyproject.toml │ ├── tools_demo.json │ ├── tools_utils.py │ ├── utils.py │ └── uv.lock ├── docs ├── index.md └── notebooks.md ├── mkdocs.yml └── notebooks ├── Codestral-samples ├── Codestral-TGI-deployment.ipynb ├── Codestral-vLLM-SageMaker.ipynb ├── codestral_chat_ui │ └── codestral_chat.py └── imgs │ ├── codestral.png │ └── img ├── Mathstral-samples ├── Mathstral-TGI-deployment-nb.ipynb ├── Mathstral_chat_ui │ └── Mathstral_chat.py └── imgs │ ├── img │ └── mathstral-benchmarks.png ├── Mistral-7B-Insurance-Neuron ├── Fine-tuned Mistral Models - thumbnail.png ├── app-config.json ├── app.py ├── deploy-mistral-7B-insurance.ipynb └── streamlit-chatbot-video.gif ├── Mistral-on-AWS-Neuron └── Mathstral │ ├── Compile-Deploy-Benchmark-Mathstral-on-Neuron.ipynb │ └── gradio_neuron │ └── mathstral_chat.py ├── NIM-inference-samples └── mixtral_8x7b_Nvidia_nim.ipynb ├── distributed-inference-deployment ├── Mixtral-8x7b-TensorRT-LLM-SageMaker.ipynb └── Mixtral-8x7b-vLLM-SageMaker.ipynb ├── finetune-mistral-7b-scripts ├── requirements.txt └── run_clm.py ├── imgs ├── imgs ├── llamaindex-agentic-rag-mistral-large2-arch.png ├── mapreduce.png ├── mistral-aws-partnership-img.jpeg ├── mistral-large-2407-code-generation.png ├── mistral-large-2407-language-diversity.webp ├── mistral-large-2407-multiple.webp ├── mistral-large-2407-tool-use.png ├── mistralaws.png ├── multilingual-mmlu.png ├── nemo-base-performance.png ├── nemo-instruct-performance.png └── refine.png ├── mistral-aws-llm-router-ReAct-agent └── Mistral-AWS-llm-router.ipynb ├── mistral-langgraph ├── Multi_Agent_LangGraph_Mistral.ipynb └── data │ ├── eventsDB_data.json │ └── restaurant_data.json ├── mistral-llamaindex-agentic-rag ├── README.md ├── architecture.png ├── docs │ ├── genai_on_aws.pdf │ └── ml_on_aws.pdf ├── mistral_agentic_rag_with_llamaindex.ipynb ├── requirements.txt └── utils.py ├── mixtral_finetune_qlora_sft ├── finetune-mixtral.ipynb └── scripts │ ├── launch_fsdp_qlora.py │ ├── merge_model_adapter.py │ └── requirements.txt ├── sample_data ├── members.json └── transactions.json └── synthetic_data_gen └── bedrock_synthetic_data_gen_chat_finetuning.ipynb /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Publish docs 2 | on: 3 | push: 4 | paths: 5 | - 'docs/**' 6 | - '.github/workflows/docs.yml' 7 | - 'mkdocs.yml' 8 | jobs: 9 | publish: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: actions/setup-python@v4 14 | with: 15 | python-version: 3.11 16 | - name: Install dependencies 17 | run: | 18 | pip install --upgrade pip 19 | pip install mkdocs-material mkdocstrings[python] mkdocs-click 20 | - name: Deploy 21 | run: mkdocs gh-deploy --force 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb_checkpoints/* 2 | .ipynb_checkpoints/ 3 | .DS_Store 4 | .env 5 | __pycache__ 6 | -------------------------------------------------------------------------------- /Blogs/Customer-Support/cs_bedrock.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import os 3 | from typing import Tuple 4 | from cs_util import Utility 5 | from langchain_aws import ChatBedrockConverse 6 | 7 | GUARDRAIL_NAME = "customer-support-content-safety-guardrail" 8 | DEFAULT_MODEL = "mistral.mistral-large-2407-v1:0" 9 | VISION_MODEL = 'us.mistral.pixtral-large-2502-v1:0' 10 | AWS_REGION = "us-west-2" 11 | 12 | class BedrockClient: 13 | def __init__(self): 14 | self.util = Utility() 15 | self.guardrail_id = '' 16 | self.guardrail_version = 'DRAFT' 17 | 18 | 19 | def init_llms(self, ticket_id: str): 20 | 21 | self.util.log_data(f'Initializing Bedrock client', ticket_id=ticket_id) 22 | self.util.log_data(f'Using guardrail_id==> {self.guardrail_id}', ticket_id=ticket_id) 23 | 24 | # Initialize ChatBedrockConverse for Text 25 | llm = ChatBedrockConverse( 26 | model=DEFAULT_MODEL, 27 | temperature=0, 28 | max_tokens=4000, 29 | region_name=AWS_REGION, 30 | ) 31 | 32 | llm_with_guardrails = ChatBedrockConverse( 33 | model=DEFAULT_MODEL, 34 | temperature=0, 35 | max_tokens=4000, 36 | region_name=AWS_REGION, 37 | guardrails={ 38 | "guardrailIdentifier": self.guardrail_id, 39 | "guardrailVersion": self.guardrail_version, 40 | "trace": "enabled" 41 | } 42 | ) 43 | 44 | # Initialize ChatBedrockConverse for Vision 45 | vision_llm = ChatBedrockConverse( 46 | model=VISION_MODEL, 47 | temperature=0, 48 | max_tokens=4000, 49 | region_name=AWS_REGION, 50 | ) 51 | 52 | return llm, vision_llm, llm_with_guardrails 53 | 54 | 55 | def create_guardrail(self) -> str: 56 | """ 57 | Creates a guardrail in Amazon Bedrock with topic policy configuration. 58 | 59 | Returns: 60 | Tuple[str, str]: Guardrail ID and version 61 | """ 62 | try: 63 | # Initialize the Bedrock client 64 | bedrock_client = boto3.client('bedrock', AWS_REGION) 65 | 66 | # check if guardrail already exists 67 | response = bedrock_client.list_guardrails() 68 | 69 | guardrail_exists = False 70 | # Check if guardrail exists 71 | for guardrail in response['guardrails']: 72 | if guardrail['name'] == GUARDRAIL_NAME: 73 | guardrail_exists = True 74 | self.guardrail_id = guardrail['id'] 75 | 76 | return self.guardrail_id 77 | 78 | if (not guardrail_exists): 79 | # Create the guardrail 80 | create_response = bedrock_client.create_guardrail( 81 | name=GUARDRAIL_NAME, 82 | description='Guardrails to prevent harmful content generation', 83 | contentPolicyConfig={ 84 | 'filtersConfig': [ 85 | { 86 | 'type': 'SEXUAL', 87 | 'inputStrength': 'MEDIUM', 88 | 'outputStrength': 'MEDIUM' 89 | }, 90 | { 91 | 'type': 'VIOLENCE', 92 | 'inputStrength': 'MEDIUM', 93 | 'outputStrength': 'MEDIUM' 94 | }, 95 | { 96 | 'type': 'HATE', 97 | 'inputStrength': 'MEDIUM', 98 | 'outputStrength': 'MEDIUM' 99 | }, 100 | { 101 | 'type': 'INSULTS', 102 | 'inputStrength': 'MEDIUM', 103 | 'outputStrength': 'MEDIUM' 104 | }, 105 | { 106 | 'type': 'MISCONDUCT', 107 | 'inputStrength': 'MEDIUM', 108 | 'outputStrength': 'MEDIUM' 109 | }, 110 | { 111 | 'type': 'PROMPT_ATTACK', 112 | 'inputStrength': 'LOW', 113 | 'outputStrength': 'NONE' 114 | } 115 | ] 116 | }, 117 | wordPolicyConfig={ 118 | 'wordsConfig': [ 119 | {'text': 'stock and investment advise'} 120 | ], 121 | 'managedWordListsConfig': [ 122 | {'type': 'PROFANITY'} 123 | ] 124 | }, 125 | contextualGroundingPolicyConfig={ 126 | 'filtersConfig': [ 127 | { 128 | 'type': 'GROUNDING', 129 | 'threshold': 0.65 130 | }, 131 | { 132 | 'type': 'RELEVANCE', 133 | 'threshold': 0.75 134 | } 135 | ] 136 | }, 137 | blockedInputMessaging="""Input prompt or context is not appropriate for customer support.""", 138 | blockedOutputsMessaging="""Generated output is not appropriate for the customer support""", 139 | ) 140 | 141 | self.guardrail_id = create_response['guardrailId'] 142 | return self.guardrail_id 143 | 144 | except Exception as e: 145 | self.util.log_error(f"Error creating guardrail: {str(e)}", ticket_id='NA') 146 | raise e 147 | 148 | def delete_guardrail(self) -> bool: 149 | """ 150 | Deletes a guardrail from Amazon Bedrock. 151 | 152 | Args: 153 | guardrail_id (str): The identifier of the guardrail to delete 154 | 155 | Returns: 156 | bool: True if deletion was successful, False otherwise 157 | """ 158 | try: 159 | # Initialize the Bedrock client 160 | bedrock_client = boto3.client('bedrock') 161 | 162 | # Delete the guardrail 163 | response = bedrock_client.delete_guardrail(guardrailIdentifier=self.guardrail_id) 164 | 165 | # Check if deletion was successful 166 | if response['ResponseMetadata']['HTTPStatusCode'] == 202: 167 | self.util.log_data(f"Successfully deleted guardrail", ticket_id='NA') 168 | return True 169 | 170 | return False 171 | 172 | except bedrock_client.exceptions.ResourceNotFoundException: 173 | self.util.log_error(f"Guardrail with ID {self.guardrail_id} not found") 174 | return False 175 | except Exception as e: 176 | self.util.log_error(f"Error deleting guardrail: {str(e)}") 177 | return False 178 | 179 | 180 | -------------------------------------------------------------------------------- /Blogs/Customer-Support/cs_db.py: -------------------------------------------------------------------------------- 1 | from sqlite3 import connect 2 | import os 3 | import pandas as pd 4 | from pandas.core.frame import DataFrame 5 | from contextlib import closing 6 | from cs_util import Utility 7 | 8 | 9 | class Database: 10 | def __init__(self): 11 | self.util = Utility() 12 | temp_path = self.util.get_temp_path() 13 | 14 | if not os.path.exists(temp_path): 15 | os.makedirs(temp_path) 16 | 17 | # This function creates anew SQLite database and imports content of .json files in the db 18 | def import_in_db(self, table_name: str, json_file_path: str): 19 | df = pd.read_json(json_file_path) 20 | with closing(connect(self.util.get_db_path())) as conn: 21 | df.to_sql(table_name, conn, if_exists='replace', index=False) 22 | conn.close() 23 | 24 | #log_data(data=f"Table *{table_name}* created with {len(df)} rows.") 25 | 26 | def execute_query(self, query: str, params: list = None, not_found_message: str=''): 27 | ''' 28 | This function executes provided SQL statement on SQLite database and returns records in json format 29 | ''' 30 | 31 | with closing(connect(self.util.get_db_path())) as conn: 32 | df = pd.read_sql_query(sql=query, con=conn, params=params) 33 | 34 | if not df.empty: 35 | return df.to_json(orient='records') 36 | else: 37 | return not_found_message 38 | 39 | def import_all(self): 40 | 41 | data_path = self.util.get_data_path() 42 | 43 | self.import_in_db(table_name='customers', json_file_path=f'{data_path}/customers.json') 44 | self.import_in_db(table_name='orders', json_file_path=f'{data_path}/orders.json') 45 | self.import_in_db(table_name='transactions', json_file_path=f'{data_path}/transactions.json') 46 | self.import_in_db(table_name='refunds', json_file_path=f'{data_path}/refunds.json') -------------------------------------------------------------------------------- /Blogs/Customer-Support/cs_jira_sm.py: -------------------------------------------------------------------------------- 1 | # JIRA imports 2 | from jira import JIRA 3 | from jira.resources import Issue 4 | from dotenv import load_dotenv 5 | from requests.auth import HTTPBasicAuth 6 | import os 7 | import requests 8 | from cs_util import Utility 9 | 10 | JIRA_PROJECT_NAME = "AnyCompany - Support" 11 | JIRA_PROJECT_KEY = "AS" 12 | JIRA_BOT_USER_ID = 'jira.ai.bot@gmail.com' 13 | # Custom Field IDs 14 | JIRA_CATEGORY_FIELD_ID = 10049 15 | JIRA_RESPONSE_FIELD_ID = 10047 16 | 17 | class JiraSM: 18 | def __init__(self): 19 | load_dotenv() 20 | self.jira_api_token=os.getenv("JIRA_API_TOKEN") 21 | self.jira_username=os.getenv("JIRA_USERNAME") 22 | self.jira_instance_url=os.getenv("JIRA_INSTANCE_URL") 23 | 24 | self.util = Utility() 25 | 26 | def get_jira_object(self): 27 | ''' 28 | This function creates a Jira object to connect to Jira instance 29 | ''' 30 | options = {'server': self.jira_instance_url} 31 | jira = JIRA(options, basic_auth=(self.jira_username, self.jira_api_token)) 32 | return jira 33 | 34 | 35 | def download_attachment(self, attachment_url, filename, ticket_id): 36 | ''' 37 | This function downloads attachment from Jira ticket and saves it locally in temp directory 38 | ''' 39 | 40 | auth = HTTPBasicAuth(self.jira_username, self.jira_api_token) 41 | headers = { 42 | "Accept": "application/json" 43 | } 44 | 45 | response = requests.get(attachment_url, headers=headers, stream=True, auth=auth) 46 | response.raise_for_status() # Raise an exception for HTTP errors 47 | 48 | file_path = os.path.join(self.util.get_temp_path(), filename) 49 | with open(file_path, "wb") as file: 50 | for chunk in response.iter_content(chunk_size=1024): 51 | file.write(chunk) 52 | 53 | self.util.log_data(data=f"Downloaded: {file_path}", ticket_id='NA') 54 | return file_path 55 | 56 | def get_ticket(self, key: str): 57 | if (len(key) > 0): 58 | jira = self.get_jira_object() 59 | issue = jira.issue(key) 60 | return issue 61 | else: 62 | return None 63 | 64 | 65 | def update_custom_field_value(self, key: str, field_name: str, value): 66 | jira_issue = self.get_ticket(key) 67 | jira_issue.update(fields={field_name: [{'value': value}]}) 68 | 69 | 70 | def assign_to_bot(self, key: str): 71 | jira_issue = self.get_jira_object() 72 | jira_issue.assign_issue(key, JIRA_BOT_USER_ID) 73 | 74 | 75 | def get_category_field_id(self): 76 | return JIRA_CATEGORY_FIELD_ID 77 | 78 | def get_response_field_id(self): 79 | return JIRA_RESPONSE_FIELD_ID -------------------------------------------------------------------------------- /Blogs/Customer-Support/cs_util.py: -------------------------------------------------------------------------------- 1 | # Standard library imports 2 | import logging 3 | import base64 4 | import sys 5 | import os 6 | import re 7 | from IPython.display import Image, display 8 | from langchain_core.messages.base import get_msg_title_repr 9 | 10 | RESET = "\033[0m" 11 | HEADER_GREEN = "\033[38;5;29m" 12 | DATA_BLUE = "\033[94m" 13 | ORANGE = "\033[38;5;208m" 14 | PURPLE = "\033[38;5;93m" 15 | ERROR_RED = "\033[38;5;196m" 16 | 17 | DATA_PATH = './data' 18 | LOG_FILE_NAME = './data/cs_logs.log' 19 | 20 | class Utility: 21 | def __init__(self): 22 | 23 | logging.basicConfig( 24 | level=logging.INFO, 25 | format='%(asctime)s - %(levelname)s - %(message)s', 26 | handlers=[ 27 | logging.StreamHandler(), 28 | logging.FileHandler(LOG_FILE_NAME) 29 | ] 30 | ) 31 | 32 | self.logger = logging.getLogger(__name__) 33 | self.data_path = DATA_PATH 34 | 35 | self.temp_path = f'{DATA_PATH}/temp' 36 | self.db_path = f'{self.temp_path}/customer_support_db.db' 37 | 38 | def get_temp_path(self): 39 | return self.temp_path 40 | 41 | def get_db_path(self): 42 | return self.db_path 43 | 44 | def get_data_path(self): 45 | return self.data_path 46 | 47 | def log_header(self, function_name: str, ticket_id: str=''): 48 | print(f'{HEADER_GREEN}') # set color 49 | self.logger.info(f' #### {function_name} ## Ticket: {ticket_id}####') 50 | #print(f'{RESET}') 51 | 52 | def log_data(self, data, ticket_id: str): 53 | print(f'{DATA_BLUE}') # reset color 54 | self.logger.info(f'Ticket: {ticket_id} -- {data}') 55 | #print(f'{RESET}') 56 | 57 | def log_error(self, error, ticket_id: str): 58 | print(f'{ERROR_RED}') # reset color 59 | self.logger.error(f'Ticket: {ticket_id} -- {error}') 60 | #print(f'{RESET}') 61 | 62 | def log_usage(self, usage: list, ticket_id: str): 63 | print(f'{DATA_BLUE}') # reset color 64 | 65 | # Find the maximum length of model names to determine column width 66 | model_col_width = max( 67 | len('Model'), 68 | max(len(item['model_name']) for item in usage) 69 | ) 70 | 71 | col_width = 15 72 | # Create the header with dynamic width for Model column 73 | usage_to_print = ( 74 | f'LLM Usage for Ticket: {ticket_id}\n' 75 | f'{"Model":<{model_col_width}} {"Input Tokens":<{col_width}} {"Output Tokens":<{col_width}} {"Latency":<{col_width}}' 76 | ) 77 | 78 | # Add each usage item with aligned columns 79 | for item in usage: 80 | usage_to_print += ( 81 | f"\n{item['model_name']:<{model_col_width}}" 82 | f" {item['input_tokens']:<{col_width}}" 83 | f"{item['output_tokens']:<{col_width}}" 84 | f"{item['latency']:<{col_width}}" 85 | ) 86 | 87 | self.logger.info(usage_to_print) 88 | #print(f'{RESET}') 89 | 90 | 91 | def log_execution_flow(self, messages, ticket_id: str): 92 | print(f'{HEADER_GREEN}') # set color 93 | self.logger.info(f" ========= Execution Flow for Ticket: {ticket_id} ========= ") 94 | for m in messages: 95 | title = get_msg_title_repr(m.type.title() + " Message") 96 | if m.name is not None: 97 | title += f"\nName: {m.name}" 98 | 99 | self.logger.info(f"{title}\n\n{m.content}") 100 | 101 | 102 | def display_image(self, image_path): 103 | ''' 104 | This functions displays an image 105 | ''' 106 | if os.path.exists(image_path): 107 | display(Image(filename=image_path)) 108 | 109 | 110 | def clean_json_string(self, json_string): 111 | ''' 112 | This functions removes decorators in llm response. 113 | Remove triple backticks and 'json' identifier 114 | ''' 115 | pattern = r'```json\n(.*?)```' 116 | cleaned_string = re.search(pattern, json_string, flags=re.DOTALL) 117 | 118 | if cleaned_string: 119 | return cleaned_string.group(1).strip() 120 | return json_string.strip() 121 | 122 | 123 | def get_image_format(self, image_path): 124 | ''' 125 | This function identifies image format by its extension 126 | ''' 127 | file_type = image_path.split('.')[-1] 128 | file_type = file_type.lower() 129 | if file_type == 'jpg': 130 | file_type = 'jpeg' 131 | 132 | return file_type 133 | 134 | 135 | def add_image_content(self, image_path: str, ticket_id: str): 136 | ''' 137 | This function reads image content and adds image data to the payload 138 | ''' 139 | 140 | self.log_data(data=f'image path ===> {image_path}', ticket_id=ticket_id) 141 | 142 | with open(image_path, 'rb') as image_file: 143 | image_bytes = image_file.read() 144 | base64_encoded = base64.b64encode(image_bytes).decode('utf-8') 145 | 146 | return { 147 | "type": "image", 148 | "source": {"type": "base64", 149 | "media_type": f"image/{self.get_image_format(image_path)}", 150 | "data": base64_encoded 151 | } 152 | } -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-10-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-10-before.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-10-updated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-10-updated.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-11-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-11-before.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-11-updated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-11-updated.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-4-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-4-before.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-4-updated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-4-updated.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-5-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-5-before.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-5-updated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-5-updated.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-6-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-6-before.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-6-updated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-6-updated.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-7-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-7-before.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-7-updated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-7-updated.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-8-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-8-before.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-8-updated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-8-updated.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-9-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-9-before.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/AS-9-updated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/AS-9-updated.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/customer-support-tech-stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/customer-support-tech-stack.png -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/customers.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "customer_id": "001", 4 | "name": "John Smith", 5 | "email": "johnsmith@gmail.com" 6 | }, 7 | { 8 | "customer_id": "002", 9 | "name": "Deepesh Dhapola", 10 | "email": "dhapola@gmail.com" 11 | } 12 | ] -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/listed-bottle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/listed-bottle.jpg -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/listed_product.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Blogs/Customer-Support/data/listed_product.jpg -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/orders.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "order_no": "ORD00009998", 4 | "order_date_time": "2025/02/10 10:40:02", 5 | "customer_id": "001", 6 | "total_amount": 59.99, 7 | "order_status": "delivery_failed", 8 | "delivery_failure_reason": "Failed. Door Locked.", 9 | "delivery_date": "2025/02/12 14:40:02", 10 | "eta": "2025/02/12 14:40:02" 11 | }, 12 | { 13 | "order_no": "ORD00009997", 14 | "order_date_time": "2025/02/11 13:15:27", 15 | "customer_id": "002", 16 | "total_amount": 79.95, 17 | "order_status": "delivered", 18 | "delivery_failure_reason": "NA", 19 | "delivery_date": "2025/02/13 11:30:00", 20 | "eta": "2025/02/13 11:30:00" 21 | }, 22 | { 23 | "order_no": "ORD00009996", 24 | "order_date_time": "2025/02/12 09:30:48", 25 | "customer_id": "001", 26 | "total_amount": 24.99, 27 | "order_status": "returned", 28 | "delivery_failure_reason": "NA", 29 | "delivery_date": "2025/02/12 09:30:48", 30 | "eta": "2025/02/14 20:30:00" 31 | }, 32 | { 33 | "order_no": "ORD00009995", 34 | "order_date_time": "2025/02/13 15:20:11", 35 | "customer_id": "002", 36 | "total_amount": 39.99, 37 | "order_status": "cancelled", 38 | "delivery_failure_reason": "NA", 39 | "delivery_date": "NA", 40 | "eta": "NA" 41 | 42 | }, 43 | { 44 | "order_no": "ORD00009994", 45 | "order_date_time": "2025/02/14 18:45:32", 46 | "customer_id": "002", 47 | "total_amount": 45.00, 48 | "order_status": "delivered", 49 | "delivery_failure_reason": "NA", 50 | "delivery_date": "2025/02/16 12:00:00", 51 | "eta": "2025/02/16 12:00:00" 52 | }, 53 | { 54 | "order_no": "ORD00009993", 55 | "order_date_time": "2025/02/15 14:25:57", 56 | "customer_id": "003", 57 | "total_amount": 69.99, 58 | "order_status": "delivery_failed", 59 | "delivery_failure_reason": "Failed. Wrong address provided", 60 | "delivery_date": "2025/02/17 16:30:00", 61 | "eta": "2025/02/17 16:30:00" 62 | }, 63 | { 64 | "order_no": "ORD00009992", 65 | "order_date_time": "2025/02/16 08:10:42", 66 | "customer_id": "001", 67 | "total_amount": 29.99, 68 | "order_status": "delivered", 69 | "delivery_failure_reason": "NA", 70 | "delivery_date": "2025/02/18 10:45:00", 71 | "eta": "2025/02/18 10:45:00" 72 | }, 73 | { 74 | "order_no": "ORD00009991", 75 | "order_date_time": "2025/02/17 17:35:19", 76 | "customer_id": "001", 77 | "total_amount": 54.99, 78 | "order_status": "processing", 79 | "delivery_failure_reason": "NA", 80 | "delivery_date": "NA", 81 | "eta": "2025/02/18 10:45:00" 82 | }, 83 | { 84 | "order_no": "ORD00009990", 85 | "order_date_time": "2025/02/18 11:50:23", 86 | "customer_id": "002", 87 | "total_amount": 89.99, 88 | "order_status": "cancelled", 89 | "delivery_failure_reason": "NA", 90 | "delivery_date": "NA", 91 | "eta": "NA" 92 | }, 93 | { 94 | "order_no": "ORD00009989", 95 | "order_date_time": "2025/02/19 13:05:06", 96 | "customer_id": "001", 97 | "total_amount": 19.99, 98 | "order_status": "delivered", 99 | "delivery_failure_reason": "NA", 100 | "delivery_date": "2025/02/21 15:20:00", 101 | "eta": "2025/02/21 10:45:00" 102 | }, 103 | { 104 | "order_no": "ORD00009988", 105 | "order_date_time": "2025/02/20 16:40:39", 106 | "customer_id": "001", 107 | "total_amount": 64.99, 108 | "order_status": "processing", 109 | "delivery_failure_reason": "NA", 110 | "delivery_date": "NA", 111 | "eta": "2025/02/25 16:00:00" 112 | }, 113 | { 114 | "order_no": "ORD00009987", 115 | "order_date_time": "2025/02/21 09:55:14", 116 | "customer_id": "002", 117 | "total_amount": 99.99, 118 | "order_status": "delivery_failed", 119 | "delivery_failure_reason": "Failed. Recipient not available", 120 | "delivery_date": "2025/02/23 13:30:00", 121 | "eta": "2025/02/23 13:30:00" 122 | }, 123 | { 124 | "order_no": "ORD00009986", 125 | "order_date_time": "2025/02/22 14:20:48", 126 | "customer_id": "001", 127 | "total_amount": 14.99, 128 | "order_status": "delivered", 129 | "delivery_failure_reason": "NA", 130 | "delivery_date": "2025/02/24 11:00:00", 131 | "eta": "2025/02/24 11:00:00" 132 | }, 133 | { 134 | "order_no": "ORD00009985", 135 | "order_date_time": "2025/02/23 19:00:31", 136 | "customer_id": "001", 137 | "total_amount": 74.99, 138 | "order_status": "delivered", 139 | "delivery_failure_reason": "NA", 140 | "delivery_date": "2025/02/25 16:45:00", 141 | "eta": "2025/02/25 16:45:00" 142 | }, 143 | { 144 | "order_no": "ORD00009984", 145 | "order_date_time": "2025/02/24 11:10:57", 146 | "customer_id": "002", 147 | "total_amount": 34.99, 148 | "order_status": "delivery_failed", 149 | "delivery_failure_reason": "Failed. Recipient refused delivery", 150 | "delivery_date": "2025/02/26 14:00:00", 151 | "eta": "2025/02/26 14:00:00" 152 | }, 153 | { 154 | "order_no": "ORD00009983", 155 | "order_date_time": "2025/02/25 15:25:42", 156 | "customer_id": "002", 157 | "total_amount": 44.99, 158 | "order_status": "delivered", 159 | "delivery_failure_reason": "NA", 160 | "delivery_date": "2025/02/27 09:30:00", 161 | "eta": "2025/02/27 09:30:00" 162 | }, 163 | { 164 | "order_no": "ORD00009982", 165 | "order_date_time": "2025/02/26 08:35:19", 166 | "customer_id": "001", 167 | "total_amount": 84.99, 168 | "order_status": "processing", 169 | "delivery_failure_reason": "NA", 170 | "delivery_date": "NA", 171 | "eta": "2025/02/28 09:30:00" 172 | }, 173 | { 174 | "order_no": "ORD00009981", 175 | "order_date_time": "2025/02/27 12:50:03", 176 | "customer_id": "002", 177 | "total_amount": 104.99, 178 | "order_status": "cancelled", 179 | "delivery_failure_reason": "NA", 180 | "delivery_date": "NA", 181 | "eta": "NA" 182 | }, 183 | { 184 | "order_no": "ORD00009980", 185 | "order_date_time": "2025/02/28 17:15:27", 186 | "customer_id": "002", 187 | "total_amount": 9.99, 188 | "order_status": "delivered", 189 | "delivery_failure_reason": "NA", 190 | "delivery_date": "2025/03/02 12:00:00", 191 | "eta": "2025/03/02 12:00:00" 192 | }, 193 | { 194 | "order_no": "ORD00009979", 195 | "order_date_time": "2025/03/01 10:25:42", 196 | "customer_id": "001", 197 | "total_amount": 94.99, 198 | "order_status": "delivered", 199 | "delivery_failure_reason": "NA", 200 | "delivery_date": "2025/03/03 14:30:00", 201 | "eta": "2025/03/03 12:00:00" 202 | } 203 | ] -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/refunds.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "customer_id": "001", 4 | "refund_transaction_id": "CD987654321EF", 5 | "transaction_id": "CD987654321EF", 6 | "order_no": "ORD00009998", 7 | "refund_transaction_date_time": "2025/03/01 12:15:27", 8 | "status": "failed", 9 | "failure_reason": "Credit Card Cancelled", 10 | "amount": 59.99, 11 | "payment_method": "Credit Card", 12 | "card_number_upi_id": "xxxx-xxxx-xxxx-5678" 13 | }, 14 | { 15 | "customer_id": "002", 16 | "refund_transaction_id": "GH567890123IJ", 17 | "transaction_id": "GH567890123IJ", 18 | "order_no": "ORD00009997", 19 | "refund_transaction_date_time": "2025/03/02 10:30:12", 20 | "status": "success", 21 | "failure_reason": "NA", 22 | "amount": 79.95, 23 | "payment_method": "Debit Card", 24 | "card_number_upi_id": "xxxx-xxxx-xxxx-9012" 25 | }, 26 | { 27 | "customer_id": "001", 28 | "refund_transaction_id": "KL345678901MN", 29 | "transaction_id": "KL345678901MN", 30 | "order_no": "ORD00009996", 31 | "refund_transaction_date_time": "2025/03/03 14:20:45", 32 | "status": "failed", 33 | "failure_reason": "UPI ID not found", 34 | "amount": 24.99, 35 | "payment_method": "UPI", 36 | "card_number_upi_id": "xxxx-xxxx-xxxx-3456" 37 | }, 38 | { 39 | "customer_id": "002", 40 | "refund_transaction_id": "OP234567890QR", 41 | "transaction_id": "OP234567890QR", 42 | "order_no": "ORD00009995", 43 | "refund_transaction_date_time": "2025/03/04 17:45:02", 44 | "status": "success", 45 | "failure_reason": "NA", 46 | "amount": 39.99, 47 | "payment_method": "Credit Card", 48 | "card_number_upi_id": "xxxx-xxxx-xxxx-7890" 49 | }, 50 | { 51 | "customer_id": "001", 52 | "refund_transaction_id": "ST123456789UV", 53 | "transaction_id": "ST123456789UV", 54 | "order_no": "ORD00009994", 55 | "refund_transaction_date_time": "2025/03/05 09:40:19", 56 | "status": "failed", 57 | "failure_reason": "Fraud Detected", 58 | "amount": 45.00, 59 | "payment_method": "UPI", 60 | "card_number_upi_id": "xxxx-xxxx-xxxx-1234" 61 | }, 62 | { 63 | "customer_id": "002", 64 | "refund_transaction_id": "WX987654321YZ", 65 | "transaction_id": "WX987654321YZ", 66 | "order_no": "ORD00009993", 67 | "refund_transaction_date_time": "2025/03/06 13:25:33", 68 | "status": "success", 69 | "failure_reason": "NA", 70 | "amount": 69.99, 71 | "payment_method": "Debit Card", 72 | "card_number_upi_id": "xxxx-xxxx-xxxx-5678" 73 | }, 74 | { 75 | "customer_id": "001", 76 | "refund_transaction_id": "AB012345678CD", 77 | "transaction_id": "AB012345678CD", 78 | "order_no": "ORD00009992", 79 | "refund_transaction_date_time": "2025/03/07 07:10:27", 80 | "status": "failed", 81 | "failure_reason": "Insufficient Funds", 82 | "amount": 29.99, 83 | "payment_method": "UPI", 84 | "card_number_upi_id": "xxxx-xxxx-xxxx-9012" 85 | }, 86 | { 87 | "customer_id": "002", 88 | "refund_transaction_id": "EF234567890GH", 89 | "transaction_id": "EF234567890GH", 90 | "order_no": "ORD00009991", 91 | "refund_transaction_date_time": "2025/03/08 16:35:04", 92 | "status": "success", 93 | "failure_reason": "NA", 94 | "amount": 54.99, 95 | "payment_method": "Credit Card", 96 | "card_number_upi_id": "xxxx-xxxx-xxxx-3456" 97 | }, 98 | { 99 | "customer_id": "001", 100 | "refund_transaction_id": "IJ456789012KL", 101 | "transaction_id": "IJ456789012KL", 102 | "order_no": "ORD00009990", 103 | "refund_transaction_date_time": "2025/03/09 10:50:09", 104 | "status": "failed", 105 | "failure_reason": "Card Expired", 106 | "amount": 89.99, 107 | "payment_method": "Debit Card", 108 | "card_number_upi_id": "xxxx-xxxx-xxxx-7890" 109 | }, 110 | { 111 | "customer_id": "002", 112 | "refund_transaction_id": "MN678901234OP", 113 | "transaction_id": "MN678901234OP", 114 | "order_no": "ORD00009989", 115 | "refund_transaction_date_time": "2025/03/10 12:05:41", 116 | "status": "success", 117 | "failure_reason": "NA", 118 | "amount": 19.99, 119 | "payment_method": "UPI", 120 | "card_number_upi_id": "xxxx-xxxx-xxxx-1234" 121 | } 122 | ] -------------------------------------------------------------------------------- /Blogs/Customer-Support/data/transactions.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "transaction_id": "CD987654321EF", 4 | "order_no": "ORD00009998", 5 | "transaction_date_time": "2025/03/01 12:15:27", 6 | "status": "success", 7 | "failure_reason": "NA", 8 | "amount": 59.99, 9 | "payment_method": "Credit Card", 10 | "card_number_upi_id": "xxxx-xxxx-xxxx-5678" 11 | }, 12 | { 13 | "transaction_id": "GH567890123IJ", 14 | "order_no": "ORD00009997", 15 | "transaction_date_time": "2025/02/28 09:30:48", 16 | "status": "failure", 17 | "failure_reason": "Payment declined by bank", 18 | "amount": 79.95, 19 | "payment_method": "Debit Card", 20 | "card_number_upi_id": "xxxx-xxxx-xxxx-9012" 21 | }, 22 | { 23 | "transaction_id": "KL345678901MN", 24 | "order_no": "ORD00009996", 25 | "transaction_date_time": "2025/02/27 15:20:11", 26 | "status": "success", 27 | "failure_reason": "NA", 28 | "amount": 24.99, 29 | "payment_method": "UPI", 30 | "card_number_upi_id": "abcd000@upi" 31 | }, 32 | { 33 | "transaction_id": "OP234567890QR", 34 | "order_no": "ORD00009995", 35 | "transaction_date_time": "2025/02/26 18:45:32", 36 | "status": "success", 37 | "failure_reason": "NA", 38 | "amount": 39.99, 39 | "payment_method": "Credit Card", 40 | "card_number_upi_id": "xxxx-xxxx-xxxx-7890" 41 | }, 42 | { 43 | "transaction_id": "ST123456789UV", 44 | "order_no": "ORD00009994", 45 | "transaction_date_time": "2025/02/25 10:40:03", 46 | "status": "success", 47 | "failure_reason": "NA", 48 | "amount": 45.00, 49 | "payment_method": "UPI", 50 | "card_number_upi_id": "1234@anybank" 51 | }, 52 | { 53 | "transaction_id": "WX987654321YZ", 54 | "order_no": "ORD00009993", 55 | "transaction_date_time": "2025/02/24 14:25:57", 56 | "status": "failure", 57 | "failure_reason": "Insufficient funds", 58 | "amount": 69.99, 59 | "payment_method": "Debit Card", 60 | "card_number_upi_id": "xxxx-xxxx-xxxx-5678" 61 | }, 62 | { 63 | "transaction_id": "AB012345678CD", 64 | "order_no": "ORD00009992", 65 | "transaction_date_time": "2025/02/23 08:10:42", 66 | "status": "success", 67 | "failure_reason": "NA", 68 | "amount": 29.99, 69 | "payment_method": "UPI", 70 | "card_number_upi_id": "0000@anyupi" 71 | }, 72 | { 73 | "transaction_id": "EF234567890GH", 74 | "order_no": "ORD00009991", 75 | "transaction_date_time": "2025/02/22 17:35:19", 76 | "status": "success", 77 | "failure_reason": "NA", 78 | "amount": 54.99, 79 | "payment_method": "Credit Card", 80 | "card_number_upi_id": "xxxx-xxxx-xxxx-3456" 81 | }, 82 | { 83 | "transaction_id": "IJ456789012KL", 84 | "order_no": "ORD00009990", 85 | "transaction_date_time": "2025/02/21 11:50:23", 86 | "status": "failure", 87 | "failure_reason": "Declined by fraud detection", 88 | "amount": 89.99, 89 | "payment_method": "Debit Card", 90 | "card_number_upi_id": "xxxx-xxxx-xxxx-7890" 91 | }, 92 | { 93 | "transaction_id": "MN678901234OP", 94 | "order_no": "ORD00009989", 95 | "transaction_date_time": "2025/02/20 13:05:06", 96 | "status": "success", 97 | "failure_reason": "NA", 98 | "amount": 19.99, 99 | "payment_method": "UPI", 100 | "card_number_upi_id": "1234@anypay" 101 | }, 102 | { 103 | "transaction_id": "QR890123456ST", 104 | "order_no": "ORD00009988", 105 | "transaction_date_time": "2025/02/19 16:40:39", 106 | "status": "success", 107 | "failure_reason": "NA", 108 | "amount": 64.99, 109 | "payment_method": "Credit Card", 110 | "card_number_upi_id": "xxxx-xxxx-xxxx-5678" 111 | }, 112 | { 113 | "transaction_id": "UV012345678WX", 114 | "order_no": "ORD00009987", 115 | "transaction_date_time": "2025/02/18 09:55:14", 116 | "status": "failure", 117 | "failure_reason": "Payment type not accepted", 118 | "amount": 99.99, 119 | "payment_method": "Debit Card", 120 | "card_number_upi_id": "xxxx-xxxx-xxxx-9012" 121 | }, 122 | { 123 | "transaction_id": "YZ234567890AB", 124 | "order_no": "ORD00009986", 125 | "transaction_date_time": "2025/02/17 14:20:48", 126 | "status": "success", 127 | "failure_reason": "NA", 128 | "amount": 14.99, 129 | "payment_method": "UPI", 130 | "card_number_upi_id": "0000@anybank" 131 | }, 132 | { 133 | "transaction_id": "CD456789012EF", 134 | "order_no": "ORD00009985", 135 | "transaction_date_time": "2025/02/16 19:00:31", 136 | "status": "success", 137 | "failure_reason": "NA", 138 | "amount": 74.99, 139 | "payment_method": "Credit Card", 140 | "card_number_upi_id": "xxxx-xxxx-xxxx-7890" 141 | }, 142 | { 143 | "transaction_id": "GH678901234IJ", 144 | "order_no": "ORD00009984", 145 | "transaction_date_time": "2025/02/15 11:10:57", 146 | "status": "failure", 147 | "failure_reason": "Incorrect payment information", 148 | "amount": 34.99, 149 | "payment_method": "Debit Card", 150 | "card_number_upi_id": "xxxx-xxxx-xxxx-1234" 151 | }, 152 | { 153 | "transaction_id": "KL890123456MN", 154 | "order_no": "ORD00009983", 155 | "transaction_date_time": "2025/02/14 15:25:42", 156 | "status": "success", 157 | "failure_reason": "NA", 158 | "amount": 44.99, 159 | "payment_method": "UPI", 160 | "card_number_upi_id": "1111@anybank" 161 | }, 162 | { 163 | "transaction_id": "OP012345678QR", 164 | "order_no": "ORD00009982", 165 | "transaction_date_time": "2025/02/13 08:35:19", 166 | "status": "success", 167 | "failure_reason": "NA", 168 | "amount": 84.99, 169 | "payment_method": "Credit Card", 170 | "card_number_upi_id": "xxxx-xxxx-xxxx-9012" 171 | }, 172 | { 173 | "transaction_id": "ST234567890UV", 174 | "order_no": "ORD00009981", 175 | "transaction_date_time": "2025/02/12 12:50:03", 176 | "status": "failure", 177 | "failure_reason": "Declined by issuer", 178 | "amount": 104.99, 179 | "payment_method": "Debit Card", 180 | "card_number_upi_id": "xxxx-xxxx-xxxx-3456" 181 | }, 182 | { 183 | "transaction_id": "WX456789012YZ", 184 | "order_no": "ORD00009980", 185 | "transaction_date_time": "2025/02/11 17:15:27", 186 | "status": "success", 187 | "failure_reason": "NA", 188 | "amount": 9.99, 189 | "payment_method": "UPI", 190 | "card_number_upi_id": "1234@anybank" 191 | }, 192 | { 193 | "transaction_id": "AB678901234CD", 194 | "order_no": "ORD00009979", 195 | "transaction_date_time": "2025/02/10 10:25:42", 196 | "status": "success", 197 | "failure_reason": "NA", 198 | "amount": 94.99, 199 | "payment_method": "Credit Card", 200 | "card_number_upi_id": "xxxx-xxxx-xxxx-1234" 201 | } 202 | 203 | 204 | ] -------------------------------------------------------------------------------- /Blogs/Customer-Support/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from cs_util import Utility 4 | from cs_db import Database 5 | from cs_cust_support_flow import CustomerSupport 6 | from cs_bedrock import BedrockClient 7 | 8 | util = Utility() 9 | bedrock_client = BedrockClient() 10 | 11 | def generate_response_for_ticket(ticket_id: str): 12 | thread = {"configurable": {"thread_id": "123456"}} 13 | 14 | llm, vision_llm, llm_with_guardrails = bedrock_client.init_llms(ticket_id=ticket_id) 15 | cust_support = CustomerSupport(llm=llm, vision_llm=vision_llm, llm_with_guardrails=llm_with_guardrails) 16 | app = cust_support.build_graph() 17 | 18 | state = cust_support.get_jira_ticket(key=ticket_id) 19 | state = app.invoke(state, thread) 20 | 21 | util.log_usage(state['usage'], ticket_id=ticket_id) 22 | util.log_execution_flow(state["messages"], ticket_id=ticket_id) 23 | 24 | 25 | def main(): 26 | db = Database() 27 | db.import_all() 28 | 29 | # create guardrails in Bedrock 30 | guardrail_id = bedrock_client.create_guardrail() 31 | 32 | # process ticket 'AS-5' - This is for refunds 33 | generate_response_for_ticket(ticket_id='AS-5') 34 | 35 | # process ticket 'AS-5' - This is for product delivery returns 36 | generate_response_for_ticket(ticket_id='AS-6') 37 | 38 | # delete guardrails 39 | bedrock_client.delete_guardrail() 40 | 41 | if __name__ == '__main__': 42 | main() -------------------------------------------------------------------------------- /Blogs/Customer-Support/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3 2 | botocore 3 | langchain 4 | langchain-community 5 | langgraph 6 | langgraph-prebuilt 7 | atlassian-python-api 8 | langchain-aws 9 | jira 10 | requests 11 | python-dotenv 12 | IPython -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /Deployment/SageMaker/imgs/image-mistral.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Deployment/SageMaker/imgs/image-mistral.webp -------------------------------------------------------------------------------- /Deployment/SageMaker/imgs/img: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Deployment/SageMaker/imgs/mistral-instruct-knowledge.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Deployment/SageMaker/imgs/mistral-instruct-knowledge.webp -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT No Attribution 2 | 3 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 13 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 15 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | -------------------------------------------------------------------------------- /MCP/MCP_Mistral_app_demo/.gradio/certificate.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw 3 | TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh 4 | cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 5 | WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu 6 | ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY 7 | MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc 8 | h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ 9 | 0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U 10 | A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW 11 | T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH 12 | B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC 13 | B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv 14 | KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn 15 | OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn 16 | jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw 17 | qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI 18 | rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV 19 | HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq 20 | hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL 21 | ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ 22 | 3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK 23 | NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 24 | ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur 25 | TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC 26 | jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc 27 | oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq 28 | 4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA 29 | mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d 30 | emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= 31 | -----END CERTIFICATE----- 32 | -------------------------------------------------------------------------------- /MCP/MCP_Mistral_app_demo/README.md: -------------------------------------------------------------------------------- 1 | # AI Assistant with Amazon Bedrock & MCP Tools 2 | 3 | This project provides a chat interface to interact with AI models from Amazon Bedrock while giving them access to external tools like Google Maps, time utilities, and memory management via the Model Context Protocol (MCP). The application supports both text and image inputs, allowing multimodal interactions with the AI models. 4 | 5 | ## Features 6 | 7 | - Chat with large language models through Amazon Bedrock 8 | - Support for both text and image inputs (multimodal capabilities) 9 | - Integration with various MCP tool servers (Google Maps, Time, Memory) 10 | - Terminal-based chat interface (chat.py) 11 | - Web-based interface using Gradio (gradio_app.py) 12 | - Automatic image processing and optimization for model compatibility 13 | 14 | ## Requirements 15 | 16 | - Python 3.9+ 17 | - AWS account with Bedrock access 18 | - Node.js (for MCP tool servers) 19 | - Required Python packages (see requirements.txt) 20 | 21 | ## Installation 22 | 23 | 1. Clone this repository: 24 | ``` 25 | git clone 26 | cd mistral-on-aws/MCP/MCP_Mistral_app_demo/ 27 | ``` 28 | 29 | 2. Install required Python packages: 30 | ``` 31 | pip install -r requirements.txt 32 | ``` 33 | 34 | 3. Configure AWS credentials: 35 | ``` 36 | aws configure 37 | ``` 38 | 39 | ## Running the Application 40 | 41 | ### Terminal-based Interface 42 | 43 | Run the terminal-based interface with: 44 | 45 | ```bash 46 | python src/chat.py 47 | ``` 48 | 49 | ### Gradio Web Interface 50 | 51 | Run the web-based interface with: 52 | 53 | ```bash 54 | python gradio_app.py 55 | ``` 56 | 57 | This will start a local web server and provide you with a URL (typically http://127.0.0.1:7860) to access the application in your browser. The application must be run from the project's root directory so that it can correctly import modules from the src directory. 58 | 59 | ## Usage 60 | 61 | 1. Start the application using one of the methods above 62 | 2. Type your queries and questions in the input field 63 | 3. Include image URLs or upload an image in Gradio app in your message to enable visual understanding 64 | 4. The AI assistant will respond and use available tools as needed 65 | 5. Type 'quit', 'exit', or 'q' to exit the application 66 | 67 | ### Image Support 68 | 69 | The application can process images from URLs or direct uploads. Simply include an image URL in your message or upload an image file, and the system will: 70 | 71 | - Automatically detect and extract the image URL or process your uploaded image file 72 | - Process and optimize the image for the AI model 73 | - Include the image in the query to the model 74 | - Support multiple image formats (JPEG, PNG, GIF, WebP) 75 | 76 | To use this feature, you can either: 77 | - Add an image URL directly in your message 78 | - Select and upload an image from your device 79 | - The system will process your image regardless of the source and incorporate it into the conversation context. 80 | 81 | ## Available Tools 82 | 83 | The application integrates with the following MCP tool servers: 84 | 85 | - **Google Maps**: For location-based queries: https://github.com/modelcontextprotocol/servers/tree/main/src/google-maps 86 | - **Time**: For time-related operations:https://github.com/yokingma/time-mcp 87 | - **Memory**: For storing and retrieving information during the conversation: https://github.com/modelcontextprotocol/servers/tree/main/src/memory 88 | 89 | ## Configuration 90 | 91 | - Tool servers are configured in the `server_configs.py` file 92 | - AWS Bedrock settings are in the `config.py` file 93 | - The web interface allows changing AWS region and model ID at runtime 94 | 95 | ## Implementation Details 96 | 97 | - Uses Amazon Bedrock's Converse API for structured conversations 98 | - Supports multimodal inputs with raw binary image data 99 | - Implements error handling for image processing and API calls 100 | - Automatically resizes large images for API compatibility 101 | 102 | ## License 103 | 104 | This project is licensed under the MIT License - see the LICENSE file for details. 105 | 106 | ## Acknowledgements 107 | 108 | - Amazon Bedrock for providing access to large language models 109 | - Model Context Protocol (MCP) for the tool integration framework 110 | - Gradio for the web interface components 111 | - This project is inspired by [ample-for-bedrock-integration-with-database-mcp-server](https://github.com/aws-samples/sample-for-bedrock-integration-with-database-mcp-server) -------------------------------------------------------------------------------- /MCP/MCP_Mistral_app_demo/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3>=1.28.0 2 | aiohttp>=3.8.0 3 | mcp>=0.1.0 4 | psutil>=5.9.0 5 | streamlit>=1.22.0 6 | nest-asyncio>=1.5.6 7 | pytz>=2023.3 8 | gradio>=4.0.0 -------------------------------------------------------------------------------- /MCP/MCP_Mistral_app_demo/src/README.md: -------------------------------------------------------------------------------- 1 | # MCP Tools Chat Application Source Code 2 | 3 | This directory contains the core components for interacting with the Model Context Protocol (MCP) tools through both command-line and web interfaces using Amazon Bedrock models. 4 | 5 | ## Core Components 6 | 7 | - **agent.py**: Handles interactions with Amazon Bedrock models, manages conversation context, and processes multimodal inputs (text and images) 8 | - **chat.py**: Provides a terminal-based interface for conversing with AI models 9 | - **config.py**: Contains configuration parameters for AWS Bedrock services 10 | - **mcpclient.py**: Client implementation for connecting to MCP servers 11 | - **server_configs.py**: Defines the available MCP server configurations 12 | - **utility.py**: Utility functions for tool management and execution 13 | 14 | ## Getting Started with the CLI Chat App 15 | 16 | The `chat.py` module provides a terminal-based interface for conversing with AI models from Amazon Bedrock with access to external tools via MCP. 17 | 18 | ### Prerequisites 19 | 20 | Before running the CLI chat application, ensure you have: 21 | 22 | 1. Python 3.9 or higher installed 23 | 2. AWS credentials configured (either via environment variables, AWS CLI configuration, or IAM role) 24 | 3. All required Python packages installed from the requirements.txt file in the parent directory 25 | 26 | ### Installation 27 | 28 | 1. Clone the repository or download the code 29 | 2. Navigate to the parent directory of this project 30 | 3. Install the required dependencies: 31 | 32 | ```bash 33 | pip install -r requirements.txt 34 | ``` 35 | 36 | ### Using chat.py 37 | 38 | To start the chat application, navigate to the parent directory and run: 39 | 40 | ```bash 41 | cd src 42 | python chat.py 43 | ``` 44 | 45 | This will launch the interactive CLI chat interface with the following features: 46 | 47 | - Terminal-based chat interface 48 | - Automatic connection to configured MCP servers 49 | - Display of available tools and their descriptions 50 | - Real-time interaction with the AI assistant 51 | - Support for image URLs in messages 52 | 53 | ### Chat Commands 54 | 55 | While in the chat session, you can use these commands: 56 | 57 | - Type your message and press Enter to send it to the AI assistant 58 | - Include image URLs in your message for visual understanding 59 | - Type `quit`, `exit`, or `q` to exit the application 60 | - Press Ctrl+C to force quit the application 61 | 62 | ## Multimodal Support 63 | 64 | The application supports multimodal interactions through: 65 | 66 | - Automatic detection of image URLs in user messages 67 | - Processing and optimization of images for compatibility with Bedrock models 68 | - Support for various image formats (JPEG, PNG, GIF, WebP) 69 | - Dynamic content handling in the conversation flow 70 | 71 | ## Configuration 72 | 73 | The application configuration is managed through: 74 | 75 | - **server_configs.py**: MCP server connections and parameters 76 | - **config.py**: AWS Bedrock settings (region and model ID) 77 | - **agent.py**: System prompts and model behavior settings 78 | 79 | ## Working with Images 80 | 81 | The `agent.py` module includes functionality to: 82 | - Detect image URLs in user input 83 | - Fetch and process images from URLs 84 | - Resize large images for API compatibility 85 | - Convert between image formats as needed 86 | - Package images correctly for the Bedrock Converse API 87 | 88 | ## Sample Questions 89 | 90 | - Q: Based on this image: https://images.pexels.com/photos/70497/pexels-photo-70497.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1, can you suggest some restaurants in London? 91 | 92 | - Q: https://images.pexels.com/photos/70497/pexels-photo-70497.jpeg What ingredients do you see in this dish? 93 | -------------------------------------------------------------------------------- /MCP/MCP_Mistral_app_demo/src/chat.py: -------------------------------------------------------------------------------- 1 | """ 2 | Interactive chat application that connects Amazon Bedrock with MCP tools. 3 | 4 | This module provides a chat interface where users can interact with AI models 5 | from Amazon Bedrock while giving the models access to external tools via 6 | the Model Context Protocol (MCP). 7 | """ 8 | import asyncio 9 | from mcp import StdioServerParameters 10 | from agent import BedrockConverseAgent 11 | from utility import UtilityHelper 12 | from mcpclient import MCPClient 13 | from datetime import datetime 14 | from server_configs import SERVER_CONFIGS 15 | from config import AWS_CONFIG 16 | 17 | # ANSI color codes for beautiful output in terminal 18 | class Colors: 19 | """ANSI color codes for terminal output formatting.""" 20 | HEADER = '\033[95m' 21 | BLUE = '\033[94m' 22 | CYAN = '\033[96m' 23 | GREEN = '\033[92m' 24 | YELLOW = '\033[93m' 25 | RED = '\033[91m' 26 | BOLD = '\033[1m' 27 | UNDERLINE = '\033[4m' 28 | END = '\033[0m' 29 | 30 | def clear_screen(): 31 | """Clear the terminal screen using ANSI escape codes.""" 32 | print('\033[2J\033[H', end='') 33 | 34 | def print_welcome(): 35 | """Print a welcome message for the chat application.""" 36 | clear_screen() 37 | print(f"{Colors.HEADER}{Colors.BOLD}Welcome to AI Assistant!{Colors.END}") 38 | print(f"{Colors.CYAN}I'm here to help you with any questions or tasks.{Colors.END}") 39 | print(f"{Colors.CYAN}Type 'quit' to exit.{Colors.END}\n") 40 | 41 | def print_tools(tools): 42 | """ 43 | Print available tools in a formatted list. 44 | 45 | Args: 46 | tools (list): List of tool specifications to display 47 | """ 48 | print(f"{Colors.CYAN}Available Tools:{Colors.END}") 49 | for tool in tools: 50 | print(f" • {Colors.GREEN}{tool['name']}{Colors.END}: {tool['description']}") 51 | print() # Add a blank line for spacing 52 | 53 | def format_message(role: str, content: str) -> str: 54 | """ 55 | Format a message with appropriate colors and timestamp. 56 | 57 | Args: 58 | role (str): Message role ('user' or 'assistant') 59 | content (str): Message content 60 | 61 | Returns: 62 | str: Formatted message with colors and timestamp 63 | """ 64 | timestamp = datetime.now().strftime("%H:%M:%S") 65 | if role == "user": 66 | return f"{Colors.BLUE}[{timestamp}] You: {Colors.END}{content}" 67 | else: 68 | return f"{Colors.GREEN}Assistant: {Colors.END}{content}" 69 | 70 | async def handle_resource_update(uri: str): 71 | """ 72 | Handle updates to resources from the MCP server. 73 | 74 | Args: 75 | uri (str): URI of the updated resource 76 | """ 77 | print(f"{Colors.YELLOW}Resource updated: {uri}{Colors.END}") 78 | 79 | async def main(): 80 | """ 81 | Main function that sets up and runs an interactive AI agent with tool integration. 82 | 83 | This function: 84 | 1. Initializes the Bedrock agent with a specified model 85 | 2. Sets up the system prompt for the agent 86 | 3. Connects to MCP servers and registers available tools 87 | 4. Runs an interactive chat loop to handle user input 88 | 5. Ensures proper cleanup of resources 89 | 90 | Returns: 91 | None 92 | """ 93 | # Initialize model configuration from config.py 94 | model_id = AWS_CONFIG["model_id"] 95 | region = AWS_CONFIG["region"] 96 | 97 | # Set up the agent and tool manager 98 | agent = BedrockConverseAgent(model_id, region) 99 | agent.tools = UtilityHelper() 100 | 101 | # Define the agent's behavior through system prompt 102 | agent.system_prompt = """ 103 | You are a helpful assistant that can use tools to help you answer questions and perform tasks. 104 | Please remember and save user's preferences into memory based on user questions and conversations. 105 | """ 106 | # Import server configs 107 | server_configs = SERVER_CONFIGS 108 | 109 | # Function to handle connection to a single MCP server 110 | async def setup_mcp_client(server_param): 111 | """Set up connection to an MCP server and register its tools.""" 112 | try: 113 | mcp_client = MCPClient(server_param) 114 | await mcp_client.__aenter__() # manually enter async context 115 | tools = await mcp_client.get_available_tools() 116 | 117 | for tool in tools: 118 | agent.tools.register_tool( 119 | name=tool['name'], 120 | func=mcp_client.call_tool, 121 | description=tool['description'], 122 | input_schema={'json': tool['inputSchema']} 123 | ) 124 | 125 | return mcp_client 126 | except Exception as e: 127 | print(f"Error setting up MCP client: {e}") 128 | return None 129 | 130 | # Start all MCP clients and register their tools 131 | mcp_clients = await asyncio.gather(*(setup_mcp_client(cfg) for cfg in server_configs)) 132 | 133 | # Filter out any None values from failed client setups 134 | mcp_clients = [client for client in mcp_clients if client is not None] 135 | 136 | # Display welcome message and available tools 137 | print_welcome() 138 | tools = [tool['toolSpec'] for tool in agent.tools.get_tools()['tools']] 139 | print_tools(tools) 140 | 141 | # Run interactive chat loop 142 | try: 143 | while True: 144 | user_prompt = input(f"\n{Colors.BOLD}User: {Colors.END}") 145 | if user_prompt.lower() in ['quit', 'exit', 'q']: 146 | print(f"\n{Colors.CYAN}Goodbye! Thanks for chatting!{Colors.END}") 147 | 148 | # Force immediate termination when user quits 149 | import os 150 | os._exit(0) 151 | 152 | if not user_prompt.strip(): 153 | continue 154 | 155 | print(f"\n{Colors.YELLOW}Thinking...{Colors.END}") 156 | response = await agent.invoke_with_prompt(user_prompt) 157 | 158 | # By default, use the standard response 159 | display_response = response 160 | 161 | 162 | print(f"\n{format_message('assistant', display_response)}") 163 | except KeyboardInterrupt: 164 | print(f"\n{Colors.CYAN}Goodbye! Thanks for chatting!{Colors.END}") 165 | 166 | # Force immediate termination on keyboard interrupt 167 | import os 168 | os._exit(0) 169 | 170 | 171 | if __name__ == "__main__": 172 | """ 173 | Application entry point. 174 | 175 | When run as a script, this initializes and runs the chat application 176 | using the asyncio event loop. 177 | """ 178 | try: 179 | # Patch the asyncio run function to suppress unhandled exceptions during shutdown 180 | original_run = asyncio.run 181 | 182 | def patched_run(main_func, **kwargs): 183 | try: 184 | return original_run(main_func, **kwargs) 185 | finally: 186 | # Force immediate exit on shutdown to avoid any cleanup errors 187 | import os 188 | import signal 189 | os._exit(0) # Use os._exit to force immediate termination 190 | 191 | # Replace asyncio.run with our patched version 192 | asyncio.run = patched_run 193 | 194 | # Run the application 195 | asyncio.run(main(), debug=False) 196 | except KeyboardInterrupt: 197 | print("\nApplication terminated by user.") 198 | except Exception as e: 199 | print(f"Application error: {e}") 200 | finally: 201 | # Just in case our patched asyncio.run didn't terminate 202 | import os 203 | os._exit(0) -------------------------------------------------------------------------------- /MCP/MCP_Mistral_app_demo/src/config.py: -------------------------------------------------------------------------------- 1 | """ 2 | Configuration module for the MCP application. 3 | 4 | This module stores configuration parameters for the application, such as 5 | AWS region and model ID for Amazon Bedrock service. 6 | """ 7 | 8 | AWS_CONFIG = { 9 | "region": "eu-central-1", # Provide AWS region 10 | "model_id": "eu.mistral.pixtral-large-2502-v1:0" # Provide model ID: eu.mistral.pixtral-large-2502-v1:0 11 | } -------------------------------------------------------------------------------- /MCP/MCP_Mistral_app_demo/src/mcpclient.py: -------------------------------------------------------------------------------- 1 | """ 2 | Model Context Protocol (MCP) client implementation module. 3 | 4 | Provides a wrapper around the MCP client functionality for connecting to 5 | and communicating with MCP tool servers. 6 | """ 7 | from mcp import ClientSession, StdioServerParameters 8 | from mcp.client.stdio import stdio_client 9 | import json 10 | import time 11 | 12 | class MCPClient: 13 | """ 14 | Model Context Protocol (MCP) client implementation. 15 | Handles connection and interaction with MCP server for tool management 16 | and execution. 17 | """ 18 | def __init__(self, server_params: StdioServerParameters): 19 | """ 20 | Initialize the MCP client with server parameters. 21 | 22 | Args: 23 | server_params (StdioServerParameters): Configuration for the MCP server 24 | """ 25 | self.read = None # Stream reader 26 | self.write = None # Stream writer 27 | self.server_params = server_params # Server configuration 28 | self.session = None # MCP session 29 | self._client = None # Internal client instance 30 | 31 | 32 | async def __aenter__(self): 33 | """Async context manager entry point. Establishes connection.""" 34 | await self.connect() 35 | return self 36 | 37 | async def __aexit__(self, exc_type, exc_val, exc_tb): 38 | """ 39 | Async context manager exit. Ensures proper cleanup of resources. 40 | Handles both session and client cleanup. 41 | """ 42 | await self.cleanup() 43 | 44 | async def cleanup(self): 45 | """ 46 | Clean up resources safely in a way that avoids cancel scope issues. 47 | 48 | This bypasses the asyncio scope checking by directly closing resources 49 | without going through the __aexit__ methods. 50 | """ 51 | self.session = None 52 | self._client = None 53 | self.read = None 54 | self.write = None 55 | 56 | async def connect(self): 57 | """ 58 | Establishes connection to MCP server. 59 | Sets up stdio client, initializes read/write streams, 60 | and creates client session. 61 | """ 62 | # Initialize stdio client with server parameters 63 | self._client = stdio_client(self.server_params) 64 | 65 | # Get read/write streams 66 | self.read, self.write = await self._client.__aenter__() 67 | 68 | # Create and initialize session 69 | session = ClientSession(self.read, self.write) 70 | self.session = await session.__aenter__() 71 | await self.session.initialize() 72 | 73 | async def get_available_tools(self): 74 | """ 75 | List available tools from the MCP server. 76 | 77 | Returns: 78 | list: List of formatted tool specifications compatible with Bedrock 79 | 80 | Raises: 81 | RuntimeError: If not connected to MCP server 82 | """ 83 | if not self.session: 84 | raise RuntimeError("Not connected to MCP server") 85 | 86 | response = await self.session.list_tools() 87 | 88 | # Extract the actual tools from the response 89 | tools = response.tools if hasattr(response, 'tools') else [] 90 | 91 | # Convert tools to list of dictionaries with expected attributes 92 | formatted_tools = [ 93 | { 94 | 'name': tool.name, 95 | 'description': str(tool.description) if tool.description is not None else "No description available", 96 | 'inputSchema': { 97 | 'json': { 98 | 'type': 'object', # Explicitly setting type as 'object' as required by the API 99 | 'properties': tool.inputSchema.get('properties', {}) if tool.inputSchema else {}, 100 | 'required': tool.inputSchema.get('required', []) if tool.inputSchema else [] 101 | } 102 | } 103 | } 104 | for tool in tools 105 | ] 106 | return formatted_tools 107 | 108 | async def call_tool(self, tool_name, arguments): 109 | """ 110 | Executes a specific tool with provided arguments. 111 | 112 | Args: 113 | tool_name (str): Name of the tool to execute 114 | arguments (dict): Tool-specific arguments 115 | 116 | Returns: 117 | dict: Tool execution results with server info 118 | 119 | Raises: 120 | RuntimeError: If not connected to MCP server 121 | """ 122 | # Verify session exists 123 | if not self.session: 124 | raise RuntimeError("Not connected to the MCP Server") 125 | 126 | # Get server info from server_params 127 | server_info = { 128 | "command": self.server_params.command, 129 | "args": self.server_params.args if hasattr(self.server_params, "args") else [] 130 | } 131 | 132 | # Get a server name to display 133 | if server_info["command"] == "npx": 134 | server_name = server_info["args"][0] if len(server_info["args"]) > 0 else "Unknown NPX Tool" 135 | if server_name.startswith("-y"): 136 | server_name = server_info["args"][1] if len(server_info["args"]) > 1 else "Unknown NPX Tool" 137 | else: 138 | server_name = server_info["command"] 139 | 140 | # Execute tool 141 | start_time = time.time() 142 | result = await self.session.call_tool(tool_name, arguments=arguments) 143 | execution_time = time.time() - start_time 144 | 145 | # Augment result with server info 146 | return { 147 | "result": result, 148 | "tool_info": { 149 | "tool_name": tool_name, 150 | "server_name": server_name, 151 | "server_info": server_info, 152 | "execution_time": f"{execution_time:.2f}s" 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /MCP/MCP_Mistral_app_demo/src/server_configs.py: -------------------------------------------------------------------------------- 1 | from mcp import StdioServerParameters 2 | SERVER_CONFIGS = [ 3 | StdioServerParameters( 4 | command="npx", 5 | args=["-y", "@modelcontextprotocol/server-google-maps"], 6 | env={"GOOGLE_MAPS_API_KEY": ""} 7 | ), 8 | StdioServerParameters( 9 | command="npx", 10 | args=["-y", "time-mcp"], 11 | ), 12 | StdioServerParameters( 13 | command="npx", 14 | args=["@modelcontextprotocol/server-memory"] 15 | ) 16 | ] -------------------------------------------------------------------------------- /MCP/MCP_Mistral_app_demo/src/utility.py: -------------------------------------------------------------------------------- 1 | """ 2 | Utility module for managing external tools integration with Amazon Bedrock. 3 | Provides functionality for tool registration, execution, and compatibility with Bedrock's requirements. 4 | """ 5 | import json 6 | 7 | 8 | class UtilityHelper: 9 | """ 10 | Manages the integration of external tools with Amazon Bedrock. 11 | 12 | This class handles: 13 | - Tool registration and name normalization 14 | - Tool specification generation for Bedrock API 15 | - Tool execution and error handling 16 | """ 17 | def __init__(self): 18 | """Initialize the tool registry.""" 19 | self._tools = {} 20 | self._name_mapping = {} 21 | 22 | @staticmethod 23 | def _correct_name(name): 24 | """ 25 | Convert tool names to Bedrock-compatible format. 26 | 27 | Args: 28 | name (str): Original tool name 29 | 30 | Returns: 31 | str: Normalized tool name with hyphens replaced by underscores 32 | """ 33 | return name.replace("-", "_") 34 | 35 | def register_tool(self, name, func, description, input_schema): 36 | """ 37 | Register a new tool with the system. 38 | 39 | Args: 40 | name (str): Original name of the tool 41 | func (callable): Async function that implements the tool 42 | description (str): Tool description for AI model 43 | input_schema (dict): JSON schema describing tool's input parameters 44 | """ 45 | corrected_name = UtilityHelper._correct_name(name) 46 | self._name_mapping[corrected_name] = name 47 | self._tools[corrected_name] = { 48 | "function": func, 49 | "description": description, 50 | "input_schema": input_schema, 51 | "original_name": name, 52 | } 53 | 54 | def get_tools(self): 55 | """ 56 | Generate tool specifications for Bedrock API. 57 | 58 | Returns: 59 | dict: Tool configurations in the format expected by Bedrock 60 | """ 61 | tool_specs = [] 62 | for corrected_name, tool in self._tools.items(): 63 | # Ensure the inputSchema.json.type is explicitly set to 'object' as required by the API 64 | input_schema = tool["input_schema"].copy() 65 | if 'json' in input_schema and 'type' not in input_schema['json']: 66 | input_schema['json']['type'] = 'object' 67 | 68 | tool_specs.append( 69 | { 70 | "toolSpec": { 71 | "name": corrected_name, 72 | "description": tool["description"], 73 | "inputSchema": input_schema, 74 | } 75 | } 76 | ) 77 | 78 | return {"tools": tool_specs} 79 | 80 | async def execute_tool(self, payload): 81 | """ 82 | Execute a tool based on the model's request. 83 | 84 | Args: 85 | payload (dict): Tool execution request with toolUseId, name, and input 86 | 87 | Returns: 88 | dict: Tool execution result with status and content 89 | 90 | Raises: 91 | ValueError: If the requested tool is not found 92 | """ 93 | tool_use_id = payload["toolUseId"] 94 | corrected_name = payload["name"] 95 | tool_input = payload["input"] 96 | 97 | if corrected_name not in self._tools: 98 | raise ValueError(f"Unknown tool {corrected_name} not found") 99 | 100 | try: 101 | tool_func = self._tools[corrected_name]["function"] 102 | original_name = self._tools[corrected_name]["original_name"] 103 | 104 | # Track tool usage for UI display if callback is set 105 | if hasattr(self, 'tool_usage_callback') and self.tool_usage_callback: 106 | # Notify about tool invocation 107 | self.tool_usage_callback({ 108 | "event": "tool_start", 109 | "tool_name": original_name, 110 | "input": tool_input 111 | }) 112 | 113 | # Execute the tool 114 | result_data = await tool_func(original_name, tool_input) 115 | 116 | # Extract the actual result and tool info 117 | if isinstance(result_data, dict) and "result" in result_data and "tool_info" in result_data: 118 | result = result_data["result"] 119 | tool_info = result_data["tool_info"] 120 | 121 | # Notify about tool completion if callback exists 122 | if hasattr(self, 'tool_usage_callback') and self.tool_usage_callback: 123 | self.tool_usage_callback({ 124 | "event": "tool_complete", 125 | "tool_name": original_name, 126 | "tool_info": tool_info, 127 | "status": "success" 128 | }) 129 | else: 130 | # Handle legacy format 131 | result = result_data 132 | tool_info = {"tool_name": original_name} 133 | 134 | return { 135 | "toolUseId": tool_use_id, 136 | "content": [{"text": str(result)}], 137 | "status": "success", 138 | } 139 | 140 | except Exception as e: 141 | # Notify about tool error if callback exists 142 | if hasattr(self, 'tool_usage_callback') and self.tool_usage_callback: 143 | self.tool_usage_callback({ 144 | "event": "tool_error", 145 | "tool_name": original_name, 146 | "error": str(e) 147 | }) 148 | 149 | return { 150 | "toolUseId": tool_use_id, 151 | "content": [{"text": f"Error executing tool: {str(e)}"}], 152 | "status": "error", 153 | } 154 | 155 | def register_tool_usage_callback(self, callback): 156 | """ 157 | Register a callback function to be called whenever a tool is used. 158 | 159 | Args: 160 | callback (callable): Function to call with tool usage information 161 | """ 162 | self.tool_usage_callback = callback 163 | 164 | def clear_tools(self): 165 | """Remove all registered tools.""" 166 | self._tools.clear() 167 | self._name_mapping.clear() 168 | -------------------------------------------------------------------------------- /MCP/MCP_Mistral_app_demo_with_Strands/README.md: -------------------------------------------------------------------------------- 1 | # MCP Chat App with Mistral on Amazon Bedrock, Strands Agents & MCP Tools 2 | 3 | This application provides both command-line and web-based chat interfaces for interacting with AI models from Amazon Bedrock while giving the models access to external tools via the Model Context Protocol (MCP). 4 | 5 | ## Features 6 | 7 | - 🤖 **AI Chat Interface**: Interactive chat with Mistral models on Amazon Bedrock 8 | - 🛠️ **MCP Tools Integration**: Access to Google Maps, time utilities, and knowledge graph tools 9 | - 📷 **Image Upload**: Upload and analyze images with multimodal AI capabilities (Gradio only) 10 | - 🌐 **Web Interface**: Clean, modern Gradio-based web UI 11 | - ⌨️ **Command Line**: Traditional terminal-based chat interface 12 | - 📱 **Real-time Tool Access**: AI can use external tools to answer questions 13 | - ⚙️ **Configuration Management**: Easy configuration via config files 14 | 15 | ## Available Tools 16 | 17 | The application integrates with the following MCP tool servers: 18 | 19 | - **Google Maps**: For location-based queries: https://github.com/modelcontextprotocol/servers/tree/main/src/google-maps 20 | - **Time**: For time-related operations:https://github.com/yokingma/time-mcp 21 | - **Memory**: For storing and retrieving information during the conversation: https://github.com/modelcontextprotocol/servers/tree/main/src/memory 22 | 23 | 24 | ## Prerequisites 25 | 26 | ### Required Environment Variables 27 | ```bash 28 | # IMPORTANT: Export AWS region before running 29 | export AWS_REGION= 30 | 31 | # Optional: AWS credentials (if not using default profile) 32 | export AWS_ACCESS_KEY_ID=your_access_key 33 | export AWS_SECRET_ACCESS_KEY=your_secret_key 34 | ``` 35 | 36 | ### Required Dependencies 37 | - Python 3.10+ 38 | - Node.js and npm (for MCP servers) 39 | - AWS credentials configured for Bedrock access 40 | - Google Maps API key (for maps functionality) 41 | 42 | ### Install Python Packages 43 | ```bash 44 | pip install -r requirements.txt 45 | ``` 46 | 47 | ## Configuration 48 | 49 | - Tool servers are configured in the `server_configs.py` file 50 | - AWS Bedrock settings are in the `config.py` file 51 | 52 | ## Usage 53 | 54 | ### Web Interface (Gradio) 55 | 56 | 1. **Set environment variables:** 57 | ```bash 58 | export AWS_REGION=> 59 | ``` 60 | 61 | 2. **Start the web application:** 62 | ```bash 63 | python gradio_app.py 64 | ``` 65 | 66 | 3. **Access the interface:** 67 | - **Local**: http://localhost:7860 68 | - **Public URL**: A shareable link will be provided in the console 69 | 70 | 4. **Features:** 71 | - Type messages in the text box 72 | - Upload images by clicking the image upload area 73 | - Press Enter or click "Send" to submit 74 | - View available tools in the "Available Tools" tab 75 | - Check current configuration in the "Configuration" tab 76 | - Clear chat history with the "Clear Chat" button 77 | 78 | ### Command Line Interface 79 | 80 | 1. **Set environment variables:** 81 | ```bash 82 | export AWS_REGION= 83 | ``` 84 | 85 | 2. **Start the command line chat:** 86 | ```bash 87 | python chat.py 88 | ``` 89 | 90 | 3. **Usage:** 91 | - Type your messages and press Enter 92 | - Type 'quit', 'exit', or 'q' to exit 93 | - The AI can use tools automatically based on your questions 94 | 95 | 96 | ## Architecture 97 | 98 | The application uses the following architecture: 99 | 100 | 1. **Agent Initialization**: Creates `BedrockModel` and `Agent` from the `strands` library 101 | 2. **MCP Client Setup**: Connects to multiple MCP servers using `ExitStack` 102 | 3. **Tool Registration**: Loads and registers tools from all MCP clients 103 | 4. **Message Processing**: Handles both text and image inputs 104 | 5. **Response Generation**: Processes agent responses and extracts text content 105 | 106 | 107 | ## License 108 | 109 | This project is licensed under the MIT License - see the LICENSE file for details. 110 | 111 | ## Acknowledgements 112 | 113 | - Amazon Bedrock for providing access to large language models 114 | - Model Context Protocol (MCP) for the tool integration framework 115 | - Gradio for the web interface components 116 | - Strands Agents: https://github.com/strands-agents -------------------------------------------------------------------------------- /MCP/MCP_Mistral_app_demo_with_Strands/chat.py: -------------------------------------------------------------------------------- 1 | """ 2 | Interactive chat application that connects Amazon Bedrock with MCP tools. 3 | 4 | This module provides a chat interface where users can interact with AI models 5 | from Amazon Bedrock while giving the models access to external tools via 6 | the Model Context Protocol (MCP). 7 | """ 8 | import asyncio 9 | from strands import Agent 10 | from strands.tools.mcp import MCPClient 11 | from strands.models import BedrockModel 12 | from mcp import stdio_client, StdioServerParameters 13 | from datetime import datetime 14 | from server_configs import SERVER_CONFIGS 15 | from config import AWS_CONFIG 16 | from contextlib import ExitStack 17 | 18 | 19 | # ANSI color codes for beautiful output in terminal 20 | class Colors: 21 | """ANSI color codes for terminal output formatting.""" 22 | HEADER = '\033[95m' 23 | BLUE = '\033[94m' 24 | CYAN = '\033[96m' 25 | GREEN = '\033[92m' 26 | YELLOW = '\033[93m' 27 | RED = '\033[91m' 28 | BOLD = '\033[1m' 29 | UNDERLINE = '\033[4m' 30 | END = '\033[0m' 31 | 32 | def clear_screen(): 33 | """Clear the terminal screen using ANSI escape codes.""" 34 | print('\033[2J\033[H', end='') 35 | 36 | def print_welcome(): 37 | """Print a welcome message for the chat application.""" 38 | clear_screen() 39 | print(f"{Colors.HEADER}{Colors.BOLD}Welcome to AI Assistant!{Colors.END}") 40 | print(f"{Colors.CYAN}I'm here to help you with any questions or tasks.{Colors.END}") 41 | print(f"{Colors.CYAN}Type 'quit' to exit.{Colors.END}\n") 42 | 43 | def print_tools(tools): 44 | """ 45 | Print available tools in a formatted list. 46 | 47 | Args: 48 | tools (list): List of MCPAgentTool objects to display 49 | """ 50 | print(f"{Colors.CYAN}Available Tools:{Colors.END}") 51 | for tool in tools: 52 | # Access properties through the tool's methods/attributes 53 | tool_spec = tool.tool_spec # This returns the ToolSpec dictionary 54 | print(f" • {Colors.GREEN}{tool_spec['name']}{Colors.END}: {tool_spec['description']}") 55 | print() 56 | 57 | def format_message(role: str, content: str) -> str: 58 | """ 59 | Format a message with appropriate colors and timestamp. 60 | 61 | Args: 62 | role (str): Message role ('user' or 'assistant') 63 | content (str): Message content 64 | 65 | Returns: 66 | str: Formatted message with colors and timestamp 67 | """ 68 | timestamp = datetime.now().strftime("%H:%M:%S") 69 | if role == "user": 70 | return f"{Colors.BLUE}[{timestamp}] You: {Colors.END}{content}" 71 | else: 72 | return f"{Colors.GREEN}Assistant: {Colors.END}{content}" 73 | 74 | async def handle_resource_update(uri: str): 75 | """ 76 | Handle updates to resources from the MCP server. 77 | 78 | Args: 79 | uri (str): URI of the updated resource 80 | """ 81 | print(f"{Colors.YELLOW}Resource updated: {uri}{Colors.END}") 82 | 83 | async def main(): 84 | """ 85 | Main function that sets up and runs an interactive AI agent with tool integration. 86 | 87 | This function: 88 | 1. Initializes the Bedrock agent with a specified model 89 | 2. Sets up the system prompt for the agent 90 | 3. Connects to MCP servers and registers available tools 91 | 4. Runs an interactive chat loop to handle user input 92 | 5. Ensures proper cleanup of resources 93 | 94 | Returns: 95 | None 96 | """ 97 | # Initialize model configuration from config.py 98 | model_id = AWS_CONFIG["model_id"] 99 | 100 | bedrock_model = BedrockModel( 101 | model_id=model_id, 102 | streaming=False 103 | ) 104 | # Define the agent's behavior through system prompt 105 | system_prompt = """ 106 | You are a helpful assistant that can use tools to help you answer questions and perform tasks. 107 | Please remember and save user's preferences into memory based on user questions and conversations. 108 | """ 109 | # Import server configs 110 | server_configs = SERVER_CONFIGS 111 | mcp_clients = [ 112 | MCPClient(lambda cfg=server_config: stdio_client(cfg)) 113 | for server_config in server_configs 114 | ] 115 | 116 | with ExitStack() as stack: 117 | # Enter all MCP clients and keep them active 118 | for mcp_client in mcp_clients: 119 | stack.enter_context(mcp_client) 120 | 121 | # Get tools from all clients 122 | tools = [] 123 | for i, mcp_client in enumerate(mcp_clients): 124 | try: 125 | client_tools = mcp_client.list_tools_sync() 126 | tools.extend(client_tools) 127 | print(f"Loaded {len(client_tools)} tools from client {i+1}") 128 | except Exception as e: 129 | print(f"Error getting tools from MCP client {i+1}: {e}") 130 | 131 | try: 132 | agent = Agent(model=bedrock_model, tools=tools,system_prompt=system_prompt) 133 | except Exception as e: 134 | print(f"{Colors.RED}[ERROR] Failed to create agent: {e}{Colors.END}") 135 | import traceback 136 | traceback.print_exc() 137 | return 138 | 139 | # Display welcome message and available tools 140 | print_welcome() 141 | print_tools(tools) 142 | 143 | # Run interactive chat loop 144 | try: 145 | while True: 146 | user_prompt = input(f"\n{Colors.BOLD}User: {Colors.END}") 147 | if user_prompt.lower() in ['quit', 'exit', 'q']: 148 | print(f"\n{Colors.CYAN}Goodbye! Thanks for chatting!{Colors.END}") 149 | 150 | # Force immediate termination when user quits 151 | import os 152 | os._exit(0) 153 | 154 | # if not user_prompt.strip(): 155 | # continuemy 156 | 157 | print(f"\n{Colors.YELLOW}Thinking...{Colors.END}") 158 | try: 159 | response = agent(user_prompt) 160 | except Exception as e: 161 | print(f"{Colors.RED}[ERROR] Agent call failed: {e}{Colors.END}") 162 | import traceback 163 | traceback.print_exc() 164 | continue 165 | 166 | # Extract the text content from the agent result 167 | if hasattr(response, 'text'): 168 | display_response = response.text 169 | elif hasattr(response, 'content'): 170 | display_response = response.content 171 | else: 172 | # Fallback to string representation 173 | display_response = str(response) 174 | 175 | print(f"\n{format_message('assistant', display_response)}") 176 | except KeyboardInterrupt: 177 | print(f"\n{Colors.CYAN}Goodbye! Thanks for chatting!{Colors.END}") 178 | 179 | # Force immediate termination on keyboard interrupt 180 | import os 181 | os._exit(0) 182 | 183 | 184 | if __name__ == "__main__": 185 | """ 186 | Application entry point. 187 | 188 | When run as a script, this initializes and runs the chat application 189 | using the asyncio event loop. 190 | """ 191 | try: 192 | # Patch the asyncio run function to suppress unhandled exceptions during shutdown 193 | original_run = asyncio.run 194 | 195 | def patched_run(main_func, **kwargs): 196 | try: 197 | return original_run(main_func, **kwargs) 198 | finally: 199 | # Force immediate exit on shutdown to avoid any cleanup errors 200 | import os 201 | import signal 202 | os._exit(0) # Use os._exit to force immediate termination 203 | 204 | # Replace asyncio.run with our patched version 205 | asyncio.run = patched_run 206 | 207 | # Run the application 208 | asyncio.run(main(), debug=False) 209 | except KeyboardInterrupt: 210 | print("\nApplication terminated by user.") 211 | except Exception as e: 212 | print(f"Application error: {e}") 213 | finally: 214 | # Just in case our patched asyncio.run didn't terminate 215 | import os 216 | os._exit(0) -------------------------------------------------------------------------------- /MCP/MCP_Mistral_app_demo_with_Strands/config.py: -------------------------------------------------------------------------------- 1 | """ 2 | Configuration module for the MCP application. 3 | 4 | This module stores configuration parameters for the application, such as 5 | AWS region and model ID for Amazon Bedrock service. 6 | """ 7 | 8 | AWS_CONFIG = { 9 | "region": "us-west-2", # Provide AWS region 10 | "model_id": "us.mistral.pixtral-large-2502-v1:0" # Provide model ID: us.mistral.pixtral-large-2502-v1:0 11 | } -------------------------------------------------------------------------------- /MCP/MCP_Mistral_app_demo_with_Strands/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3>=1.28.0 2 | aiohttp>=3.8.0 3 | mcp>=0.1.0 4 | psutil>=5.9.0 5 | streamlit>=1.22.0 6 | nest-asyncio>=1.5.6 7 | pytz>=2023.3 8 | gradio>=4.0.0 9 | strands-agents>=0.1.6 10 | strands-agents-tools>=0.1.4 -------------------------------------------------------------------------------- /MCP/MCP_Mistral_app_demo_with_Strands/server_configs.py: -------------------------------------------------------------------------------- 1 | from mcp import StdioServerParameters 2 | SERVER_CONFIGS = [ 3 | StdioServerParameters( 4 | command="npx", 5 | args=["-y", "@modelcontextprotocol/server-google-maps"], 6 | env={"GOOGLE_MAPS_API_KEY": ""} 7 | ), 8 | StdioServerParameters( 9 | command="npx", 10 | args=["-y", "time-mcp"], 11 | ), 12 | StdioServerParameters( 13 | command="npx", 14 | args=["@modelcontextprotocol/server-memory"] 15 | ) 16 | 17 | ] 18 | -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral Large (25.02)/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | test/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | cover/ 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | local_settings.py 62 | db.sqlite3 63 | db.sqlite3-journal 64 | 65 | # Flask stuff: 66 | instance/ 67 | .webassets-cache 68 | 69 | # Scrapy stuff: 70 | .scrapy 71 | 72 | # Sphinx documentation 73 | docs/_build/ 74 | 75 | # PyBuilder 76 | .pybuilder/ 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # IPython 83 | profile_default/ 84 | ipython_config.py 85 | 86 | # pyenv 87 | # For a library or package, you might want to ignore these files since the code is 88 | # intended to run in multiple environments; otherwise, check them in: 89 | # .python-version 90 | 91 | # pipenv 92 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 93 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 94 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 95 | # install all needed dependencies. 96 | #Pipfile.lock 97 | 98 | # UV 99 | # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. 100 | # This is especially recommended for binary packages to ensure reproducibility, and is more 101 | # commonly ignored for libraries. 102 | #uv.lock 103 | 104 | # poetry 105 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 106 | # This is especially recommended for binary packages to ensure reproducibility, and is more 107 | # commonly ignored for libraries. 108 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 109 | #poetry.lock 110 | 111 | # pdm 112 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 113 | #pdm.lock 114 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 115 | # in version control. 116 | # https://pdm.fming.dev/latest/usage/project/#working-with-version-control 117 | .pdm.toml 118 | .pdm-python 119 | .pdm-build/ 120 | 121 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 122 | __pypackages__/ 123 | 124 | # Celery stuff 125 | celerybeat-schedule 126 | celerybeat.pid 127 | 128 | # SageMath parsed files 129 | *.sage.py 130 | 131 | # Environments 132 | .env 133 | .venv 134 | env/ 135 | venv/ 136 | ENV/ 137 | env.bak/ 138 | venv.bak/ 139 | 140 | # Spyder project settings 141 | .spyderproject 142 | .spyproject 143 | 144 | # Rope project settings 145 | .ropeproject 146 | 147 | # mkdocs documentation 148 | /site 149 | 150 | # mypy 151 | .mypy_cache/ 152 | .dmypy.json 153 | dmypy.json 154 | 155 | # Pyre type checker 156 | .pyre/ 157 | 158 | # pytype static type analyzer 159 | .pytype/ 160 | 161 | # Cython debug symbols 162 | cython_debug/ 163 | 164 | # PyCharm 165 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 166 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 167 | # and can be added to the global gitignore or merged into this file. For a more nuclear 168 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 169 | #.idea/ 170 | 171 | # Ruff stuff: 172 | .ruff_cache/ 173 | 174 | # PyPI configuration file 175 | .pypirc 176 | -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral Large (25.02)/README.md: -------------------------------------------------------------------------------- 1 | # Math Problem Assistant with Pixtral Large on AWS 2 | 3 | This demo showcases a Math Problem Assistant powered by the Pixtral Large model on AWS Bedrock. The application helps students understand and solve math problems by analyzing images of math questions and providing step-by-step guidance. 4 | 5 | ## Prerequisites 6 | 7 | - Python 3.11 or later 8 | - AWS account with access to Bedrock service 9 | - AWS credentials configured locally 10 | - Access to the Mistral Pixtral Large model on AWS Bedrock 11 | 12 | ## Quick Start 13 | 14 | 1. Create and activate a virtual environment: 15 | ```bash 16 | python3 -m venv .venv 17 | source .venv/bin/activate # On Windows, use: .venv\Scripts\activate 18 | ``` 19 | 20 | 2. Install dependencies: 21 | ```bash 22 | pip install -r requirements.txt 23 | ``` 24 | 25 | 3. Set up your AWS credentials: 26 | - Create a `.env` file in the project directory 27 | - Add your AWS configuration: 28 | ``` 29 | AWS_ACCESS_KEY_ID=your_access_key 30 | AWS_SECRET_ACCESS_KEY=your_secret_key 31 | AWS_DEFAULT_REGION=your_region 32 | ``` 33 | 34 | 4. Run the application: 35 | ```bash 36 | streamlit run app.py 37 | ``` 38 | 39 | 5. Open your browser and navigate to http://localhost:8501 40 | 41 | ## Usage 42 | 43 | 1. Click the "Try Demo" button to test the app with a pre-loaded vector geometry problem, or 44 | 2. Enter the URL of any math problem image in the input field 45 | 3. The app will analyze the image and provide: 46 | - A simple explanation of what the problem is asking 47 | - Identification of key mathematical concepts 48 | - Step-by-step guidance for solving the problem 49 | - Hints for challenging aspects 50 | 4. Use the chat interface for follow-up questions about the problem 51 | 52 | ## Notes 53 | 54 | - The app uses LaTeX for mathematical notation, rendered through MathJax 55 | - The model is designed to guide students through the problem-solving process rather than providing direct answers 56 | - Image URLs must be publicly accessible -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral Large (25.02)/requirements.txt: -------------------------------------------------------------------------------- 1 | altair==5.5.0 2 | annotated-types==0.7.0 3 | anyio==4.9.0 4 | appnope==0.1.4 5 | asttokens==3.0.0 6 | attrs==25.3.0 7 | blinker==1.9.0 8 | boto3==1.37.24 9 | botocore==1.37.24 10 | cachetools==5.5.2 11 | certifi==2025.1.31 12 | charset-normalizer==3.4.1 13 | click==8.1.8 14 | comm==0.2.2 15 | contourpy==1.3.1 16 | cycler==0.12.1 17 | debugpy==1.8.13 18 | decorator==5.2.1 19 | dotenv==0.9.9 20 | eval_type_backport==0.2.2 21 | executing==2.2.0 22 | fonttools==4.57.0 23 | gitdb==4.0.12 24 | GitPython==3.1.44 25 | h11==0.16.0 26 | httpcore==1.0.7 27 | httpx==0.25.2 28 | httpx-sse==0.4.0 29 | idna==3.10 30 | ipykernel==6.29.5 31 | ipython==9.0.2 32 | ipython_pygments_lexers==1.1.1 33 | ipywidgets==8.1.5 34 | jedi==0.19.2 35 | Jinja2==3.1.6 36 | jmespath==1.0.1 37 | jsonschema==4.23.0 38 | jsonschema-specifications==2024.10.1 39 | jupyter_client==8.6.3 40 | jupyter_core==5.7.2 41 | jupyterlab_widgets==3.0.13 42 | kiwisolver==1.4.8 43 | markdown-it-py==3.0.0 44 | MarkupSafe==3.0.2 45 | matplotlib==3.10.1 46 | matplotlib-inline==0.1.7 47 | mcp==1.6.0 48 | mdurl==0.1.2 49 | mistral_common==1.5.4 50 | mistralai==0.0.12 51 | narwhals==1.33.0 52 | nest-asyncio==1.6.0 53 | numpy==1.26.4 54 | orjson==3.10.16 55 | packaging==23.2 56 | pandas==2.2.3 57 | parso==0.8.4 58 | pexpect==4.9.0 59 | Pillow==10.3.0 60 | platformdirs==4.3.7 61 | prompt_toolkit==3.0.50 62 | protobuf==4.25.6 63 | psutil==7.0.0 64 | ptyprocess==0.7.0 65 | pure_eval==0.2.3 66 | pyarrow==19.0.1 67 | pydantic==2.11.1 68 | pydantic-settings==2.8.1 69 | pydantic_core==2.33.0 70 | pydeck==0.9.1 71 | Pygments==2.19.1 72 | pyparsing==3.2.3 73 | python-dateutil==2.9.0.post0 74 | python-dotenv==1.0.0 75 | pytz==2025.2 76 | pyzmq==26.4.0 77 | referencing==0.36.2 78 | regex==2024.11.6 79 | requests==2.32.2 80 | rich==13.9.4 81 | rpds-py==0.24.0 82 | s3transfer==0.11.4 83 | sentencepiece==0.2.0 84 | six==1.17.0 85 | smithery==0.1.1 86 | smmap==5.0.2 87 | sniffio==1.3.1 88 | sse-starlette==2.2.1 89 | stack-data==0.6.3 90 | starlette==0.46.1 91 | streamlit==1.37.0 92 | tenacity==8.5.0 93 | tiktoken==0.9.0 94 | toml==0.10.2 95 | tornado==6.5.1 96 | traitlets==5.14.3 97 | typing-inspection==0.4.0 98 | typing_extensions==4.13.0 99 | tzdata==2025.2 100 | urllib3==2.3.0 101 | uvicorn==0.34.0 102 | wcwidth==0.2.13 103 | websockets==15.0.1 104 | widgetsnbextension==4.0.13 105 | -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_benchmarking_data/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_benchmarking_data/.gitignore -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/29IYUhRytF5g4wGBCxFm7A.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/29IYUhRytF5g4wGBCxFm7A.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/3a1SR_oZI0-dCEvLG7US5g.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/3a1SR_oZI0-dCEvLG7US5g.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/3agipTLldLEBe7JIvhnv9g.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/3agipTLldLEBe7JIvhnv9g.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/40_Year_Net_Present_Value_of_4-Year_Colleges_by_Tuition_in_the_United_States.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/40_Year_Net_Present_Value_of_4-Year_Colleges_by_Tuition_in_the_United_States.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/AMZN-Q2-2024-Earning-High-Quality.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/AMZN-Q2-2024-Earning-High-Quality.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/AMZN-Q2-2024-Earnings-Release.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/AMZN-Q2-2024-Earnings-Release.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/Amazon_Chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/Amazon_Chart.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/Amazon_Chart_resize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/Amazon_Chart_resize.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/Crosstab_of_Cola_Preference_by_Age_and_Gender.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/Crosstab_of_Cola_Preference_by_Age_and_Gender.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/DNNIYVEp62blavqxGKLX5A.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/DNNIYVEp62blavqxGKLX5A.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/Iconographic_navigation_comparison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/Iconographic_navigation_comparison.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/Map_Motorcycles_vs_cars_by_population_millions_2002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/Map_Motorcycles_vs_cars_by_population_millions_2002.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/Stevens_Field_VFR_Map_(2022).jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/Stevens_Field_VFR_Map_(2022).jpeg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/a01-000u-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/a01-000u-02.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/a01-000u-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/a01-000u-03.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/a01-000u-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/a01-000u-04.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/a01-082u-00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/a01-082u-00.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/a01-082u-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/a01-082u-01.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/a01-082u-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/a01-082u-02.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/a01-082u-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/a01-082u-03.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/a01-082u-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/a01-082u-04.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/airport_lanes.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/airport_lanes.jpeg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/amazon_gloves.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/amazon_gloves.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/amazon_s1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/amazon_s1.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/amazon_s1_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/amazon_s1_2.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/br_marketplace_delete_endpoint.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/br_marketplace_delete_endpoint.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/br_marketplace_deploy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/br_marketplace_deploy.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/br_marketplace_model_card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/br_marketplace_model_card.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/br_marketplace_model_endpoint.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/br_marketplace_model_endpoint.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/br_model_catalog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/br_model_catalog.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/cap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/cap.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/car_image_after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/car_image_after.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/car_image_before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/car_image_before.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/chair.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/chair.jpeg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/cleaner.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/cleaner.jpeg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/coffee.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/coffee.jpeg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/database-schema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/database-schema.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/dog_bag.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/dog_bag.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/dresser.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/dresser.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/er-diagram.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/er-diagram.jpeg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/gdp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/gdp.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/handwriting_low_res_2_resize.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/handwriting_low_res_2_resize.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/hindi_teaser.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/hindi_teaser.jpeg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/insurance_90degree.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/insurance_90degree.pdf -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/jxOrwCQTTDt9Uvu_c3br5w.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/jxOrwCQTTDt9Uvu_c3br5w.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/logical_reasoning.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/logical_reasoning.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/luggage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/luggage.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/org_hierarchy.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/org_hierarchy.jpeg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/portfolio-website.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/portfolio-website.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/restaurant-receipt-brazil.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/restaurant-receipt-brazil.jpeg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/scene.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/scene.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/texas_noaa_image.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/texas_noaa_image.jpeg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/trig-equations-from-context.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/trig-equations-from-context.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/trimmed_green_beans.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/trimmed_green_beans.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/whiteboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/whiteboard.png -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/xQdHJOV6XXIRRuFpNVIojw.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/xQdHJOV6XXIRRuFpNVIojw.jpg -------------------------------------------------------------------------------- /Pixtral-samples/Pixtral_data/xqHNkPl7rohq7_R7f1nAUA.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Pixtral-samples/Pixtral_data/xqHNkPl7rohq7_R7f1nAUA.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Mistral-on-AWS 2 | 3 | ![mistral-aws](/notebooks/imgs/mistralaws.png) 4 | 5 | A collection of notebooks and samples to get started with Mistral models on AWS. 6 | Open a PR if you would like to contribute! :twisted_rightwards_arrows: 7 | 8 | ## What's New :star::star: 9 | 10 | Explore our comprehensive collection of notebooks organized by model, deployment options, and use cases! 11 | 12 | ### Model Capabilities & Use Cases 13 | 14 | #### Pixtral 15 | - [Comprehensive Capabilities Guide](Pixtral-samples/Pixtral_capabilities.ipynb) 16 | - Deployment Options: 17 | - [SageMaker Real-time Inference](Deployment/SageMaker/Pixtral-12b-LMI-SageMaker-realtime-inference.ipynb) 18 | - [Bedrock Marketplace Integration](Deployment/Bedrock%20Marketplace/Deploy-Pixtral12B-from-Bedrock-Marketplace.ipynb) 19 | 20 | #### Mistral Models 21 | - **Small 3**: [Model Overview & Capabilities](Mistral%20Small%203/Mistral_small_3.ipynb) 22 | - **NeMo**: [Comparative Analysis & Benchmarks](Mistral%20NeMo/NeMo_comparative_analysis.ipynb) 23 | 24 | ### Latest Highlights ✨ 25 | - Enhanced Pixtral deployment options across AWS services 26 | - Comprehensive model comparison and analysis 27 | - Streamlined deployment guides for various AWS services 28 | - In-depth exploration of model capabilities and use cases 29 | 30 | > 💡 **Note**: All notebooks include detailed explanations, code samples, and best practices for implementation. 31 | 32 | 33 | 34 | ## Getting Started :electric_plug: 35 | 36 | 1. Please visit [Amazon Bedrock user guide](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html) on how to enable model access. 37 | 2. The notebooks are executed from SageMaker studio with Data Science 3.0 image. 38 | 39 | ## Security 40 | 41 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 42 | 43 | ## Distributors 44 | 45 | - AWS 46 | - Mistral 47 | 48 | ## License 49 | 50 | This library is licensed under the MIT-0 License. See the LICENSE file. 51 | -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/README.md: -------------------------------------------------------------------------------- 1 | # Mistral on AWS Enablement Workshop 2 | This workshop contains a set of notebooks to show you how to use Mistral models in AWS environments, including Amazon Bedrock and Amazon Bedrock Marketplace. At the end, you will also learn how to build an agentic RAG application using Mistral model and LlamaIndex. 3 | 4 | 5 | ## Prerequisites 6 | - An AWS account with access to Amazon Bedrock 7 | - Access to Mistral Large 2 (mistral.mistral-large-2407-v1:0) in us-west-2 8 | - **Increase ml.g6.12xlarge for endpoint usage to at least 2 in Amazon SageMaker service quota webpage in us-west-2** 9 | - Basic understanding of Python and Jupyter notebooks 10 | 11 | ## Setup Instructions 12 | 1. Create an Amazon SageMaker domain in region **us-west-2**. This step may take a few minutes. 13 | 2. Create a SageMaker domain user profile. 14 | 3. Launch SageMaker Studio, select JupyterLab, and create a space. 15 | 4. Select the instance ml.t3.medium and the image SageMaker Distribution 2.3.1, then run the space. 16 | 5. Navigate to the AWS Bedrock service in the AWS console. On the left banner, select “Model access.” 17 | 6. Click on “Modify model access.” 18 | 7. Select the models: Mistral Large 2 (24.07) and Titan Text Embeddings V2 from the list, and request access to these models. 19 | 8. Go to the SageMaker user profile details and find the execution role that the SageMaker notebook uses. It should look similar to: 20 | AmazonSageMaker-ExecutionRole-20250213T123456 21 | 9. Go to AWS console IAM service, add “AmazonBedrockFullAccess” to the execution role. 22 | 10. Clone the workshop repository in the SageMaker JupyterLab terminal: 23 | ```bash 24 | git clone https://github.com/aws-samples/mistral-on-aws.git 25 | cd notebooks/London-enablement-workshop 26 | ``` 27 | 11. Install the required Python packages by running the following command in the terminal: 28 | ```bash 29 | pip install -r requirements.txt -q 30 | ``` 31 | 32 | 33 | ## Workshop Content 34 | 35 | ### Notebook1: 36 | - Mistral model prompt capabilities and best practices 37 | 38 | ### Notebook2: 39 | - Oveview of Mistral Small 3 model 40 | - Deploying Mistral Small 3 model in Amazon Bedrock Marketplace 41 | - Examples of use cases, such as fraud detection and sentiment analysis 42 | 43 | ### Notebook3: 44 | - Overview of Mistral Pixtral 12B model, Vision Language Model (VLM) 45 | - Deploying Pixtral 12B model in Amazon Bedrock Marketplace 46 | - Examples of use cases, such as visual logic reasoning and vehicle damage assessment 47 | 48 | ### Notebook4: 49 | - Overall agentic RAG application architecture 50 | - Integrating API tools into the application 51 | - Building RAG with Amazon OpenSearch Serverless and integrating into the application 52 | - Testing the final chatbot 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/docs/genai_on_aws.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/docs/genai_on_aws.pdf -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/docs/ml_on_aws.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/docs/ml_on_aws.pdf -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/a01-000u-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/a01-000u-04.png -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/br_marketplace_delete_endpoint.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/br_marketplace_delete_endpoint.jpg -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/br_marketplace_deploy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/br_marketplace_deploy.jpg -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/br_marketplace_model_card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/br_marketplace_model_card.jpg -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/br_marketplace_model_endpoint.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/br_marketplace_model_endpoint.jpg -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/br_model_catalog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/br_model_catalog.jpg -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/cap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/cap.png -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/car_image_after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/car_image_after.png -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/car_image_before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/car_image_before.png -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/endpoint-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/endpoint-delete.png -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/gdp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/gdp.png -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/llamaindex-agentic-rag-mistral-large2-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/llamaindex-agentic-rag-mistral-large2-arch.png -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/logical_reasoning.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/logical_reasoning.jpg -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/model-configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/model-configuration.png -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/model-endpoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/model-endpoint.png -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/model-information.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/model-information.png -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/images/search-model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/London-enablement-workshop/images/search-model.png -------------------------------------------------------------------------------- /Workshops/London-enablement-workshop/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3 2 | requests 3 | sagemaker>=2.237.1 4 | PyPDF2 5 | llama-index 6 | llama-index-core 7 | llama-index-llms-bedrock-converse>=0.4.8 8 | llama-index-retrievers-bedrock 9 | llama-index-tools-arxiv 10 | feedparser 11 | opensearch-py 12 | requests-aws4auth -------------------------------------------------------------------------------- /Workshops/NY_Bedrock_Workshop/AWS-security-whitepaper.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/NY_Bedrock_Workshop/AWS-security-whitepaper.pdf -------------------------------------------------------------------------------- /Workshops/NY_Bedrock_Workshop/requirements.txt: -------------------------------------------------------------------------------- 1 | aiobotocore==2.15.2 2 | boto3==1.35.16 3 | botocore==1.35.16 4 | datasets==3.0.1 5 | tqdm==4.66.4 6 | pypdf==5.0.1 -------------------------------------------------------------------------------- /Workshops/aws-summit-paris-2025-agentic/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | __pycache__/ 3 | .ipynb_checkpoints/ -------------------------------------------------------------------------------- /Workshops/aws-summit-paris-2025-agentic/README.md: -------------------------------------------------------------------------------- 1 | # AWS Paris Summit 2025 - ISV booth demo 2 | 3 | This directory contains the code to showcase the agentic capabilities of Mistral 4 | models within the AWS Bedrock platform. 5 | 6 | ## Getting started 7 | 8 | This demo rely on the following external services, for which you will need to 9 | fill in the appropriate API key in an `.env` file at the root of this directory: 10 | 11 | - `GOOGLE_WEATHER_API_KEY` for Google's [Weather 12 | API](https://developers.google.com/maps/documentation/weather/reference/rest). 13 | - `GOOGLE_MAPS_GEOCODE_API_KEY` for Google Maps' [Geocoding 14 | API](https://developers.google.com/maps/documentation/geocoding/overview). - 15 | `GOOGLE_ROUTES_API_KEY` for Google Maps' [Routes 16 | API](https://developers.google.com/maps/documentation/routes). 17 | 18 | You will also need [uv](https://github.com/astral-sh/uv) installed. 19 | 20 | To start the demo notebook, run: 21 | 22 | ```shell 23 | uv run jupyter notebook 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /Workshops/aws-summit-paris-2025-agentic/assets/event_venue.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/Workshops/aws-summit-paris-2025-agentic/assets/event_venue.jpeg -------------------------------------------------------------------------------- /Workshops/aws-summit-paris-2025-agentic/aws_llm.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import json 3 | import os 4 | from pathlib import Path 5 | from typing import List, Dict, Any, Optional, Self 6 | from tools_utils import tool_map 7 | from utils import load_image_file_to_bytes, get_file_extension 8 | 9 | AWS_BEDROCK_MISTRAL_LARGE_MODEL_ID = "mistral.mistral-large-2407-v1:0" 10 | AWS_SAGEMAKER_PIXTRAL_12B_ENDPOINT_ARN = ( 11 | "arn:aws:sagemaker:us-west-2:777356365391:endpoint/harizo-tests-pixtral12b" 12 | ) 13 | AWS_REGION = "us-west-2" 14 | AWS_BEDROCK_DEFAULT_INFERENCE_CONFIG = {"temperature": 0.0, "maxTokens": 4096} 15 | AWS_BEDROCK_DEFAULT_SYSTEM_MESSAGE = """ 16 | Tu es un assistant serviable et informel. Ton role est de guider l'utilisateur 17 | dans sa découverte de la ville de Paris. Réponds toujours aux questions en Français. 18 | """ 19 | 20 | 21 | client = boto3.client(service_name="bedrock-runtime", region_name=AWS_REGION) 22 | 23 | with Path("tools_demo.json").open(mode="r") as f_in: 24 | tools_demo = json.load(f_in) 25 | 26 | 27 | class Agent: 28 | def __init__(self): 29 | self.model_id = AWS_BEDROCK_MISTRAL_LARGE_MODEL_ID 30 | self.messages: List[Dict[str, Any]] = [] 31 | self.tools: Optional[Dict[str, Any]] = None 32 | self.system_message_content = AWS_BEDROCK_DEFAULT_SYSTEM_MESSAGE 33 | 34 | def show_messages(self): 35 | print(json.dumps(self.messages, indent=4)) 36 | 37 | def save_messages(self, file_name: str): 38 | with Path(file_name).open(mode="w") as f_in: 39 | json.dump(self.messages, f_in) 40 | 41 | def ask( 42 | self, user_message_content: str, image_paths: Optional[List[str]] = None 43 | ) -> Self: 44 | user_message = {"role": "user", "content": [{"text": user_message_content}]} 45 | converse_params = { 46 | "modelId": self.model_id, 47 | "messages": self.messages, 48 | "inferenceConfig": AWS_BEDROCK_DEFAULT_INFERENCE_CONFIG, 49 | "system": [{"text": self.system_message_content}], 50 | } 51 | if image_paths: 52 | # Override default model id to force multimodal usage 53 | converse_params["modelId"] = AWS_SAGEMAKER_PIXTRAL_12B_ENDPOINT_ARN 54 | for imgp in image_paths: 55 | user_message["content"].append( 56 | { 57 | "image": { 58 | "format": get_file_extension(imgp), 59 | "source": {"bytes": load_image_file_to_bytes(imgp)}, 60 | } 61 | } 62 | ) 63 | if self.tools: 64 | converse_params.update({"toolConfig": self.tools}) 65 | self.messages.append(user_message) 66 | try: 67 | resp = client.converse(**converse_params) 68 | output_message = resp["output"]["message"] 69 | self.messages.append(output_message) 70 | if tool_use := output_message["content"][0].get("toolUse", None): 71 | tool_use_id = tool_use["toolUseId"] 72 | func_name = tool_use["name"] 73 | func_args = tool_use["input"] 74 | func = tool_map[func_name] 75 | func_out = func(**func_args) 76 | tool_message_content = { 77 | "toolResult": { 78 | "toolUseId": tool_use_id, 79 | "content": [{"json": func_out}], 80 | } 81 | } 82 | tool_message = {"role": "user", "content": [tool_message_content]} 83 | self.messages.append(tool_message) 84 | try: 85 | resp_tool_use = client.converse(**converse_params) 86 | self.messages.append(resp_tool_use["output"]["message"]) 87 | except Exception as e: 88 | print(f"Error during tool use: {e}") 89 | print(self.messages[-1]["content"][0]["text"]) 90 | except Exception as e: 91 | print(f"Conversation error: {e}") 92 | raise 93 | -------------------------------------------------------------------------------- /Workshops/aws-summit-paris-2025-agentic/notebook.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "87022b08", 7 | "metadata": {}, 8 | "outputs": [ 9 | { 10 | "name": "stdout", 11 | "output_type": "stream", 12 | "text": [ 13 | "mistral.mistral-large-2407-v1:0\n", 14 | "\n", 15 | "Tu es un assistant serviable et informel. Ton role est de guider l'utilisateur\n", 16 | "dans sa découverte de la ville de Paris. Réponds toujours aux questions en Français.\n", 17 | "\n" 18 | ] 19 | } 20 | ], 21 | "source": [ 22 | "from aws_llm import Agent, tools_demo\n", 23 | "\n", 24 | "demo_agent = Agent()\n", 25 | "print(demo_agent.model_id)\n", 26 | "print(demo_agent.system_message_content)" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 2, 32 | "id": "58ab051c", 33 | "metadata": {}, 34 | "outputs": [ 35 | { 36 | "name": "stdout", 37 | "output_type": "stream", 38 | "text": [ 39 | "Tu es devant le Palais des Congrès à Paris. C'est un lieu célèbre pour ses grandes conférences, expositions et événements. L'architecture moderne et les grands panneaux publicitaires te donnent une idée des nombreux événements qui s'y déroulent.\n" 40 | ] 41 | } 42 | ], 43 | "source": [ 44 | "demo_agent.ask(\n", 45 | " \"Ou suis-je en ce moment? Indice: c'est à Paris dans un lieu habitué aux grandes conférences.\",\n", 46 | " image_paths=[\"assets/event_venue.jpeg\"],\n", 47 | ")" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 3, 53 | "id": "50444759", 54 | "metadata": {}, 55 | "outputs": [ 56 | { 57 | "name": "stdout", 58 | "output_type": "stream", 59 | "text": [ 60 | "Il fait 22.7°C et il y a un ciel partiellement ensoleillé au Palais des Congrès de Paris en ce moment.\n" 61 | ] 62 | } 63 | ], 64 | "source": [ 65 | "demo_agent = Agent()\n", 66 | "demo_agent.tools = tools_demo\n", 67 | "demo_agent.ask(\"Quel temps fait-il au Palais des Congrès de Paris en ce moment?\")" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 4, 73 | "id": "e38faee2", 74 | "metadata": {}, 75 | "outputs": [ 76 | { 77 | "name": "stdout", 78 | "output_type": "stream", 79 | "text": [ 80 | "La station Velib la plus proche est Porte Maillot - Perreire, située à environ 158 mètres du Palais des Congrès de Paris.\n" 81 | ] 82 | } 83 | ], 84 | "source": [ 85 | "demo_agent.ask(\"Quelle est la station Velib la plus proche de cet endroit ?\")" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 5, 91 | "id": "14b7b7d5", 92 | "metadata": {}, 93 | "outputs": [ 94 | { 95 | "name": "stdout", 96 | "output_type": "stream", 97 | "text": [ 98 | "Il reste 13 vélos disponibles à la station Porte Maillot - Perreire.\n" 99 | ] 100 | } 101 | ], 102 | "source": [ 103 | "demo_agent.ask(\"Combien de vélos y reste-t-il ?\")" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 6, 109 | "id": "51920b6b", 110 | "metadata": {}, 111 | "outputs": [ 112 | { 113 | "name": "stdout", 114 | "output_type": "stream", 115 | "text": [ 116 | "Pour aller de Porte Maillot - Perreire à la Gare de Lyon, suivez ces indications :\n", 117 | "\n", 118 | "1. Prendre la direction nord-est sur Bd Pereire vers Pl. du Maréchal Juin (17 m)\n", 119 | "2. Au Pl. du Maréchal Juin, prendre la 3e sortie sur Av. de Villiers (1028 m)\n", 120 | "3. Prendre légèrement à droite sur Bd Malesherbes (1744 m)\n", 121 | "4. Continuer tout droit sur Pl. de la Madeleine (63 m)\n", 122 | "5. Tourner à gauche pour rester sur Pl. de la Madeleine (99 m)\n", 123 | "6. Prendre à droite sur Rue Duphot (47 m)\n", 124 | "7. Prendre à droite sur Rue du Chevalier de Saint-George (129 m)\n", 125 | "8. Continuer sur Rue Saint-Florentin (187 m)\n", 126 | "9. Prendre à droite sur Rue de Rivoli (19 m)\n", 127 | "10. Prendre à gauche sur Pl. de la Concorde (33 m)\n", 128 | "11. Rester sur la voie de gauche pour continuer sur Pl. de la Concorde (270 m)\n", 129 | "12. Tourner à gauche (28 m)\n", 130 | "13. Tourner à gauche (313 m)\n", 131 | "14. Continuer sur Voie Georges Pompidou (2053 m)\n", 132 | "15. Tourner légèrement à droite pour continuer sur Voie Georges Pompidou (1433 m)\n", 133 | "16. Tourner légèrement à droite (512 m)\n", 134 | "17. Prendre légèrement à droite sur Port de la Rapée (477 m)\n", 135 | "18. Prendre à gauche sur Rue Villiot (294 m)\n", 136 | "19. Tourner à gauche vers All. de Bercy (62 m)\n", 137 | "20. Continuer sur All. de Bercy\n", 138 | "\n", 139 | "Votre destination se trouvera sur la droite. (247 m)\n", 140 | "\n", 141 | "La distance totale est de 9.05 km et le trajet dure environ 30 minutes.\n" 142 | ] 143 | } 144 | ], 145 | "source": [ 146 | "demo_agent.ask(\n", 147 | " \"Peux-tu me tracer l'itinéraire pour aller de cette station à la Gare de Lyon ?\"\n", 148 | ")" 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": null, 154 | "id": "31c79046", 155 | "metadata": {}, 156 | "outputs": [], 157 | "source": [] 158 | } 159 | ], 160 | "metadata": { 161 | "kernelspec": { 162 | "display_name": "Python 3 (ipykernel)", 163 | "language": "python", 164 | "name": "python3" 165 | } 166 | }, 167 | "nbformat": 4, 168 | "nbformat_minor": 5 169 | } 170 | -------------------------------------------------------------------------------- /Workshops/aws-summit-paris-2025-agentic/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "aws-summit-paris-2025-agentic" 3 | version = "1.0.0" 4 | description = "Demo for the AWS Paris Summit 2025" 5 | readme = "README.md" 6 | requires-python = ">=3.12" 7 | dependencies = [ 8 | "boto3>=1.37.25", 9 | "notebook>=7.3.3", 10 | "numpy>=2.2.4", 11 | "python-dotenv>=1.1.0", 12 | ] 13 | -------------------------------------------------------------------------------- /Workshops/aws-summit-paris-2025-agentic/tools_demo.json: -------------------------------------------------------------------------------- 1 | { 2 | "tools": [ 3 | { 4 | "toolSpec": { 5 | "name": "get_weather", 6 | "description": "Fetches the weather at a specific location", 7 | "inputSchema": { 8 | "json": { 9 | "type": "object", 10 | "properties": { 11 | "address": { 12 | "type": "string", 13 | "description": "The location to get the weather from" 14 | } 15 | }, 16 | "required": [ 17 | "address" 18 | ] 19 | } 20 | } 21 | } 22 | }, 23 | { 24 | "toolSpec": { 25 | "name": "get_nearest_velib_station", 26 | "description": "Retrieves the closest Velib bike rental station", 27 | "inputSchema": { 28 | "json": { 29 | "type": "object", 30 | "properties": { 31 | "address": { 32 | "type": "string", 33 | "description": "The location to search the nearest Velib bike rental station from" 34 | } 35 | }, 36 | "required": [ 37 | "address" 38 | ] 39 | } 40 | } 41 | } 42 | }, 43 | { 44 | "toolSpec": { 45 | "name": "get_remaining_bikes", 46 | "description": "Get the number of remaining bikes at a given Velib bike rental station", 47 | "inputSchema": { 48 | "json": { 49 | "type": "object", 50 | "properties": { 51 | "station_id": { 52 | "type": "string", 53 | "description": "The ID of the Velib bike rental station to get remaining bikes from" 54 | } 55 | }, 56 | "required": [ 57 | "station_id" 58 | ] 59 | } 60 | } 61 | } 62 | }, 63 | { 64 | "toolSpec": { 65 | "name": "get_biking_itinerary", 66 | "description": "Create a biking itinerary description", 67 | "inputSchema": { 68 | "json": { 69 | "type": "object", 70 | "properties": { 71 | "origin_address": { 72 | "type": "string", 73 | "description": "The starting location of the biking itinerary" 74 | }, 75 | "destination_address": { 76 | "type": "string", 77 | "description": "The end point of the biking itinerary" 78 | } 79 | }, 80 | "required": [ 81 | "origin_address", 82 | "destination_address" 83 | ] 84 | } 85 | } 86 | } 87 | } 88 | ] 89 | } -------------------------------------------------------------------------------- /Workshops/aws-summit-paris-2025-agentic/tools_utils.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, Any, List 2 | import httpx 3 | import os 4 | import json 5 | from dotenv import load_dotenv 6 | from pathlib import Path 7 | from utils import haversine_distance, to_minutes 8 | 9 | GOOGLE_WEATHER_API_ENDPOINT = ( 10 | "https://weather.googleapis.com/v1/currentConditions:lookup" 11 | ) 12 | GOOGLE_MAPS_GEOCODE_API_ENDPOINT = "https://maps.googleapis.com/maps/api/geocode/json" 13 | GOOGLE_ROUTES_API_ENDPOINT = "https://routes.googleapis.com/directions/v2:computeRoutes" 14 | VELIB_STATIONS_FILE_PATH = "./assets/velib_stations.json" 15 | VELIB_SERVICE_URL = "https://velib-metropole-opendata.smovengo.cloud/opendata/Velib_Metropole/station_status.json" 16 | 17 | CREDENTIALS_VARIABLES = [ 18 | "GOOGLE_WEATHER_API_KEY", 19 | "GOOGLE_MAPS_GEOCODE_API_KEY", 20 | "GOOGLE_ROUTES_API_KEY", 21 | ] 22 | 23 | load_dotenv() 24 | for var in CREDENTIALS_VARIABLES: 25 | if not os.environ.get(var, None): 26 | raise ValueError(f"Missing env variable for credentials: {var}") 27 | 28 | 29 | def _geocode(address: str) -> Dict[str, float]: 30 | url = GOOGLE_MAPS_GEOCODE_API_ENDPOINT 31 | headers = {"Content-Type": "application/json"} 32 | params = {"address": address, "key": os.getenv("GOOGLE_MAPS_GEOCODE_API_KEY")} 33 | try: 34 | resp = httpx.get(url=url, headers=headers, params=params) 35 | resp.raise_for_status() 36 | resp_json = resp.json() 37 | return resp_json["results"][0]["geometry"]["location"] 38 | except Exception as exc: 39 | print(f"Error when requesting {url}: {exc}") 40 | raise 41 | 42 | 43 | def _parse_legs(legs: List[Dict[str, Any]]) -> List[str]: 44 | out: List[str] = [] 45 | for leg in legs: 46 | for step in leg["steps"]: 47 | instruction = step["navigationInstruction"]["instructions"] 48 | distance = step["distanceMeters"] 49 | line = f"{instruction} ({distance}m)" 50 | out.append(line) 51 | return out 52 | 53 | 54 | def get_weather(address: str) -> Dict[str, Any]: 55 | location_lat_lon = _geocode(address=address) 56 | url = GOOGLE_WEATHER_API_ENDPOINT 57 | headers = {"Content-Type": "application/json"} 58 | params = { 59 | "location.latitude": location_lat_lon["lat"], 60 | "location.longitude": location_lat_lon["lng"], 61 | "key": os.getenv("GOOGLE_WEATHER_API_KEY"), 62 | } 63 | try: 64 | resp = httpx.get(url=url, headers=headers, params=params) 65 | resp.raise_for_status() 66 | resp_json = resp.json() 67 | return { 68 | "description": resp_json["weatherCondition"]["description"]["text"], 69 | "temperature": resp_json["temperature"]["degrees"], 70 | } 71 | except Exception as exc: 72 | print(f"Error when requesting {url}: {exc}") 73 | 74 | 75 | def get_nearest_velib_station(address: str) -> Dict[str, Any]: 76 | locations_lat_lon = _geocode(address=address) 77 | with Path(VELIB_STATIONS_FILE_PATH).open(mode="r") as f_in: 78 | stations_data = json.load(f_in).get("data").get("stations") 79 | 80 | station_names_by_id = { 81 | str(item["station_id"]): item["name"] for item in stations_data 82 | } 83 | 84 | station_ids = [item["station_id"] for item in stations_data] 85 | positions = [[item["lat"], item["lon"]] for item in stations_data] 86 | distances = haversine_distance( 87 | source_lat=locations_lat_lon["lat"], 88 | source_lon=locations_lat_lon["lng"], 89 | targets_latlon=positions, 90 | ) 91 | sorted_distances = [ 92 | (sid, dist) for sid, dist in zip(station_ids, distances.tolist()) 93 | ] 94 | sorted_distances.sort(key=lambda x: x[1]) 95 | nearest_station = { 96 | "name": station_names_by_id[str(sorted_distances[0][0])], 97 | "id": str(sorted_distances[0][0]), 98 | "distance_km": sorted_distances[0][1], 99 | } 100 | return nearest_station 101 | 102 | 103 | def get_remaining_bikes(station_id: str) -> Dict[str, Any]: 104 | try: 105 | resp = httpx.get(url=VELIB_SERVICE_URL) 106 | station_live_data = resp.json().get("data").get("stations") 107 | station_live_availability_by_id = { 108 | str(item["station_id"]): item["numBikesAvailable"] 109 | for item in station_live_data 110 | } 111 | return {"nb_remaining_bikes": station_live_availability_by_id[station_id]} 112 | 113 | except httpx.HTTPStatusError as exc: 114 | print( 115 | f"Request failed with status code {exc.response.status_code}: {exc.response.text}" 116 | ) 117 | except httpx.RequestError as exc: 118 | print(f"An error occurred while requesting {exc.request.url!r}: {exc}") 119 | except Exception as exc: 120 | print(f"An unexpected error occurred: {exc}") 121 | raise 122 | 123 | 124 | def get_biking_itinerary( 125 | origin_address: str, destination_address: str 126 | ) -> Dict[str, Any]: 127 | origin_lat_lon = _geocode(origin_address) 128 | destination_lat_lon = _geocode(destination_address) 129 | try: 130 | url = GOOGLE_ROUTES_API_ENDPOINT 131 | headers = { 132 | "Content-Type": "application/json", 133 | "X-Goog-Api-Key": os.getenv("GOOGLE_ROUTES_API_KEY"), 134 | "X-Goog-FieldMask": "routes.duration,routes.distanceMeters,routes.legs", 135 | } 136 | payload = { 137 | "origin": { 138 | "location": { 139 | "latLng": { 140 | "latitude": origin_lat_lon["lat"], 141 | "longitude": origin_lat_lon["lng"], 142 | } 143 | } 144 | }, 145 | "destination": { 146 | "location": { 147 | "latLng": { 148 | "latitude": destination_lat_lon["lat"], 149 | "longitude": destination_lat_lon["lng"], 150 | } 151 | } 152 | }, 153 | "travelMode": "BICYCLE", 154 | "languageCode": "fr", 155 | "units": "METRIC", 156 | } 157 | resp = httpx.post(url=url, headers=headers, json=payload) 158 | resp.raise_for_status() 159 | resp_json = resp.json() 160 | route = resp_json["routes"][0] 161 | # Itinerary 162 | itinerary = _parse_legs(route["legs"]) 163 | # Distance + duration 164 | distance_km = float(format(route["distanceMeters"] / 1000.0, ".2f")) 165 | duration_min = to_minutes(route["duration"]) 166 | return { 167 | "itinerary": itinerary, 168 | "distance_km": distance_km, 169 | "duration_min": duration_min, 170 | } 171 | except httpx.HTTPStatusError as exc: 172 | print( 173 | f"Request failed with status code {exc.response.status_code}: {exc.response.text}" 174 | ) 175 | except httpx.RequestError as exc: 176 | print(f"An error occurred while requesting {exc.request.url!r}: {exc}") 177 | except Exception as exc: 178 | print(f"An unexpected error occurred: {exc}") 179 | 180 | 181 | tool_map = { 182 | "get_weather": get_weather, 183 | "get_nearest_velib_station": get_nearest_velib_station, 184 | "get_remaining_bikes": get_remaining_bikes, 185 | "get_biking_itinerary": get_biking_itinerary, 186 | } 187 | -------------------------------------------------------------------------------- /Workshops/aws-summit-paris-2025-agentic/utils.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import base64 3 | from typing import List 4 | from pathlib import Path 5 | 6 | 7 | def haversine_distance( 8 | source_lat: float, source_lon: float, targets_latlon: List[List[float]] 9 | ) -> np.ndarray: 10 | # Convert degrees to radians 11 | targets = np.array(targets_latlon) 12 | lats = targets[:, 0] 13 | lons = targets[:, 1] 14 | lat1_rad, lon1_rad = np.radians(source_lat), np.radians(source_lon) 15 | lats_rad, lons_rad = np.radians(lats), np.radians(lons) 16 | 17 | # Differences in coordinates 18 | dlat = lats_rad - lat1_rad 19 | dlon = lons_rad - lon1_rad 20 | 21 | # Haversine formula 22 | a = ( 23 | np.sin(dlat / 2.0) ** 2 24 | + np.cos(lat1_rad) * np.cos(lats_rad) * np.sin(dlon / 2.0) ** 2 25 | ) 26 | c = 2.0 * np.arctan2(np.sqrt(a), np.sqrt(1 - a)) 27 | distances = 6371.0 * c # Radius of Earth in kilometers 28 | 29 | return distances 30 | 31 | 32 | def to_minutes(duration_str: str) -> float: 33 | total_seconds = int(duration_str.replace("s", "")) 34 | total_minutes = float(format(total_seconds / 60.0, ".1f")) 35 | return total_minutes 36 | 37 | 38 | def load_image_file_to_bytes(file_name: str) -> bytes: 39 | with Path(file_name).open(mode="rb") as f_in: 40 | image_data = f_in.read() 41 | return image_data 42 | 43 | 44 | def load_image_file_to_b64(file_name: str) -> str: 45 | image_data = load_image_file_to_bytes(file_path=file_name) 46 | b64_encoded_data = base64.b64encode(image_data) 47 | return b64_encoded_data.decode("utf-8") 48 | 49 | 50 | def get_file_extension(file_name: str) -> str: 51 | return Path(file_name).suffix.replace(".", "") 52 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Bedrock Mistral prompting examples 2 | 3 | ## Getting Started 🚀 4 | 5 | Please visit [Amazon Bedrock user guide](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html) on how to enable model access. 📚 6 | 7 | The notebooks are executed from SageMaker studio with Data Science 3.0 image. 💻🔬 8 | 9 | ## Introduction 🌍 10 | 11 | Welcome to the Bedrock Mistral prompting examples repository! This collection aims to provide you with a wide range of prompting examples and techniques to enhance your experience with the Mistral language model. Whether you're a beginner or an experienced user, these examples will help you in your generative AI journey. 💡 12 | 13 | ## Resources 📚 14 | 15 | Looking for additional resources? Check out these helpful links: 16 | 17 | - [Mistral Documentation](https://mistral.ai/) 18 | - [Bedrock Documentation](https://aws.amazon.com/bedrock/) 19 | -------------------------------------------------------------------------------- /docs/notebooks.md: -------------------------------------------------------------------------------- 1 | # Main Notebooks 📚 2 | 3 | - **Mistral Getting Started Guide**: 🚀 This notebook adds tool use to the comprehensive guide on utilizing the Converse API with the Mistral models, focusing on defining tools, understanding tool_choice impacts, and leveraging the API for enhanced functionality. Users will learn to configure tools, observe the effects of different tool choices on model outputs, and gain practical experience with the Converse API to maximize the Mistral models' potential in various scenarios. 4 | 5 | - **Prompt Engineering 101 w/ Mistral**: 🛠️ This notebook provides a comprehensive guide on how to get started with the Mistral AI models on Amazon Bedrock. It highlights the significance of prompt engineering techniques, such as zero-shot, few-shot, and chain-of-thought prompting, to enhance the quality and accuracy of model outputs. The notebook demonstrates how to effectively utilize special tokens and instruction templates to maximize the potential of LLMs. Additionally, it offers a detailed comparison of the capabilities of Mistral Large, Mixtral 8x7B, and Mistral Small models, showcasing their respective strengths in analytical reasoning and multilingual tasks through insightful examples. Overall, the notebook equips users with the necessary knowledge and techniques to leverage the power of Mistral AI models on Amazon Bedrock effectively. 6 | 7 | - **OpenAI to Mistral**: 🌉 This guide provides a foundation for transitioning OpenAI prompts and workloads to Mistral models, demonstrating their capabilities and efficiency through practical examples. 8 | 9 | - **Agentic Workflows with tool use - now with native tool use!**: 🤖 We demonstrate an agentic workflow that leverages Mistral models on Amazon Bedrock to create a seamless function calling experience. We explore techniques for crafting effective prompts over function calling and developing custom helper functions capable of understanding an API's data structure. These helper functions can identify the necessary tools and methods to be executed during the agentic workflow interactions. 10 | 11 | - **Advanced RAG Pipeline with Q&A Automation and Model Evaluation**: ⚙️ This notebook automates and evaluates the RAG pipeline with Mistral 7B Instruct as the generator. It utilizes LlamaIndex and Ragas to automate Q&A, generating questions based on your data, allowing you to test your RAG pipeline's performance on a diverse set of queries without manual effort. Additionally, it assesses performance metrics such as faithfulness, relevancy, correctness, semantic similarity, and others on tailored test sets, aiming to identify strengths, limitations, and areas for improvement in the pipeline. 12 | 13 | - **Summarizing long documents with LangChain**: 📚 This Python notebook explores summarizing long documents using the Mistral Large language model on Amazon Bedrock with the LangChain library. It covers three main summarization techniques: Stuff (passing the entire document to the model in a single call), Map Reduce (a scalable technique, splitting the document into chunks, summarizing each chunk in parallel, and combining these summaries), and Refine (an iterative approach, generating an initial summary and refining it with additional context from subsequent chunks). The notebook includes detailed code examples for each technique using LangChain's utilities and chains. It demonstrates loading PDF documents, splitting them into text chunks, and customizing prompt templates. Additionally, it showcases the Mistral model's multilingual capabilities by generating a summary in French. 14 | 15 | - **Multi-chain Routing in LangChain**: 🔀 This notebook demonstrates the use of multi-chain routing in LangChain, a Python library for building applications with large language models (LLMs) and integrating different Mistral AI models from Amazon Bedrock (Mistral Large, Mistral 7B, and Mixtral 8X7B). The notebook explores a use case in the Financial Services Industry (FSI), where a user can query information about their investments, retrieve financial reports, and search for relevant news articles using a single pipeline. 16 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Mistral on AWS 2 | copyright: Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | theme: 4 | name: material 5 | icon: 6 | annotation: material/plus-circle-outline 7 | repo: material/github 8 | palette: 9 | - media: "(prefers-color-scheme: light)" 10 | scheme: default 11 | primary: white 12 | accent: deep purple 13 | toggle: 14 | icon: material/weather-night 15 | name: "Switch to dark mode" 16 | - media: "(prefers-color-scheme: dark)" 17 | scheme: slate 18 | primary: black 19 | accent: deep purple 20 | toggle: 21 | icon: material/weather-sunny 22 | name: "Switch to light mode" 23 | features: 24 | - header.autohide 25 | - content.code.copy 26 | - content.code.annotate 27 | - navigation.indexes 28 | - navigation.footer 29 | - navigation.top 30 | - navigation.tabs 31 | repo_url: https://github.com/aws-samples/bedrock-mistral-prompting-examples 32 | repo_name: aws-samples/bedrock-mistral-prompting-examples 33 | nav: 34 | - Home: index.md 35 | - Notebooks: notebooks.md 36 | -------------------------------------------------------------------------------- /notebooks/Codestral-samples/codestral_chat_ui/codestral_chat.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import gradio as gr 3 | import io 4 | import json 5 | 6 | 7 | # default hyperparameters for llm 8 | parameters = { 9 | "do_sample": True, 10 | "top_p": 0.6, 11 | "temperature": 0.9, 12 | "top_k": 50, 13 | "max_new_tokens": 2048, 14 | "stop": [""] 15 | } 16 | 17 | system_prompt = "You are a helpful Assistant, called Codestral. You are meant to be an expert at code generation tasks" 18 | 19 | 20 | # Helper for reading lines from a stream 21 | 22 | class ReadLines: 23 | def __init__(self, stream): 24 | self.byte_iterator = iter(stream) 25 | self.buffer = io.BytesIO() 26 | self.read_pos = 0 27 | 28 | def __iter__(self): 29 | return self 30 | 31 | def __next__(self): 32 | while True: 33 | self.buffer.seek(self.read_pos) 34 | line = self.buffer.readline() 35 | if line and line[-1] == ord("\n"): 36 | self.read_pos += len(line) 37 | return line[:-1] 38 | try: 39 | chunk = next(self.byte_iterator) 40 | except StopIteration: 41 | if self.read_pos < self.buffer.getbuffer().nbytes: 42 | continue 43 | raise 44 | if "PayloadPart" not in chunk: 45 | print("Unknown event type:" + chunk) 46 | continue 47 | self.buffer.seek(0, io.SEEK_END) 48 | self.buffer.write(chunk["PayloadPart"]["Bytes"]) 49 | 50 | 51 | # helper method to format prompt 52 | 53 | def format_prompt(message, history, system_prompt): 54 | prompt = "" 55 | for user_prompt, bot_response in history: 56 | prompt = f" [INST] {user_prompt} [/INST] {bot_response}" 57 | prompt += f"### Instruction\n{user_prompt}\n\n" 58 | prompt += f"### Answer\n{bot_response}\n\n" 59 | # add new user prompt if history is not empty 60 | if len(history) > 0: 61 | prompt += f" [INST] {message} [/INST] " 62 | else: 63 | prompt += f" [INST] {message} [/INST] " 64 | return prompt 65 | 66 | def create_gradio_app( 67 | endpoint_name, 68 | session=boto3, 69 | parameters=parameters, 70 | system_prompt=system_prompt, 71 | format_prompt=format_prompt, 72 | concurrency_limit=4, 73 | share=True, 74 | ): 75 | smr = session.client("sagemaker-runtime") 76 | 77 | def generate( 78 | prompt, 79 | history, 80 | ): 81 | formatted_prompt = format_prompt(prompt, history, system_prompt) 82 | 83 | request = {"inputs": formatted_prompt, "parameters": parameters, "stream": True} 84 | resp = smr.invoke_endpoint_with_response_stream( 85 | EndpointName=endpoint_name, 86 | Body=json.dumps(request), 87 | ContentType="application/json", 88 | ) 89 | 90 | output = "" 91 | for c in ReadLines(resp["Body"]): 92 | c = c.decode("utf-8") 93 | if c.startswith("data:"): 94 | chunk = json.loads(c.lstrip("data:").rstrip("/n")) 95 | if chunk["token"]["special"]: 96 | continue 97 | if chunk["token"]["text"] in request["parameters"]["stop"]: 98 | break 99 | output += chunk["token"]["text"] 100 | for stop_str in request["parameters"]["stop"]: 101 | if output.endswith(stop_str): 102 | output = output[: -len(stop_str)] 103 | output = output.rstrip() 104 | yield output 105 | 106 | yield output 107 | return output 108 | 109 | demo = gr.ChatInterface(generate, title="Chat with Codestral", concurrency_limit=4, chatbot=gr.Chatbot(layout="panel")) 110 | 111 | demo.launch(share=share) 112 | -------------------------------------------------------------------------------- /notebooks/Codestral-samples/imgs/codestral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/Codestral-samples/imgs/codestral.png -------------------------------------------------------------------------------- /notebooks/Codestral-samples/imgs/img: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /notebooks/Mathstral-samples/Mathstral_chat_ui/Mathstral_chat.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import gradio as gr 3 | import io 4 | import json 5 | 6 | 7 | # default hyperparameters for llm 8 | parameters = { 9 | "do_sample": True, 10 | "top_p": 0.6, 11 | "temperature": 0.9, 12 | "top_k": 50, 13 | "max_new_tokens": 2048, 14 | "stop": [""] 15 | } 16 | 17 | system_prompt = "You are a helpful Assistant, called Mathstral. You are meant to be an expert at math and reasoning generation tasks" 18 | 19 | 20 | # Helper for reading lines from a stream 21 | 22 | class ReadLines: 23 | def __init__(self, stream): 24 | self.byte_iterator = iter(stream) 25 | self.buffer = io.BytesIO() 26 | self.read_pos = 0 27 | 28 | def __iter__(self): 29 | return self 30 | 31 | def __next__(self): 32 | while True: 33 | self.buffer.seek(self.read_pos) 34 | line = self.buffer.readline() 35 | if line and line[-1] == ord("\n"): 36 | self.read_pos += len(line) 37 | return line[:-1] 38 | try: 39 | chunk = next(self.byte_iterator) 40 | except StopIteration: 41 | if self.read_pos < self.buffer.getbuffer().nbytes: 42 | continue 43 | raise 44 | if "PayloadPart" not in chunk: 45 | print("Unknown event type:" + chunk) 46 | continue 47 | self.buffer.seek(0, io.SEEK_END) 48 | self.buffer.write(chunk["PayloadPart"]["Bytes"]) 49 | 50 | 51 | # helper method to format prompt 52 | 53 | def format_prompt(message, history, system_prompt): 54 | prompt = "" 55 | for user_prompt, bot_response in history: 56 | prompt = f" [INST] {user_prompt} [/INST] {bot_response}" 57 | prompt += f"### Instruction\n{user_prompt}\n\n" 58 | prompt += f"### Answer\n{bot_response}\n\n" 59 | # add new user prompt if history is not empty 60 | if len(history) > 0: 61 | prompt += f" [INST] {message} [/INST] " 62 | else: 63 | prompt += f" [INST] {message} [/INST] " 64 | return prompt 65 | 66 | def create_gradio_app( 67 | endpoint_name, 68 | session=boto3, 69 | parameters=parameters, 70 | system_prompt=system_prompt, 71 | format_prompt=format_prompt, 72 | concurrency_limit=4, 73 | share=True, 74 | ): 75 | smr = session.client("sagemaker-runtime") 76 | 77 | def generate( 78 | prompt, 79 | history, 80 | ): 81 | formatted_prompt = format_prompt(prompt, history, system_prompt) 82 | 83 | request = {"inputs": formatted_prompt, "parameters": parameters, "stream": True} 84 | resp = smr.invoke_endpoint_with_response_stream( 85 | EndpointName=endpoint_name, 86 | Body=json.dumps(request), 87 | ContentType="application/json", 88 | ) 89 | 90 | output = "" 91 | for c in ReadLines(resp["Body"]): 92 | c = c.decode("utf-8") 93 | if c.startswith("data:"): 94 | chunk = json.loads(c.lstrip("data:").rstrip("/n")) 95 | if chunk["token"]["special"]: 96 | continue 97 | if chunk["token"]["text"] in request["parameters"]["stop"]: 98 | break 99 | output += chunk["token"]["text"] 100 | for stop_str in request["parameters"]["stop"]: 101 | if output.endswith(stop_str): 102 | output = output[: -len(stop_str)] 103 | output = output.rstrip() 104 | yield output 105 | 106 | yield output 107 | return output 108 | 109 | demo = gr.ChatInterface(generate, title="Chat with Codestral", concurrency_limit=4, chatbot=gr.Chatbot(layout="panel")) 110 | 111 | demo.launch(share=share) 112 | -------------------------------------------------------------------------------- /notebooks/Mathstral-samples/imgs/img: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /notebooks/Mathstral-samples/imgs/mathstral-benchmarks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/Mathstral-samples/imgs/mathstral-benchmarks.png -------------------------------------------------------------------------------- /notebooks/Mistral-7B-Insurance-Neuron/Fine-tuned Mistral Models - thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/Mistral-7B-Insurance-Neuron/Fine-tuned Mistral Models - thumbnail.png -------------------------------------------------------------------------------- /notebooks/Mistral-7B-Insurance-Neuron/app-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "sagemaker_region": "us-west-2", 3 | "bedrock_region": "us-west-2", 4 | "sagemaker_endpoint_name": "huggingface-pytorch-tgi-inference-ml-in-2024-11-12-16-12-31-309", 5 | "bedrock_model_id": "arn:aws:bedrock:us-west-2:603555443475:imported-model/7qig1rjkxppp", 6 | "sagemaker_model_id": "aboavent/Mistral-7B-Insurance-neuron" 7 | } 8 | -------------------------------------------------------------------------------- /notebooks/Mistral-7B-Insurance-Neuron/app.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | import boto3 3 | import json 4 | from botocore.exceptions import ClientError 5 | 6 | # Load configuration from app-config.json 7 | with open("app-config.json", "r") as config_file: 8 | config = json.load(config_file) 9 | 10 | # Extract configuration variables 11 | sagemaker_region = config["sagemaker_region"] 12 | bedrock_region = config["bedrock_region"] 13 | sagemaker_endpoint_name = config["sagemaker_endpoint_name"] 14 | bedrock_model_id = config["bedrock_model_id"] 15 | sagemaker_model_id = config["sagemaker_model_id"] # Updated field 16 | 17 | # Initialize AWS clients in their respective regions 18 | sagemaker_client = boto3.client("sagemaker-runtime", region_name=sagemaker_region) 19 | bedrock_client = boto3.client("bedrock-runtime", region_name=bedrock_region) 20 | 21 | # Streamlit UI 22 | st.title("Insurance Customer Support Chatbot") 23 | st.write("This app uses the Mistral-7b-Insurance model deployed on SageMaker or Bedrock to answer questions about insurance.") 24 | 25 | # Model selection 26 | model_choice = st.radio("Select the model to use:", ("SageMaker", "Bedrock")) 27 | 28 | # Pre-defined prompts for user selection 29 | predefined_prompts = [ 30 | "Can you help me understand my health insurance benefits?", 31 | "What does my policy cover if I need to see a specialist?", 32 | "Are dental treatments covered in my current insurance plan?", 33 | "How do I file a claim for a recent doctor visit?", 34 | "Can you explain what deductible means in my policy?", 35 | "Tell me about insurance and its risks", 36 | "How can I reduce my monthly insurance premium" 37 | ] 38 | 39 | # Dropdown for predefined prompts with an option to edit or enter a custom query 40 | selected_prompt = st.selectbox("Choose a question or enter your own:", predefined_prompts) 41 | user_query = st.text_input("Your question:", value=selected_prompt) 42 | 43 | # Function to query the model on SageMaker 44 | def query_sagemaker_model(endpoint_name, query): 45 | payload = { 46 | "model": sagemaker_model_id, # Updated model name from config 47 | "messages": [ 48 | {"role": "system", "content": "You are an expert in customer support for Insurance."}, 49 | {"role": "user", "content": query} # Send the user query as a string 50 | ], 51 | "parameters": { 52 | "do_sample": True, 53 | "max_new_tokens": 128, 54 | "temperature": 0.7, 55 | "top_k": 50, 56 | "top_p": 0.95, 57 | } 58 | } 59 | 60 | try: 61 | # Send the request to SageMaker endpoint 62 | response = sagemaker_client.invoke_endpoint( 63 | EndpointName=endpoint_name, 64 | ContentType="application/json", 65 | Body=json.dumps(payload) 66 | ) 67 | 68 | # Parse the response 69 | result = json.loads(response['Body'].read()) 70 | return result['choices'][0]['message']['content'] 71 | 72 | except ClientError as e: 73 | st.error(f"An error occurred with SageMaker: {e.response['Error']['Message']}") 74 | return None 75 | 76 | # Function to query the model on Bedrock with streaming 77 | def query_bedrock_model(model_id, query): 78 | # Set base inference configuration 79 | inference_config = { 80 | "temperature": 0.5, # Adjust temperature as needed 81 | "maxTokens": 1024, # Set maximum tokens if you want a longer response 82 | "topP": 0.95 # This is accepted directly by Bedrock in inferenceConfig 83 | } 84 | 85 | # Additional model-specific fields 86 | additional_model_fields = { 87 | "top_k": 200 # Set top_k here, as it’s not part of the core inferenceConfig 88 | } 89 | 90 | # Attempt to stream the response 91 | try: 92 | response = bedrock_client.converse_stream( 93 | modelId=model_id, 94 | messages=[ 95 | { 96 | "role": "user", 97 | "content": [{"text": query}] 98 | } 99 | ], 100 | inferenceConfig=inference_config, 101 | additionalModelRequestFields=additional_model_fields # Pass additional fields here 102 | ) 103 | 104 | # Display response incrementally as the stream is received 105 | full_response = "" # Collects the full response text 106 | stream = response.get('stream', []) 107 | 108 | # Streamlit placeholder for updating the response in real-time 109 | response_placeholder = st.empty() 110 | 111 | for event in stream: 112 | if 'contentBlockDelta' in event: 113 | delta_text = event['contentBlockDelta']['delta']['text'] 114 | full_response += delta_text 115 | response_placeholder.text(full_response) # Update displayed text in real-time 116 | 117 | # Check for end of message 118 | if 'messageStop' in event: 119 | break 120 | 121 | return full_response 122 | 123 | except ClientError as e: 124 | st.error(f"An error occurred with Bedrock: {e.response['Error']['Message']}") 125 | return None 126 | 127 | 128 | # Display the response 129 | if user_query: 130 | st.write("Querying the model...") 131 | if model_choice == "SageMaker": 132 | model_response = query_sagemaker_model(sagemaker_endpoint_name, user_query) 133 | if model_response: 134 | st.write("Response from the model:") 135 | st.write(model_response) 136 | else: 137 | # response will be streamed 138 | model_response = query_bedrock_model(bedrock_model_id, user_query) 139 | 140 | 141 | -------------------------------------------------------------------------------- /notebooks/Mistral-7B-Insurance-Neuron/streamlit-chatbot-video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/Mistral-7B-Insurance-Neuron/streamlit-chatbot-video.gif -------------------------------------------------------------------------------- /notebooks/Mistral-on-AWS-Neuron/Mathstral/gradio_neuron/mathstral_chat.py: -------------------------------------------------------------------------------- 1 | import gradio as gr 2 | import boto3 3 | import json 4 | import io 5 | 6 | # hyperparameters for llm 7 | parameters = { 8 | "model": "nithiyn/mathstral-neuron", # placholder, needed 9 | "top_p": 0.6, 10 | "temperature": 0.9, 11 | "max_tokens": 2048, 12 | "stop": ["<|eot_id|>"], 13 | } 14 | 15 | system_prompt = ( 16 | "You are an helpful assistant called Mathstral, you are an expert at Math and Reasoning." 17 | ) 18 | 19 | 20 | # Helper for reading lines from a stream 21 | class LineIterator: 22 | def __init__(self, stream): 23 | self.byte_iterator = iter(stream) 24 | self.buffer = io.BytesIO() 25 | self.read_pos = 0 26 | 27 | def __iter__(self): 28 | return self 29 | 30 | def __next__(self): 31 | while True: 32 | self.buffer.seek(self.read_pos) 33 | line = self.buffer.readline() 34 | if line and line[-1] == ord("\n"): 35 | self.read_pos += len(line) 36 | return line[:-1] 37 | try: 38 | chunk = next(self.byte_iterator) 39 | except StopIteration: 40 | if self.read_pos < self.buffer.getbuffer().nbytes: 41 | continue 42 | raise 43 | if "PayloadPart" not in chunk: 44 | print("Unknown event type:" + chunk) 45 | continue 46 | self.buffer.seek(0, io.SEEK_END) 47 | self.buffer.write(chunk["PayloadPart"]["Bytes"]) 48 | 49 | 50 | # helper method to format prompt 51 | def create_messages_dict(message, history, system_prompt): 52 | messages = [] 53 | if system_prompt: 54 | messages.append({"role": "system", "content": system_prompt}) 55 | for user_prompt, bot_response in history: 56 | messages.append({"role": "user", "content": user_prompt}) 57 | messages.append({"role": "assistant", "content": bot_response}) 58 | messages.append({"role": "user", "content": message}) 59 | return messages 60 | 61 | 62 | def create_gradio_app( 63 | endpoint_name, 64 | session=boto3, 65 | parameters=parameters, 66 | system_prompt=system_prompt, 67 | share=True, 68 | ): 69 | smr = session.client("sagemaker-runtime") 70 | 71 | def generate( 72 | prompt, 73 | history, 74 | ): 75 | messages = create_messages_dict(prompt, history, system_prompt) 76 | 77 | request = {"messages": messages, **parameters, "stream": True} 78 | resp = smr.invoke_endpoint_with_response_stream( 79 | EndpointName=endpoint_name, 80 | Body=json.dumps(request), 81 | ContentType="application/json", 82 | ) 83 | 84 | output = "" 85 | for c in LineIterator(resp["Body"]): 86 | c = c.decode("utf-8") 87 | if c.startswith("data:"): 88 | chunk = json.loads(c.lstrip("data:").rstrip("/n"))["choices"][0] 89 | if chunk["finish_reason"]: 90 | break 91 | output += chunk["delta"]["content"] 92 | for stop_str in request["stop"]: 93 | if output.endswith(stop_str): 94 | output = output[: -len(stop_str)] 95 | output = output.rstrip() 96 | yield output 97 | 98 | yield output 99 | return output 100 | 101 | demo = gr.ChatInterface( 102 | generate, title="Chat with Mistral Mathstral", chatbot=gr.Chatbot(layout="panel") 103 | ) 104 | 105 | demo.queue().launch(share=share) 106 | -------------------------------------------------------------------------------- /notebooks/finetune-mistral-7b-scripts/requirements.txt: -------------------------------------------------------------------------------- 1 | transformers==4.50.0 2 | peft==0.4.0 3 | accelerate==0.27.2 4 | bitsandbytes==0.41.3 5 | safetensors==0.4.1 6 | tokenizers==0.19 7 | -------------------------------------------------------------------------------- /notebooks/finetune-mistral-7b-scripts/run_clm.py: -------------------------------------------------------------------------------- 1 | import os 2 | import argparse 3 | from transformers import ( 4 | AutoModelForCausalLM, 5 | AutoTokenizer, 6 | set_seed, 7 | default_data_collator, 8 | BitsAndBytesConfig, 9 | Trainer, 10 | TrainingArguments, 11 | ) 12 | from datasets import load_from_disk 13 | import torch 14 | 15 | import bitsandbytes as bnb 16 | from huggingface_hub import login, HfFolder 17 | 18 | 19 | def parse_arge(): 20 | """Parse the arguments.""" 21 | parser = argparse.ArgumentParser() 22 | # add model id and dataset path argument 23 | parser.add_argument( 24 | "--model_id", 25 | type=str, 26 | help="Model id to use for training.", 27 | ) 28 | parser.add_argument( 29 | "--dataset_path", type=str, default="lm_dataset", help="Path to dataset." 30 | ) 31 | parser.add_argument( 32 | "--hf_token", type=str, default=HfFolder.get_token(), help="Path to dataset." 33 | ) 34 | # add training hyperparameters for epochs, batch size, learning rate, and seed 35 | parser.add_argument( 36 | "--epochs", type=int, default=3, help="Number of epochs to train for." 37 | ) 38 | parser.add_argument( 39 | "--per_device_train_batch_size", 40 | type=int, 41 | default=1, 42 | help="Batch size to use for training.", 43 | ) 44 | parser.add_argument( 45 | "--lr", type=float, default=5e-5, help="Learning rate to use for training." 46 | ) 47 | parser.add_argument( 48 | "--seed", type=int, default=42, help="Seed to use for training." 49 | ) 50 | parser.add_argument( 51 | "--gradient_checkpointing", 52 | type=bool, 53 | default=True, 54 | help="Path to deepspeed config file.", 55 | ) 56 | parser.add_argument( 57 | "--bf16", 58 | type=bool, 59 | default=True if torch.cuda.get_device_capability()[0] == 8 else False, 60 | help="Whether to use bf16.", 61 | ) 62 | parser.add_argument( 63 | "--merge_weights", 64 | type=bool, 65 | default=True, 66 | help="Whether to merge LoRA weights with base model.", 67 | ) 68 | args, _ = parser.parse_known_args() 69 | 70 | if args.hf_token: 71 | print(f"Logging into the Hugging Face Hub with token {args.hf_token[:10]}...") 72 | login(token=args.hf_token) 73 | 74 | return args 75 | 76 | 77 | # COPIED FROM https://github.com/artidoro/qlora/blob/main/qlora.py 78 | def print_trainable_parameters(model, use_4bit=False): 79 | """ 80 | Prints the number of trainable parameters in the model. 81 | """ 82 | trainable_params = 0 83 | all_param = 0 84 | for _, param in model.named_parameters(): 85 | num_params = param.numel() 86 | # if using DS Zero 3 and the weights are initialized empty 87 | if num_params == 0 and hasattr(param, "ds_numel"): 88 | num_params = param.ds_numel 89 | 90 | all_param += num_params 91 | if param.requires_grad: 92 | trainable_params += num_params 93 | if use_4bit: 94 | trainable_params /= 2 95 | print( 96 | f"all params: {all_param:,d} || trainable params: {trainable_params:,d} || trainable%: {100 * trainable_params / all_param}" 97 | ) 98 | 99 | 100 | # COPIED FROM https://github.com/artidoro/qlora/blob/main/qlora.py 101 | def find_all_linear_names(model): 102 | lora_module_names = set() 103 | for name, module in model.named_modules(): 104 | if isinstance(module, bnb.nn.Linear4bit): 105 | names = name.split(".") 106 | lora_module_names.add(names[0] if len(names) == 1 else names[-1]) 107 | 108 | if "lm_head" in lora_module_names: # needed for 16-bit 109 | lora_module_names.remove("lm_head") 110 | return list(lora_module_names) 111 | 112 | 113 | def create_peft_model(model, gradient_checkpointing=True, bf16=True): 114 | from peft import ( 115 | get_peft_model, 116 | LoraConfig, 117 | TaskType, 118 | prepare_model_for_kbit_training, 119 | ) 120 | from peft.tuners.lora import LoraLayer 121 | 122 | # prepare int-4 model for training 123 | model = prepare_model_for_kbit_training( 124 | model, use_gradient_checkpointing=gradient_checkpointing 125 | ) 126 | if gradient_checkpointing: 127 | model.gradient_checkpointing_enable() 128 | 129 | # get lora target modules 130 | modules = find_all_linear_names(model) 131 | print(f"Found {len(modules)} modules to quantize: {modules}") 132 | 133 | peft_config = LoraConfig( 134 | r=64, 135 | lora_alpha=16, 136 | target_modules=modules, 137 | lora_dropout=0.1, 138 | bias="none", 139 | task_type=TaskType.CAUSAL_LM, 140 | ) 141 | 142 | model = get_peft_model(model, peft_config) 143 | 144 | # pre-process the model by upcasting the layer norms in float 32 for 145 | for name, module in model.named_modules(): 146 | if isinstance(module, LoraLayer): 147 | if bf16: 148 | module = module.to(torch.bfloat16) 149 | if "norm" in name: 150 | module = module.to(torch.float32) 151 | if "lm_head" in name or "embed_tokens" in name: 152 | if hasattr(module, "weight"): 153 | if bf16 and module.weight.dtype == torch.float32: 154 | module = module.to(torch.bfloat16) 155 | 156 | model.print_trainable_parameters() 157 | return model 158 | 159 | 160 | def training_function(args): 161 | # set seed 162 | set_seed(args.seed) 163 | 164 | dataset = load_from_disk(args.dataset_path) 165 | # load model from the hub with a bnb config 166 | bnb_config = BitsAndBytesConfig( 167 | load_in_4bit=True, 168 | bnb_4bit_use_double_quant=True, 169 | bnb_4bit_quant_type="nf4", 170 | bnb_4bit_compute_dtype=torch.bfloat16, 171 | ) 172 | 173 | model = AutoModelForCausalLM.from_pretrained( 174 | args.model_id, 175 | use_cache=False 176 | if args.gradient_checkpointing 177 | else True, # this is needed for gradient checkpointing 178 | device_map="auto", 179 | quantization_config=bnb_config, 180 | ) 181 | 182 | # create peft config 183 | model = create_peft_model( 184 | model, gradient_checkpointing=args.gradient_checkpointing, bf16=args.bf16 185 | ) 186 | 187 | # Define training args 188 | output_dir = "/tmp/mistral" 189 | training_args = TrainingArguments( 190 | output_dir=output_dir, 191 | per_device_train_batch_size=args.per_device_train_batch_size, 192 | bf16=args.bf16, # Use BF16 if available 193 | learning_rate=args.lr, 194 | num_train_epochs=args.epochs, 195 | gradient_checkpointing=args.gradient_checkpointing, 196 | # logging strategies 197 | logging_dir=f"{output_dir}/logs", 198 | logging_strategy="steps", 199 | logging_steps=10, 200 | save_strategy="no", 201 | ) 202 | 203 | # Create Trainer instance 204 | trainer = Trainer( 205 | model=model, 206 | args=training_args, 207 | train_dataset=dataset, 208 | data_collator=default_data_collator, 209 | ) 210 | 211 | # Start training 212 | trainer.train() 213 | 214 | sagemaker_save_dir="/opt/ml/model/" 215 | if args.merge_weights: 216 | # merge adapter weights with base model and save 217 | # save int 4 model 218 | trainer.model.save_pretrained(output_dir, safe_serialization=False) 219 | # clear memory 220 | del model 221 | del trainer 222 | torch.cuda.empty_cache() 223 | 224 | from peft import AutoPeftModelForCausalLM 225 | 226 | # load PEFT model in fp16 227 | model = AutoPeftModelForCausalLM.from_pretrained( 228 | output_dir, 229 | low_cpu_mem_usage=True, 230 | torch_dtype=torch.float16, 231 | ) 232 | # Merge LoRA and base model and save 233 | model = model.merge_and_unload() 234 | model.save_pretrained( 235 | sagemaker_save_dir, safe_serialization=True, max_shard_size="2GB" 236 | ) 237 | else: 238 | trainer.model.save_pretrained( 239 | sagemaker_save_dir, safe_serialization=True 240 | ) 241 | 242 | # save tokenizer for easy inference 243 | tokenizer = AutoTokenizer.from_pretrained(args.model_id) 244 | tokenizer.save_pretrained(sagemaker_save_dir) 245 | 246 | 247 | def main(): 248 | args = parse_arge() 249 | training_function(args) 250 | 251 | 252 | if __name__ == "__main__": 253 | main() 254 | -------------------------------------------------------------------------------- /notebooks/imgs/imgs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /notebooks/imgs/llamaindex-agentic-rag-mistral-large2-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/imgs/llamaindex-agentic-rag-mistral-large2-arch.png -------------------------------------------------------------------------------- /notebooks/imgs/mapreduce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/imgs/mapreduce.png -------------------------------------------------------------------------------- /notebooks/imgs/mistral-aws-partnership-img.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/imgs/mistral-aws-partnership-img.jpeg -------------------------------------------------------------------------------- /notebooks/imgs/mistral-large-2407-code-generation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/imgs/mistral-large-2407-code-generation.png -------------------------------------------------------------------------------- /notebooks/imgs/mistral-large-2407-language-diversity.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/imgs/mistral-large-2407-language-diversity.webp -------------------------------------------------------------------------------- /notebooks/imgs/mistral-large-2407-multiple.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/imgs/mistral-large-2407-multiple.webp -------------------------------------------------------------------------------- /notebooks/imgs/mistral-large-2407-tool-use.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/imgs/mistral-large-2407-tool-use.png -------------------------------------------------------------------------------- /notebooks/imgs/mistralaws.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/imgs/mistralaws.png -------------------------------------------------------------------------------- /notebooks/imgs/multilingual-mmlu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/imgs/multilingual-mmlu.png -------------------------------------------------------------------------------- /notebooks/imgs/nemo-base-performance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/imgs/nemo-base-performance.png -------------------------------------------------------------------------------- /notebooks/imgs/nemo-instruct-performance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/imgs/nemo-instruct-performance.png -------------------------------------------------------------------------------- /notebooks/imgs/refine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/imgs/refine.png -------------------------------------------------------------------------------- /notebooks/mistral-llamaindex-agentic-rag/README.md: -------------------------------------------------------------------------------- 1 | # Creating an Agentic RAG Application with LlamaIndex, Mistral and Amazon Bedrock for Advanced Knowledge Discovery 2 | 3 | ## Introduction 4 | 5 | Agentic RAG (Retrieval-Augmented Generation) applications represent an advanced approach in AI that integrates large language models (LLMs) with external knowledge retrieval and autonomous agent capabilities. These systems dynamically access and process information, break down complex tasks, utilise external tools, apply reasoning, and adapt to various contexts. They go beyond simple question-answering by performing multi-step processes, making decisions, and generating complex outputs. 6 | 7 | In this notebook, we demonstrate an example of building an agentic RAG application using the LlamaIndex framework. This application serves as a technology discovery and research tool, using the Mistral Large 2 model via Bedrock Converse as the LLM to orchestrate agent flow and generate responses. It interacts with well-known websites, such as Arxiv, GitHub, and TechCrunch, and can access knowledge bases containing documentation and internal knowledge. 8 | 9 | This application can be further expanded to accommodate broader use cases requiring dynamic interaction with internal and external APIs, as well as the integration of internal knowledge bases to provide more context-aware responses to user queries. 10 | 11 | --- 12 | 13 | ## Prerequisites 🔥 14 | 15 | - At the time of writing this notebook, the Mistral Large 2 model is only available in the `us-west-2` region. 16 | - Create an Amazon SageMaker domain. 17 | - Create a SageMaker domain user profile. 18 | - Launch Amazon SageMaker Studio, select JupyterLab, and create a space. 19 | - Select the instance `ml.t3.medium` and the image `SageMaker Distribution 2.3.1`, then run the space. 20 | - On the IAM console, create an inline policy for the SageMaker Notebook execution role and add the following JSON configuration to the policy: 21 | ```json 22 | { 23 | "Version": "2012-10-17", 24 | "Statement": [ 25 | { 26 | "Effect": "Allow", 27 | "Action": [ 28 | "bedrock:Rerank", 29 | "bedrock:Retrieve", 30 | "bedrock:InvokeModel", 31 | "bedrock:InvokeModelWithResponseStream", 32 | "bedrock:ListFoundationModels" 33 | ], 34 | "Resource": "*" 35 | }, 36 | { 37 | "Effect": "Allow", 38 | "Action": [ 39 | "iam:CreatePolicy", 40 | "iam:AttachRolePolicy" 41 | ], 42 | "Resource": [ 43 | "arn:aws:iam:::role/*", 44 | "arn:aws:iam:::policy/*" 45 | ] 46 | }, 47 | { 48 | "Effect": "Allow", 49 | "Action": [ 50 | "aoss:*" 51 | ], 52 | "Resource": "*" 53 | } 54 | ] 55 | } 56 | ``` 57 | - Navigate to the AWS Bedrock service in the AWS console. On the left banner, select “Model access.” Click on “Modify model access.” Select the models: Mistral Large 2 (24.07), Titan Text Embeddings V2, and Rerank 1.0 from the list, and request access to these models. 58 | 59 | 60 | --- 61 | 62 | ## Architecture 63 | 64 | This solution uses the LlamaIndex framework to build an agent flow with two main components: [AgentRunner and AgentWorker](https://docs.llamaindex.ai/en/stable/module_guides/deploying/agents/agent_runner/). The AgentRunner serves as an orchestrator that manages conversation history, creates and maintains tasks, executes task steps, and provides a user-friendly interface for interactions. The AgentWorker handles the step-by-step reasoning and task execution. 65 | 66 | For reasoning and task planning, we use Mistral Large 2 model from Amazon Bedrock. The agent integrates with GitHub, arXiv, TechCrunch and DuckDuckGo APIs, while also accessing internal knowledge through Bedrock Knowledge Bases and Amazon OpenSearch Serverless to provide context-aware answers. 67 | 68 | 69 | architecture 70 | 71 | ## Next Step 72 | Please open the notebook "mistral_agentic_rag_with_llamaindex.ipynb" and follow the instructions to build the solution. 73 | -------------------------------------------------------------------------------- /notebooks/mistral-llamaindex-agentic-rag/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/mistral-llamaindex-agentic-rag/architecture.png -------------------------------------------------------------------------------- /notebooks/mistral-llamaindex-agentic-rag/docs/genai_on_aws.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/mistral-llamaindex-agentic-rag/docs/genai_on_aws.pdf -------------------------------------------------------------------------------- /notebooks/mistral-llamaindex-agentic-rag/docs/ml_on_aws.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/mistral-on-aws/cd00df1e21c8a18520d52083294a2b48658182c8/notebooks/mistral-llamaindex-agentic-rag/docs/ml_on_aws.pdf -------------------------------------------------------------------------------- /notebooks/mistral-llamaindex-agentic-rag/requirements.txt: -------------------------------------------------------------------------------- 1 | llama-index 2 | llama-index-llms-bedrock-converse 3 | llama-index-embeddings-bedrock 4 | llama-index-retrievers-bedrock 5 | llama-index-tools-arxiv 6 | llama-index-tools-duckduckgo 7 | llama-index-postprocessor-bedrock-rerank 8 | llama-index-vector-stores-opensearch 9 | feedparser 10 | opensearch-py 11 | requests-aws4auth -------------------------------------------------------------------------------- /notebooks/mistral-llamaindex-agentic-rag/utils.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import json 3 | from urllib.parse import urlparse 4 | from opensearchpy import OpenSearch, RequestsHttpConnection, AWSV4SignerAuth 5 | 6 | 7 | boto3_session = boto3.session.Session() 8 | region_name = boto3_session.region_name 9 | account_number = boto3.client('sts').get_caller_identity().get('Account') 10 | identity = boto3.client('sts').get_caller_identity()['Arn'] 11 | iam_client = boto3.client('iam') 12 | 13 | def create_oss_policy_attach_execution_role(collection_id, notebook_execution_role): 14 | 15 | # define oss policy document 16 | oss_policy_document = { 17 | "Version": "2012-10-17", 18 | "Statement": [ 19 | { 20 | "Effect": "Allow", 21 | "Action": [ 22 | "aoss:APIAccessAll" 23 | ], 24 | "Resource": [ 25 | f"arn:aws:aoss:{region_name}:{account_number}:collection/{collection_id}" 26 | ] 27 | } 28 | ] 29 | } 30 | 31 | oss_policy_name = collection_id + '-blog-oss' 32 | 33 | oss_policy = iam_client.create_policy( 34 | PolicyName=oss_policy_name, 35 | PolicyDocument=json.dumps(oss_policy_document), 36 | Description='Policy for accessing opensearch serverless', 37 | ) 38 | oss_policy_arn = oss_policy["Policy"]["Arn"] 39 | # print("Opensearch serverless policy arn: ", oss_policy_arn) 40 | 41 | iam_client.attach_role_policy( 42 | RoleName=notebook_execution_role.split('/')[-1], 43 | PolicyArn=oss_policy_arn 44 | ) 45 | return None 46 | 47 | 48 | def create_policies_in_oss(collection_name, aoss_client, notebook_execution_role): 49 | 50 | encryption_policy_name = collection_name + '-blog-encryption' 51 | encryption_policy = aoss_client.create_security_policy( 52 | name=encryption_policy_name, 53 | policy=json.dumps( 54 | { 55 | 'Rules': [{'Resource': ['collection/' + collection_name], 56 | 'ResourceType': 'collection'}], 57 | 'AWSOwnedKey': True 58 | }), 59 | type='encryption' 60 | ) 61 | 62 | network_policy_name = collection_name + '-blog-network' 63 | network_policy = aoss_client.create_security_policy( 64 | name=network_policy_name, 65 | policy=json.dumps( 66 | [ 67 | {'Rules': [{'Resource': ['collection/' + collection_name], 68 | 'ResourceType': 'collection'}], 69 | 'AllowFromPublic': True} 70 | ]), 71 | type='network' 72 | ) 73 | 74 | access_policy_name = collection_name + '-blog-access' 75 | access_policy = aoss_client.create_access_policy( 76 | name=access_policy_name, 77 | policy=json.dumps( 78 | [ 79 | { 80 | 'Rules': [ 81 | { 82 | 'Resource': ['collection/' + collection_name], 83 | 'Permission': [ 84 | 'aoss:CreateCollectionItems', 85 | 'aoss:DeleteCollectionItems', 86 | 'aoss:UpdateCollectionItems', 87 | 'aoss:DescribeCollectionItems'], 88 | 'ResourceType': 'collection' 89 | }, 90 | { 91 | 'Resource': ['index/' + collection_name + '/*'], 92 | 'Permission': [ 93 | 'aoss:CreateIndex', 94 | 'aoss:DeleteIndex', 95 | 'aoss:UpdateIndex', 96 | 'aoss:DescribeIndex', 97 | 'aoss:ReadDocument', 98 | 'aoss:WriteDocument'], 99 | 'ResourceType': 'index' 100 | }], 101 | 'Principal': [identity, notebook_execution_role], 102 | 'Description': 'Easy data policy'} 103 | ]), 104 | type='data' 105 | ) 106 | return encryption_policy, network_policy, access_policy 107 | 108 | 109 | def create_collection(collection_name, notebook_execution_role): 110 | aoss_client = boto3.client('opensearchserverless') 111 | access_policy = create_policies_in_oss(collection_name, aoss_client, notebook_execution_role) 112 | collection = aoss_client.create_collection(name=collection_name,type='VECTORSEARCH', standbyReplicas='DISABLED') 113 | 114 | collection_id = collection['createCollectionDetail']['id'] 115 | create_oss_policy_attach_execution_role(collection_id, notebook_execution_role) 116 | 117 | endpoint ='https://' + collection_id + '.' + region_name + '.aoss.amazonaws.com:443' 118 | return endpoint 119 | 120 | 121 | def create_index(index_name, endpoint, emb_dim=1024): 122 | service = 'aoss' 123 | credentials = boto3.Session().get_credentials() 124 | awsauth = AWSV4SignerAuth(credentials, "us-west-2", service) 125 | 126 | parsed_url = urlparse(endpoint) 127 | host = parsed_url.netloc.split(':')[0] 128 | 129 | # Build the OpenSearch client 130 | oss_client = OpenSearch( 131 | hosts=[{'host': host, 'port': 443}], 132 | http_auth=awsauth, 133 | use_ssl=True, 134 | verify_certs=True, 135 | connection_class=RequestsHttpConnection, 136 | timeout=300 137 | ) 138 | 139 | # Prepare index configurations 140 | index_body = { 141 | "settings": { 142 | "index.knn": "true", 143 | "number_of_shards": 1, 144 | "knn.algo_param.ef_search": 512, 145 | "number_of_replicas": 0, 146 | }, 147 | "mappings": { 148 | "properties": { 149 | "vector": { 150 | "type": "knn_vector", 151 | "dimension": emb_dim, 152 | "method": { 153 | "name": "hnsw", 154 | "engine": "faiss", 155 | "space_type": "l2" 156 | }, 157 | }, 158 | "chunk": {"type": "text"}, 159 | } 160 | } 161 | } 162 | try: 163 | response = oss_client.indices.create(index_name, body=index_body) 164 | print(f"response received for the create index -> {response}") 165 | except Exception as e: 166 | print(f"error in creating index={index_name}, exception={e}") -------------------------------------------------------------------------------- /notebooks/mixtral_finetune_qlora_sft/scripts/merge_model_adapter.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import random 4 | import torch 5 | from transformers import AutoTokenizer, TrainingArguments 6 | from transformers import ( 7 | AutoModelForCausalLM, 8 | AutoTokenizer, 9 | BitsAndBytesConfig, 10 | set_seed, 11 | ) 12 | from typing import Dict, Optional, Tuple 13 | import argparse 14 | from datasets import load_dataset 15 | 16 | 17 | def set_custom_env(env_vars: Dict[str, str]) -> None: 18 | """ 19 | Set custom environment variables. 20 | 21 | Args: 22 | env_vars (Dict[str, str]): A dictionary of environment variables to set. 23 | Keys are variable names, values are their corresponding values. 24 | 25 | Returns: 26 | None 27 | 28 | Raises: 29 | TypeError: If env_vars is not a dictionary. 30 | ValueError: If any key or value in env_vars is not a string. 31 | """ 32 | if not isinstance(env_vars, dict): 33 | raise TypeError("env_vars must be a dictionary") 34 | 35 | for key, value in env_vars.items(): 36 | if not isinstance(key, str) or not isinstance(value, str): 37 | raise ValueError("All keys and values in env_vars must be strings") 38 | 39 | os.environ.update(env_vars) 40 | 41 | # Optionally, print the updated environment variables 42 | print("Updated environment variables:") 43 | for key, value in env_vars.items(): 44 | print(f" {key}: {value}") 45 | 46 | 47 | def create_test_prompt(): 48 | dataset = load_dataset( 49 | "json", 50 | data_files=os.path.join(args.testdata, "dataset.json"), 51 | split="train" 52 | ) 53 | 54 | # Shuffle the dataset and select the first row 55 | random_row = dataset.shuffle().select(range(1))[0] 56 | 57 | return random_row 58 | 59 | 60 | def generate_text(model, prompt, max_length=500, num_return_sequences=1): 61 | # Encode the input prompt 62 | tokenizer = AutoTokenizer.from_pretrained( 63 | args.model_id, 64 | use_fast=True 65 | ) 66 | 67 | device = "cuda" if torch.cuda.is_available() else "cpu" 68 | tokenizer.pad_token = tokenizer.eos_token 69 | 70 | prompt_input=prompt['prompt'].split("### Meaning representation")[0] + "### Meaning representation" 71 | 72 | print(prompt_input) 73 | 74 | input_ids = tokenizer.encode(prompt_input, return_tensors="pt").to(device) 75 | 76 | # Generate text 77 | with torch.no_grad(): 78 | output = model.generate( 79 | input_ids, 80 | max_length=max_length, 81 | num_return_sequences=num_return_sequences, 82 | no_repeat_ngram_size=2, 83 | top_k=50, 84 | top_p=0.95, 85 | temperature=0.7 86 | ) 87 | 88 | # Decode and return the generated text 89 | generated_texts = [tokenizer.decode(seq, skip_special_tokens=True) for seq in output] 90 | 91 | return generated_texts 92 | 93 | def merge_and_save_model(model_id, adapter_dir, output_dir): 94 | from peft import PeftModel 95 | 96 | print("Trying to load a Peft model. It might take a while without feedback") 97 | base_model = AutoModelForCausalLM.from_pretrained( 98 | model_id, 99 | low_cpu_mem_usage=True, 100 | #torch_dtype=torch.float16, 101 | device_map="auto", 102 | #offload_folder="/opt/ml/model/" 103 | ) 104 | 105 | print("Loaded base model") 106 | 107 | prompt=create_test_prompt() 108 | 109 | print(f"\n\n\n*** Generating Inference on Base Model: {generate_text(base_model,prompt)}\n\n\n") 110 | 111 | base_model.config.use_cache = False 112 | 113 | # Load the adapter 114 | peft_model = PeftModel.from_pretrained( 115 | base_model, 116 | adapter_dir, 117 | #torch_dtype=torch.float16, # Set dtype to float16 118 | #offload_folder="/opt/ml/model/" 119 | ) 120 | 121 | print("Loaded peft model") 122 | model = peft_model.merge_and_unload() 123 | print("Merge done") 124 | 125 | print(f"***\n\n\n Generating Inference on Trained Model: {generate_text(model,prompt)}\n\n\n") 126 | 127 | os.makedirs(output_dir, exist_ok=True) 128 | 129 | print(f"Saving the newly created merged model to {output_dir}") 130 | model.save_pretrained(output_dir, safe_serialization=True) 131 | base_model.config.save_pretrained(output_dir) 132 | 133 | 134 | def parse_arge(): 135 | 136 | parser = argparse.ArgumentParser() 137 | 138 | # infra configuration 139 | parser.add_argument("--adapterdir", type=str, default=os.environ["SM_CHANNEL_ADAPTER"]) 140 | parser.add_argument("--testdata", type=str, default=os.environ["SM_CHANNEL_TESTDATA"]) 141 | 142 | parser.add_argument("--model_id", type=str, default="meta-llama/Meta-Llama-3.1-8B") 143 | parser.add_argument("--hf_token", type=str, default="") 144 | parser.add_argument("--dataset_name", type=str, default="") 145 | 146 | args = parser.parse_known_args() 147 | 148 | return args 149 | 150 | if __name__ == "__main__": 151 | 152 | args, _ = parse_arge() 153 | 154 | custom_env: Dict[str, str] = {"HF_DATASETS_TRUST_REMOTE_CODE": "TRUE", 155 | "HF_TOKEN": args.hf_token 156 | } 157 | set_custom_env(custom_env) 158 | 159 | # launch training 160 | merge_and_save_model(args.model_id, args.adapterdir,"/opt/ml/model/merged/") 161 | -------------------------------------------------------------------------------- /notebooks/mixtral_finetune_qlora_sft/scripts/requirements.txt: -------------------------------------------------------------------------------- 1 | transformers==4.50.0 2 | datasets==2.18.0 3 | accelerate==0.33.0 4 | evaluate==0.4.1 5 | bitsandbytes==0.43.3 6 | huggingface_hub==0.23.2 7 | trl==0.9.6 8 | peft==0.12.0 9 | wandb 10 | py7zr -------------------------------------------------------------------------------- /notebooks/sample_data/members.json: -------------------------------------------------------------------------------- 1 | { 2 | "C2345678901": { 3 | "profile": { 4 | "name": "Cody Johnson", 5 | "member_id": "C2345678901", 6 | "address": "6785 Mistral Drive , Dallas Tx 15241" 7 | }, 8 | 9 | "insurance": { 10 | "name": "Apex Health", 11 | "payer_id": 345678, 12 | "payer_id_type": "Group Number", 13 | "policy_name": "PPO Plan", 14 | "policy_information": 567890, 15 | "plan_name": "PPO 500", 16 | "pcp": "Dr. Perry", 17 | "pcp_id": 456168868 18 | }, 19 | "claims": [ 20 | { 21 | "claim": "34567890123", 22 | "type": "Medical", 23 | "provider": { 24 | "name": "Southwest Medical Center", 25 | "provider_id": 2345678901, 26 | "provider_id_type": "TIN", 27 | "provider_billing_address": "100 Main St, Dallas, TX 75201" 28 | }, 29 | "date": { 30 | "start_date": 20210201, 31 | "end_date": 20210203 32 | }, 33 | "charges": { 34 | "price_billed": 2500, 35 | "negotiated_price": 2000, 36 | "insurance_paid": 1500, 37 | "patient_responsibility": 500 38 | }, 39 | "service": { 40 | "name": "Outpatient Surgery", 41 | "code": "29807" 42 | } 43 | }, 44 | { 45 | "claim": "101112131415", 46 | "type": "Pharmacy", 47 | "pharmacy": { 48 | "name": "Walmart Pharmacy", 49 | "provider_id": 4561237890, 50 | "provider_id_type": "NCPDP" 51 | }, 52 | "date": 20210215, 53 | "drug": { 54 | "name": "Lisinopril", 55 | "code": "3456780291", 56 | "fill_number": 1, 57 | "days_supply": 30 58 | }, 59 | "prescriber": { 60 | "identifier": 3345678901, 61 | "name": "Jane Doe" 62 | } 63 | } 64 | ] 65 | }, 66 | "B4567891234": { 67 | "profile": { 68 | "name": "Sarah Williams", 69 | "member_id": "B4567891234", 70 | "address": "786 Strawberry Grove Rd, Dallas TX 23418" 71 | }, 72 | "insurance": { 73 | "name": "Apex Health", 74 | "payer_id": 345678, 75 | "payer_id_type": "Group Number", 76 | "policy_name": "Medicare advantage Plan", 77 | "policy_information": 567890, 78 | "plan_name": "HMO 2000", 79 | "pcp": "Dr. Malhotra", 80 | "pcp_id": 45616768 81 | }, 82 | "claims": [ 83 | { 84 | "claim": "23456787654", 85 | "type": "Medical", 86 | "provider": { 87 | "name": "Memorial Hospital", 88 | "provider_id": 4561237890, 89 | "provider_id_type": "TIN", 90 | "provider_billing_address": "200 Memorial Dr, Boston, MA 02129" 91 | }, 92 | "date": { 93 | "start_date": 20201201, 94 | "end_date": 20201203 95 | }, 96 | "charges": { 97 | "price_billed": 7500, 98 | "negotiated_price": 6000, 99 | "insurance_paid": 5000, 100 | "patient_responsibility": 1000 101 | }, 102 | "service": { 103 | "name": "Appendectomy", 104 | "code": "47100" 105 | } 106 | }, 107 | { 108 | "claim": "98765432109", 109 | "type": "Pharmacy", 110 | "pharmacy": { 111 | "name": "Walgreens", 112 | "provider_id": 9876543210, 113 | "provider_id_type": "NCPDP" 114 | }, 115 | "date": 20201205, 116 | "drug": { 117 | "name": "Amoxicillin", 118 | "code": "1234567899", 119 | "fill_number": 2, 120 | "days_supply": 14 121 | }, 122 | "prescriber": { 123 | "identifier": 2345678901, 124 | "name": "Dr. Meredith Grey" 125 | } 126 | }, 127 | { 128 | "claim": "932109", 129 | "type": "Pharmacy", 130 | "pharmacy": { 131 | "name": "Walgreens", 132 | "provider_id": 9876543210, 133 | "provider_id_type": "NCPDP" 134 | }, 135 | "date": 20201205, 136 | "drug": { 137 | "name": "Coumadin", 138 | "code": "1234567899", 139 | "fill_number": 3, 140 | "days_supply": 30 141 | }, 142 | "prescriber": { 143 | "identifier": 2345678901, 144 | "name": "Dr. Meredith Grey" 145 | }, 146 | "status": "denied", 147 | "status_reason": "No medical necessity." 148 | } 149 | ] 150 | }, 151 | "D12345678": { 152 | "profile": { 153 | "name": "Mary Anderson", 154 | "member_id": "D12345678", 155 | "address": "3456 Clear Pond Lane, Dallas, TX 75231" 156 | }, 157 | "insurance": { 158 | "name": "Apex Health", 159 | "payer_id": 345678, 160 | "payer_id_type": "Group Number", 161 | "policy_name": "PPO Plan", 162 | "policy_information": 5678190, 163 | "plan_name": "PPO 500 HD", 164 | "pcp": "Dr. Morano", 165 | "pcp_id": 45016768 166 | }, 167 | "claims": [ 168 | { 169 | "claimNumber": "987654321", 170 | "dateOfService": "2023-01-15", 171 | "provider": { 172 | "name": "Memorial Hospital", 173 | "provider_billing_address": "100 Main St, Austin, TX 75201", 174 | "npi": "123456789" 175 | }, 176 | "type": "Medical", 177 | "charges": { 178 | "billedAmount": 2500, 179 | "paidAmount": 2000, 180 | "patientResponsibility": 500 181 | }, 182 | "procedureCode": "99214", 183 | "diagnosisCodes": ["E11.9", "J44.9"] 184 | }, 185 | { 186 | "claimNumber": "112233445", 187 | "dateOfService": "2023-01-31", 188 | "pharmacy": { 189 | "name": "CVS Pharmacy", 190 | "npi": "987654321" 191 | }, 192 | "type": "Pharmacy", 193 | "prescription": { 194 | "drugName": "Lisinopril", 195 | "ndc": "12345678910", 196 | "daysSupply": 30 197 | } 198 | } 199 | ] 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /notebooks/sample_data/transactions.json: -------------------------------------------------------------------------------- 1 | { 2 | "transaction_id": [ 3 | "T1001", 4 | "T1002", 5 | "T1003", 6 | "T1004", 7 | "T1005" 8 | ], 9 | "customer_id": [ 10 | "C001", 11 | "C002", 12 | "C003", 13 | "C002", 14 | "C001" 15 | ], 16 | "payment_amount": [ 17 | 125.5, 18 | 89.99, 19 | 120.0, 20 | 54.3, 21 | 210.2 22 | ], 23 | "payment_date": [ 24 | "2021-10-05", 25 | "2021-10-06", 26 | "2021-10-07", 27 | "2021-10-05", 28 | "2021-10-08" 29 | ], 30 | "payment_status": [ 31 | "Paid", 32 | "Unpaid", 33 | "Paid", 34 | "Paid", 35 | "Pending" 36 | ] 37 | } --------------------------------------------------------------------------------