diff --git a/bootstrap/database/db-init-job.yaml b/bootstrap/database/db-init-job.yaml index eecd8fa..06878a7 100644 --- a/bootstrap/database/db-init-job.yaml +++ b/bootstrap/database/db-init-job.yaml @@ -13,7 +13,7 @@ spec: command: ['sh', '-c', 'until nc -z -v -w30 $POSTGRESQL_DATABASE 5432; do echo "Waiting for database connection..."; sleep 2; done;'] env: - name: POSTGRESQL_DATABASE - value: claimdb.ic-shared-db.svc.cluster.local + value: agenticdb.agentic-db.svc.cluster.local containers: - name: postgresql image: registry.redhat.io/rhel9/postgresql-13:latest @@ -21,20 +21,20 @@ spec: - name: POSTGRESQL_DATABASE valueFrom: secretKeyRef: - name: claimdb + name: agenticdb key: database-name - name: POSTGRESQL_USER valueFrom: secretKeyRef: - name: claimdb + name: agenticdb key: database-user - name: PGPASSWORD valueFrom: secretKeyRef: - name: claimdb + name: agenticdb key: database-password - name: POSTGRESQL_DATABASE_HOST - value: claimdb.ic-shared-db.svc.cluster.local + value: agenticdb.agentic-db.svc.cluster.local command: ["/bin/bash", "-c"] args: - | diff --git a/bootstrap/database/deployment.yaml b/bootstrap/database/deployment.yaml index c359be1..fd670af 100644 --- a/bootstrap/database/deployment.yaml +++ b/bootstrap/database/deployment.yaml @@ -1,19 +1,19 @@ apiVersion: apps/v1 kind: Deployment metadata: - namespace: ic-shared-db - name: ic-shared-db + namespace: agentic-zone + name: agentic-db annotations: argocd.argoproj.io/sync-wave: "1" spec: selector: matchLabels: - app: ic-shared-db + app: agentic-db replicas: 1 template: metadata: labels: - app: ic-shared-db + app: agentic-db spec: containers: - name: postgresql diff --git a/bootstrap/database/kustomization.yaml b/bootstrap/database/kustomization.yaml index 31539b1..2a4e3bd 100644 --- a/bootstrap/database/kustomization.yaml +++ b/bootstrap/database/kustomization.yaml @@ -2,21 +2,17 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization -namespace: ic-shared-db +namespace: agentic-zone commonLabels: - component: ic-shared-db + component: agentic-zone resources: -# wave 0 -- namespace.yaml # wave 1 - pvc.yaml - secret.yaml -- secret-minio.yaml - deployment.yaml - service.yaml -- sql-script-configmap.yaml +# - sql-script-configmap.yaml # wave 2 - db-init-job.yaml -- populate-images.yaml diff --git a/bootstrap/database/namespace.yaml b/bootstrap/database/namespace.yaml deleted file mode 100644 index f57dfb1..0000000 --- a/bootstrap/database/namespace.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -apiVersion: v1 -kind: Namespace -metadata: - name: ic-shared-db - labels: - app: ic-shared-db - argocd.argoproj.io/managed-by: openshift-gitops - annotations: - openshift.io/display-name: "Shared PostgreSQL Database" - argocd.argoproj.io/sync-wave: "0" diff --git a/bootstrap/database/populate-images.yaml b/bootstrap/database/populate-images.yaml deleted file mode 100644 index 924abad..0000000 --- a/bootstrap/database/populate-images.yaml +++ /dev/null @@ -1,59 +0,0 @@ ---- -apiVersion: batch/v1 -kind: Job -metadata: - name: populate-images - annotations: - argocd.argoproj.io/sync-wave: "2" -spec: - backoffLimit: 4 - template: - spec: - initContainers: - - name: wait-for-minio - image: busybox:1.28 - command: ['sh', '-c', 'until nc -z -v -w30 $MINIO_ENDPOINT 9000; do echo "Waiting for Minio connection..."; sleep 2; done;'] - env: - - name: MINIO_ENDPOINT - value: minio.ic-shared-minio.svc.cluster.local - containers: - - name: add-images-to-bucket - image: image-registry.openshift-image-registry.svc:5000/redhat-ods-applications/s2i-generic-data-science-notebook:1.2 - imagePullPolicy: IfNotPresent - command: ["/bin/bash"] - args: - - -ec - - |- - git clone https://github.com/rh-aiservices-bu/parasol-insurance.git - - cat << 'EOF' | python3 - import boto3, os, botocore - - s3 = boto3.client("s3", - endpoint_url=os.getenv("AWS_S3_ENDPOINT"), - aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"), - aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY")) - - # Create image bucket - bucket_name = "claim-images" - try: - s3.head_bucket(Bucket=bucket_name) - except botocore.exceptions.ClientError as e: - if e.response['Error']['Code'] == '404': - s3.create_bucket(Bucket=bucket_name) - - # Upload original images to minio - for filename in os.listdir("parasol-insurance/bootstrap/ic-shared-database/images/original_images"): - with open(f"parasol-insurance/bootstrap/ic-shared-database/images/original_images/{filename}", "rb") as f: - s3.upload_fileobj(f, bucket_name, f"original_images/{filename}") - - # Upload processed images to minio - for filename in os.listdir("parasol-insurance/bootstrap/ic-shared-database/images/processed_images"): - with open(f"parasol-insurance/bootstrap/ic-shared-database/images/processed_images/{filename}", "rb") as f: - s3.upload_fileobj(f, bucket_name, f"processed_images/{filename}") - - EOF - envFrom: - - secretRef: - name: secret-minio - restartPolicy: Never diff --git a/bootstrap/database/pvc.yaml b/bootstrap/database/pvc.yaml index 77f8c1f..9303771 100644 --- a/bootstrap/database/pvc.yaml +++ b/bootstrap/database/pvc.yaml @@ -3,9 +3,9 @@ apiVersion: v1 kind: PersistentVolumeClaim metadata: name: claimdb - namespace: ic-shared-db + namespace: agentic-zone labels: - app: ic-shared-db + app: agentic-db annotations: argocd.argoproj.io/sync-wave: "1" spec: diff --git a/bootstrap/database/secret.yaml b/bootstrap/database/secret.yaml index d663dd1..a7a0f30 100644 --- a/bootstrap/database/secret.yaml +++ b/bootstrap/database/secret.yaml @@ -2,13 +2,13 @@ kind: Secret apiVersion: v1 metadata: name: claimdb - namespace: ic-shared-db + namespace: agentic-zone labels: - app: ic-shared-db + app: agentic-db annotations: argocd.argoproj.io/sync-wave: "1" stringData: - database-name: claimdb - database-password: claimdb - database-user: claimdb + database-name: agenticdb + database-password: agenticdb + database-user: agenticdb type: Opaque \ No newline at end of file diff --git a/bootstrap/database/service.yaml b/bootstrap/database/service.yaml index da668a7..cd53e32 100644 --- a/bootstrap/database/service.yaml +++ b/bootstrap/database/service.yaml @@ -2,10 +2,10 @@ apiVersion: v1 kind: Service metadata: - name: claimdb - namespace: ic-shared-db + name: agenticdb + namespace: agentic-zone labels: - app: ic-shared-db + app: agentic-db annotations: argocd.argoproj.io/sync-wave: "1" spec: @@ -15,6 +15,6 @@ spec: port: 5432 targetPort: 5432 selector: - app: ic-shared-db + app: agentic-db sessionAffinity: None type: ClusterIP diff --git a/lab-materials/07-agent-frameworks/7.1-tool-calling-langgraph.ipynb b/lab-materials/07-agent-frameworks/7.1-tool-calling-langgraph-mistral.ipynb similarity index 100% rename from lab-materials/07-agent-frameworks/7.1-tool-calling-langgraph.ipynb rename to lab-materials/07-agent-frameworks/7.1-tool-calling-langgraph-mistral.ipynb diff --git a/lab-materials/07-agent-frameworks/7.2-react-agents-langgraph-granite3.ipynb b/lab-materials/07-agent-frameworks/7.2-react-agents-langgraph-granite3.ipynb index 192a11b..03c6c12 100644 --- a/lab-materials/07-agent-frameworks/7.2-react-agents-langgraph-granite3.ipynb +++ b/lab-materials/07-agent-frameworks/7.2-react-agents-langgraph-granite3.ipynb @@ -7,7 +7,7 @@ "source": [ "## Agentic AI (ReAct) with LangGraph\n", "\n", - "### LLM Used - Granite3.0-8B" + "### LLM Used - Granite3.1-8B" ] }, { @@ -92,18 +92,28 @@ "output_type": "stream", "text": [ "\n", - "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip available: \u001b[0m\u001b[31;49m22.2.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m25.0\u001b[0m\n", "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n" ] } ], "source": [ - "!pip install -q langchain-openai termcolor langchain_community duckduckgo_search wikipedia openapi-python-client==0.12.3 langgraph langchain_experimental" + "!pip install -q langchain-openai termcolor langchain_community duckduckgo_search==7.1.0 wikipedia openapi-python-client==0.12.3 langgraph langchain_experimental" ] }, { "cell_type": "code", "execution_count": 2, + "id": "ebef994b-baf1-4afd-90a9-9a8a62946717", + "metadata": {}, + "outputs": [], + "source": [ + "#!pip install duckduckgo_search==7.1.0" + ] + }, + { + "cell_type": "code", + "execution_count": 3, "id": "60bb3f0f-40b5-49a6-b493-5e361db0113e", "metadata": { "tags": [] @@ -154,7 +164,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "id": "7b908fd0-01dd-4ad2-b745-b3a4c56a7a7e", "metadata": { "tags": [] @@ -162,8 +172,8 @@ "outputs": [], "source": [ "INFERENCE_SERVER_URL = os.getenv('API_URL_GRANITE')\n", - "MODEL_NAME = \"granite30-8b\"\n", - "API_KEY= os.getenv('API_KEY')" + "MODEL_NAME = \"granite-3-8b-instruct\"\n", + "API_KEY= os.getenv('API_KEY_GRANITE')" ] }, { @@ -176,7 +186,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "01baa2b8-529d-455d-ad39-ef4a96dbaf97", "metadata": { "tags": [] @@ -218,7 +228,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "id": "192a9964-44cb-4095-8c4b-bb7e36753b07", "metadata": { "tags": [] @@ -263,7 +273,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "id": "81154c2a-abe2-42cd-88f7-9777007895ae", "metadata": { "tags": [] @@ -285,7 +295,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "id": "19f30dac-6b3f-4731-8640-47dca14aeb11", "metadata": { "tags": [] @@ -341,7 +351,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "64d96fe7-b74d-4e93-af91-5ba2c5242fc7", "metadata": { "tags": [] @@ -378,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "e08b4c68-11b2-4407-8732-3093fbe4cf32", "metadata": { "tags": [] @@ -391,7 +401,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "1128d826-bb1c-474c-b803-4f8ee93bf5ea", "metadata": { "tags": [] @@ -400,10 +410,10 @@ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -427,7 +437,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "6d8d03d3-cbe3-42ac-8a90-3ef612d57c41", "metadata": { "tags": [] @@ -436,10 +446,10 @@ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -464,7 +474,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "f3ae4e2f-789e-43c0-93a7-30e4e74d4fc9", "metadata": { "tags": [] @@ -509,7 +519,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "id": "3d4f4155-3efb-45e7-9bdc-9adfb7726ac5", "metadata": { "tags": [] @@ -517,7 +527,7 @@ "outputs": [ { "data": { - "image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAD5ANYDASIAAhEBAxEB/8QAHQABAAMAAwEBAQAAAAAAAAAAAAUGBwMECAEJAv/EAFAQAAEEAQIDAgYOBQgIBwAAAAEAAgMEBQYRBxIhEzEVFhciQZQIFDI2UVVWYXF0stHS0yNUgZGTN0JDUnWClbMYJCUzcpKWoTQ1U2SxwfD/xAAbAQEBAAMBAQEAAAAAAAAAAAAAAQIDBQQGB//EADQRAQABAgEJBAoDAQEAAAAAAAABAhEDBBIhMUFRUpHRFGGhsQUTFSMzYnGSweEiMoHw8f/aAAwDAQACEQMRAD8A/VNERAREQEREBcNq5XpR89ieOuz+tK8NH7yoO7fu56/PjsVMaVWueS3k2tDnNf8A+lCHAtLh3ue4Frdw0Bzi7k+1uH+n4XmWXFwX7J25rV9vtmZxHpL37n93Rb4opp+JP+Qtt7u+NWF+N6HrLPvTxqwvxxQ9ZZ96eKuF+J6HqzPuTxVwvxPQ9WZ9yvue/wAF0HjVhfjih6yz708asL8cUPWWfenirhfieh6sz7k8VcL8T0PVmfcnue/wNB41YX44oess+9PGrC/HFD1ln3p4q4X4noerM+5PFXC/E9D1Zn3J7nv8DQeNWF+OKHrLPvXcqZCrfaXVbMNlo7zDIHAfuXT8VcL8T0PVmfcupa0Dpy3IJXYanDO07tsVohDM0/NIzZw/YU9zO2fD9JoT6KsR2bmkZ4Yb9qbJYeVwjZen5e1quJ2a2UgAOYegD9twdubfcuFnWuujN74JgREWtBERAREQEREBERAREQEREBRGrsw/T+l8rkYgHTVqz5Imu7i/bzQf27KXVe4hU5b2iczHC0yTNrulYxo3LnM88AD4SW7LbgxE4lMVarwsa0hp/Dx4DDVKEZ5uxZ58npkkJ3e8/O5xc4n4SVIrhp2or1SCzA7nhmY2RjvhaRuD+4rmWFUzNUzVrQVS4gcVtLcLose/UmTNJ+QkdFUghrTWZp3NbzP5IoWPeQ0dSdthuNyFbVinslaFR8GncnHj9YN1Jjn2ZMRnNHY43ZqEro2hzJogHB0cvQFrmlp5epb0KxHZynsmNP43irpvSba161RzeF8Lw5Orjrc4PPJC2FobHC7zXNkc50hIDNmh3KXBWC1x+0FR1y3SFnPe186+02i2KWnO2E2HDdsInMfZdodxs3n3O4GyymPL6z07rvhdr7WOk8tdt2NI2cTmIdPUH3H070ktaYc8Ue5a13ZPG43DT0J9KoHFvH6z1PNqYZjDa/y2oMfquC3j6mNgmGFhxMFyKSOSNsZEdiQxNJI2fLzno0AdA9MW+O2iaesb2lDlLFjUNGaOvaoU8basPgdJG2RheY4nBrC17fPJ5dyRvuCBF8BePeN454Kzcq0buOuV7FmOSvPSssjEbLEkUbmzSRMY9zmsDnMaSWElrgCF1uEun7uM4xcaclaxtipBkstj3Vbc0DmNtRsx0DSWOI2e1r+dvTcA8w791F+xjsZDS+HymhMxp7NY3JYvKZS17esUXtoWYZb0ksbobG3I8ubM08oO45XbgbINwREQdfIUK+VoWaVuJs9WzG6GWJ/c9jhs4H6QSojQ1+e/puEWpe3t1JZqM0p33kfDK6IvO/8AW5Ob9qn1WeHje00/JcG/Jfu2rkfMNt45J3ujO3zs5T+1ein4NV98fldizIiLzoIiICIiAiIgIiICIiAiIgIiIKpTnZoN5o29osA55dTt9eSpudzDKe5jdyeR/Ru2zDsQ3tOPVfCLQ2v8jHktR6SwmfvNiELLWQoxTyCMEkNDnAnl3c47fOVbXsbIxzHtD2OGxa4bgj4Cq0/h9joSTjbOQwoP9Fjrb44h8G0R3jb+xo/7BeiaqMTTXNp53/7/AFlolXj7G3hQWhvk30tygkgeCYNgfT/N+YKzaP4d6W4ew2YtMaexmn4rLmunZjajIBKRuAXBoG+257/hXD4k2PlVnv40P5SeJNj5VZ7+ND+Unq8Pj8JS0b1oRVfxJsfKrPfxofylU72Oy1firg9PM1TmPB1zC378pMsPadrDPTYzb9H7nlsSb9O/l6j0vV4fH4SWje1RQurNF4DXeMbjtR4Whnce2QTNq5Gu2eMPAIDuVwI3AcRv85XR8SbHyqz38aH8pPEmx8qs9/Gh/KT1eHx+Elo3oBvsbuFLA4N4caXaHjZwGJg6jcHY+b8IH7lJ6Z4K6A0Zl4srgNF4HDZOIObHco4+KGVocNnAOa0EbgkFdzxJsfKrPfxofyl98QKdh3+0MhlcqzffsbV14iP0sZytcPmcCEzMONdfKP8AwtD+crkPG7t8Nipeeo/mhyGRhd5kLOodFG4d8p7unuBu4kHla6ywQR1oI4YWNiijaGMYwbBrQNgAPQF8q1YaVeOvXhjrwRtDWRRNDWtA7gAOgC5VhXXExm06oJERFqQREQEREBERAREQEREBERAREQEREBERAWfZYt8v2lgSebxYy+w9G3trG7+n6PR+0enQVn+V38v2lurdvFjL9CBv/wCKxvd6dvo6d2/oQaAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgLPcsB/pA6VPM0HxXzHm7dT/reM677d37fSP2aEs9y23+kFpXqebxXzGw5f/d4z0/8A7/sg0JERAREQEREBERAREQEREBERAREQEREBERAREQEVVyuq70mQsUsHRr23VXclizcndFEx+wPI3la4vcARv3Ab7bkggdLw7rD9Qwfrc35a9VOTYkxfRH+wtl3RUjw7rD9Qwfrc35aeHdYfqGD9bm/LWXZa98c4LLuvAesfZ7ZXT3siK+JtcK53ahxMdzTox8WYDu3lnsVnNex3tfflPtcbbDzg8H0BexfDusP1DB+tzflrIM97H+bUPsg8PxasY/DDM46r2JqCxIYp5mjlincez352NOw/4Wf1erste+OcFnpZFSPDusP1DB+tzflp4d1h+oYP1ub8tOy1745wWXdFSPDusP1DB+tzflp4d1h+oYP1ub8tOy1745wWXdFT6er8pRswsz2PqV6sz2xNuUbD5WxvcdmiRrmNLQSQOYE9SNwB1VwWjEwqsOf5ExYREWpBERAREQEREBERAREQEREBERBn2kTzNzZPf4Xu9fomcFPKA0h7jNf2xd/znKfXYxf7ys6xEUPhdXYnUOUzeOx9v2xcwtltS/H2b29jK6Nsobu4AO8x7Tu0kddu/cLSiYRF0TnMe3Nsw5uweFX13WxS7QdqYQ4NMnL38vM4Dfu3Ko7yKH07q7E6sOVGKt+2ji70mNt/o3s7KxGGl7POA325m9RuDv0KmFARdE5zHtzbMObsHhV9d1sUu0HamEODTJy9/LzOA37tyu8qK7xBO2kMgR3jsyPmPaN2WirOuIXvPyP0M+21aKsMo+FR9Z8qWWwREXPYiIiAiIgIiICIiAiIgIiICIiDPdIe4zX9sXf85yn1AaQ9xmv7Yu/5zlPrsYv95WdbAdK4jIcaNc8QrmW1fqLCx6ezzsNj8Tg8i6nHBFHFE8TSNb/vXSmRx/SczdgAAqDqjT99tz2R+rcZqnPYPJadteEKUONuGGu6aHFwSgyxgbSh3KGlr927dwBJK3zVnATQet9Qy5zMYET5SeNkVieC1PXFpjfctmbE9rZQB0HOHdOncpifhjpq1S1bUlxvNX1WHDMs7eUe2g6AQHrzbs/RtDfM5e7fv6rzZt0ec+M2rc9q6HUGT0nb1JVy+mdNQZPIWKuoDjsbSmfA6xHtXEb/AG08t6ua/ZnKGjmaSVN4bBxa69krpLOXshlq1y3oKDLvjo5SxXiMotQ7s5GPAMR5vOjI5XHqQStXznADQOpMhHcyWnmWZW1YqT2GzM2KeGMbRsmjDwyblHcZA4hc2S4GaJy1bTkNnESHxegFbGSxXrEc0EIDR2ZkbIHvZsxvmvLh07lM2R52s4G9itG8c9eYrWGc0/mNPanyt2pBXultCV8UcTxHLXPmSdofMPNueo229M6cln+KNPipqfJatzmjrmlYmNxuNxl51aCmW0I7XbTx90we+R24kBHK3Ybd61+97HHh1ks/NmbWm2WLs9w5CdslucwT2C7m7SSHtOzkIPdzNO2wA2AAXb1jwH0Jr7OuzGdwDLt+RjIp3NsTRMtMYd2NnjY9rJgPQJA4ejuTNkYxo3H+Unj/AKE1NlbeXoZLI8PKubmrUsnYrRib2xATGY2PAMW7vOjPmuPVwJXqVVLVfCjSutclh8hlsX2l7EbilZrWJa0kTSQSzeJzS5h5W+Y7dvTuVtWcRYV3iF7z8j9DPttWirOuIXvPyP0M+21aKplHwqPrPlSy2CIi57EREQEREBERAREQEREBERAREQZ7pD3Ga/ti7/nOU+oy7icrp7IXZsdj3ZijcmdZMMUzI5oZHDzwOdwa5pI37wQSe/0R3jPmDfbTbo3LvmLXOcWTVHMZy8m4e8TcrXESNIaSCRuQCGkjs1WxJz6ZjT3xHnLKYvpWRFCeFs98jMr61S/PTwtnvkZlfWqX56xzPmj7o6lk2ihPC2e+RmV9apfnqr3eMdbH8Qsfoexg78WqshUfdrY4z1eaSFm/M7m7blHc47E7kNJA2BTM+aPujqWaGihPC2e+RmV9apfnp4Wz3yMyvrVL89Mz5o+6OpZNooTwtnvkZlfWqX56eFs98jMr61S/PTM+aPujqWcHEL3n5H6GfbatFWb0HXtdyNo2cZLg6kcjZrMN6VgtSNZKQGtiYTsxzoyO0J2LQeUHmDhpC82UTEU00XvMXnRp126E6rCIi8LEREQEREBERAREQEREBERARfHODGlziGtA3JPcFAxvsansNkjkmpYiCc+5Ebm5SMxdCHbkti5nnu5XOdECD2Z/SB/M+Qs6lE1bEyy06ZjhlZnIuykilBk8+OEbkl3I07vLeUdowt5yHBstjcVTw8MkNGrFUikmksPbEwNDpJHl8jzt3uc5xJPpJK5q1aGlWir14mQQRMEccUTQ1rGgbBoA6AAdNlyoCIiAvzx4g+xl43Z72XVTWVbUWlaufnM2ZxcbrtoxQVKksEQgeRX9IsRggAg7v3Pw/ocs/wAhyzcfMByhpdX0zkec7nmaJLVHl6d2x7J3/L9KDQEREBERBFZvTtfMsfK176GTFeStXytVkftqq15aXdm57XDbmZG4tcC1xY3ma4DZdV+opcRekhzcUNKpLahq0L0cjntsukb0bIOUdi/nBYASWu5o9ncz+Rs+iAirIqy6Jqh1NktrT9WCxNNWHbWrjHc3aNEI3c57QC9oiAJADGsGwDVYoJ47MLJoniSJ7Q5rm9xB7ig5EREBERAREQEREBERARFxWp/ataabkfL2bC/kjG7nbDfYD0lBAWRDrK9cx7uSfCVHSU8lSuY/njuvdGxwY17/ADXRtDzzcrXAv2bzAxyMNkUDoOPk0XhHdrlJjJUjmL82f9d3e0OImA6B45ti0dARsOgCnkBERAREQFn3DgnVeodQa435qOREWOxDt9w+jAXkTjrttLLLM4Ee6jbCfg2/vUtqXiFlbGlMZM6PEV3hmfyELnNdy7B3tKJw7pHgjtHA7sjdsNnyNcy9V68VSCOCCNkMMTQxkcbQ1rGgbAADuAHoQciIiAiIgIiICgbtF+Bt2srRazsJ5PbGShc2WR7w2Pl54ms5vP5WsHKGnn5QOh6meRB1sdkauYx9W/RsR26VqJs8FiFwcyWNwDmuaR0IIIIPzrsqv4WWSjqTMYuR+UtMcGZGGzbiBrxtlLmmvFKO8sdEXlrurRMzYkbBtgQEREBERAREQERQuY1tp7T9oVsnnMdj7JHN2Nm0xj9vh5Sd9lnTRVXNqYvK2umkVW8qWjvlTiPXY/vVZ4l3+G3FfQmZ0ln9R4qbFZSDsZQy/G17SCHMe07+6a9rXDfpu0bgjotvZ8bgnlK5s7kjoXiBpeGWpow6k31NSdLSGKzuQidmJxCXDtnx83O8PjYJWv286NzXnvKvy/OL2FPBejwV9kTq+/qPN4uTH4ema2JyntlgiuGZw/SRnfbcRtcHDvaX7H5/enlS0d8qcR67H96dnxuCeUmbO5aUVW8qWjvlTiPXY/vTypaO+VOI9dj+9Oz43BPKTNnctKpuezuQ1Bl5NOabl7CSItGVzPLzNx7CN+yi3HK+y5vc07iJrhI8HeOOaIyXEarrPOs0vpbOVIHyx89vLxTxudCwj3FZrtxLMfh2LIx1dueVjr1g8HQ03i4cdjazatOHmLY2kklznFz3ucdy5znOc5znEuc5xJJJJWqqiqibVxZLWfMDgaGmMRWxmMritSrghjOYuJJJc5znOJc97nEuc9xLnOcSSSSVIIiwQREQEREBERAREQV22Q3iHihvmSX4u50i/wDLRyzVv998E55v0fwsE/wKxLHMn7IrhVX4jYqGXifhYnsxt9r4mZ2oMeHCaoNp/wBJ0nHXsx/V9sfAtjQEREBERAREQdLNXHY/D3rTAC+CCSVoPwtaSP8A4VR0lUjrYClIBzT2YmTzzO6vmkc0Fz3E9SST+zu7grPqr3sZj6nN9gqvaa97mK+qRfYC6GBowp+q7EkiIs0EREBERB1clja2WpyVrUYkif8APsWkdQ5pHVrgdiHDqCAR1Xf0HlJ81ovB3rT+1sz04nyybbc7uUbu29G567fOuJcPCz+TnTn1GL7KxxdODPdMeU9F2LSiIucgiIgIireutZwaKxAsOjFm5O/sqtXm5e1f3kk+hrRuSfgGw3JAOzDw6sWuKKIvMiZyeWo4So63kblehVb7qe1K2Ng+lziAqxLxh0dC8tOchcR03jjkeP3hpCw/J2rWdyPhDK2HX73XlkkHmxDf3Mbe5jeg6DqdgSSeq419bheg8OKfe1zfu/dy8Nx8s2jfjpvq8v4E8s2jfjpvq8v4FhyLd7Dybiq5x0LwwLiR7HTSeqfZjY7Ule5GeHuSk8MZVwikDY7DDu+Dl25v0r+U9BsA93wL3d5ZtG/HTfV5fwLDkT2Hk3FVzjoXhuPlm0b8dN9Xl/AvrOMmjXu28Nxt+d8MjR+8tWGonsPJuKrnHQvD0th9QYzUNd0+LyFXIRNPK51aVsgafgOx6H5ipBeWIDJSvR3qU8lG/H7i1XIa9vzHoQ4dB5rgQduoK3Xhvr4axpTV7bWQZemGieNnuZWnulYPQ0kEEd7SCOo2J4uXei6slp9ZRN6fGF16lyREXCRF6q97GY+pzfYKr2mve5ivqkX2ArDqr3sZj6nN9gqvaa97mK+qRfYC6OD8Gfr+F2O9YdIyCR0LGyzBpLGOdyhztugJ2O3X07FeduFvHrVGM4K5jWevMVFYr1L1uCrNj7oms3Z/CEleOsIexjazZ3JG13MeYDmIb1Xo1ee4eAWrpdA6l0FPkcLFgHX5svgctCZXXIbJvC5E2eItDOVry5pLXkkbdApN9iLA32Qk+lrWZqcQ9MHSFqhhZc/F7VyDchHZrRODZWteGM2la5zBybbHnGziFwV+N+dnsVcRqfR02jptQYu3awlmPJttOe+KHtXRShrGmGUMPOAC4ea7ztwo3M8CNUcXMhm73EW5hqLp9O2NP0KmnnSzRw9u5rpLL3ytYS7eOPZgGwAO5Peu7juFGutX6q01kdf38EyppqnahqMwJme+5YngNd08vaNaIwIy/Zjebq8+d0Cn8hB6S445jTXDDgtjIsW7VeqNV4RkzZ8rlhUZI+KCJ0nNO9ry+V5kGzdiXbOJI2XoTHzT2aFaazWNOzJE18tcvD+yeQCWcw6HY7jcdDsvP1jgtr53BDA8PbFHQuoq+PqSY6STK+2Wjs2NayrYj5WOLJmgOLgPTtyvC2zQen7elNE4DC38lJmL2OoQVJ8hNvz2XsjDXSHck7uIJ6knr1JVpvtE6uHhZ/Jzpz6jF9lcy4eFn8nOnPqMX2VcX4M/WPKV2LSiIucgiIgLAuLOSdkuIliBziYsbVjgjae5rpP0jyPpHZA/8AW+rAuLONdjOIc87mkRZOrHPG89znx/o3gfQOyP98Lvehc3tWnXabeH4uuyVWRdfI34sXRntziUwwsL3iGF8r9h8DGAucfmAJVVHFvT5/os5/07kPyF9vViUUaKpiGtcnODWkkgAdST6FidL2UGHu5Co9kGPOEt22VIp2ZqB17zn8jZHUx54YXEH3RcGnctCvbOKOn7721exzR7c9ns/T99jTv06uMAAHXvJ2Ve4faE1doOLH6fa/T97TNCRzYr0zZRfdX3JawsA5OYbgc/N3D3O68mJXXXVT6mrRttad1vyrin43X68OUyUmli3T2LzMmHuX/CDe0aW2BCJWRcnnN3c0kFzSNyBzAbnr8TOKGYmw+uaOl8JNcgwtGeK7mm3xWNWcwF+0I2Je+NrmuOxbsegO658jwmy9vh1rDAMs0hczGdmydd7nv7NsT7bJgHnk3DuVpGwBG/p9K4NQ8NNYV/HnH6cs4WTCaqE00gybpmTVbEsAikLeRpD2u5Wnrtsfh9OiqcozbTfTHdfb+ho+i55bWjsFNNI+aaShA98kji5znGNpJJPeSfSphUXH63xWjcZQwd9uUku4+tDWmdTwt6eIubG0EtkZCWuHzgrn8runj/AEWd/wCnch+QvbTi4cRETVF/qi5qW0VknYfXuAsscWiac0pQP57JWkAf84jd/dVbwuarZ/HR3agsNgeSALVaWvJ0Ox3ZI1rh3ekdVZNE412Z17gKzG8zYJzdlI/mMjaSD/zmMf3lMomicCuatVp8mVOt6QREX5gqL1V72Mx9Tm+wVXtNe9zFfVIvsBWnM03ZHEXqjCA+eCSIE+guaR/9qoaSuR2MDThB5LNaFkFiB3R8MjWgOY4HqCD+8bEdCF0MDThTHeuxMIiLNBERAREQFw8LP5OdOfUYvsrjyeUrYio+zalEcbegHe57j0DWtHVziSAGjckkAdSpDQmLnwmjMJRtM7OzBTiZLHvvyP5Ru3f07Hpv8yxxdGDPfMeU9V2J1ERc5BERAVc1zoyDWuHFZ8grW4X9rVtcvMYn93UdN2kbgjfuPQggEWNFsw8SrCriuibTA8u5Wpa0/kPaGWrnH3OvK153ZKP60b+547u7qNxuGnouNenMli6WZqPq36kF6s/3UNmJsjD9LSCFWJeEGjpXFxwNdpPXaNz2D9wIC+twvTmHNPvaJv3fstDCkW5eRvRvxHF/Fk/Enkb0b8RxfxZPxLd7cybhq5R1LQw1FuXkb0b8RxfxZPxJ5G9G/EcX8WT8Se3Mm4auUdS0MNRbl5G9G/EcX8WT8S+s4O6NY7fwFA75nve4fuLtk9uZNw1co6lo3sLrCXIXmUaMEl++/wBzVrgOefnPXZo6jznEAb9St24caCGjaM09p7J8vb5TPIz3EbR7mJh7y0Ek7nq4knYDZrbFiMFjcBXMGMoVsfCTuWVomxhx+E7DqfnK764mXelKsrp9XRFqfGV1ahERcNBQuY0Vp/UNgWMpg8bkZwOUS2qkcjwPg3cCdlNIsqa6qJvTNpNSreSvRnyTwn+HxfhTyV6M+SeE/wAPi/CrSi3doxuOecred6reSvRnyTwn+HxfhTyV6M+SeE/w+L8KtKJ2jG455yXneq3kr0Z8k8J/h8X4U8lejPknhP8AD4vwq0onaMbjnnJed6DxWhtOYKy2zjsBjKFhu/LNWqRxvbv37EDcbqcRFqqrqrm9U3TWIiLAEREBERAREQEREBERAREQEREBERB//9k=", + "image/jpeg": "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", "text/plain": [ "" ] @@ -540,7 +550,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "id": "dfbd1dc6-8d9e-4b89-bcfe-f2e465af3f67", "metadata": { "tags": [] @@ -582,7 +592,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "id": "321f2258-0334-4bb4-b3c0-781311c143c0", "metadata": {}, "outputs": [], @@ -627,7 +637,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "id": "20bfca23-56a3-43f5-b0a0-f932f7d7e328", "metadata": { "tags": [] @@ -642,29 +652,50 @@ "What is the biggest mountain in the world?\n", "\n", "\n", - "The biggest mountain in the world is Mount Everest, which is located in the Himalayas on the border of Nepal and Tibet. It has a height of approximately 8,848.86 meters (29,031.7 feet) above sea level.\n", + "\n", + "\n", + "\n", + "\n", + "The biggest mountain in the world is Mount Everest, with a height of 29,032 feet (8,849 meters). It's located on the border between Nepal and the Tibet Autonomous Region of China.\n", "\n", "==================================\u001b[1m Agent Message \u001b[0m==================================\n", "\n", "Obtain the area of the mountain\n", "\n", "\n", - "The area of a mountain is not a well-defined concept, as mountains are three-dimensional objects and do not have a flat surface area like a square or circle. However, if you are interested in the surface area of the land covered by a mountain, that would require specific geographical data and calculations.\n", + "\n", + "\n", "\n", - "For Mount Everest, the base of the mountain is approximately 20 kilometers (12 miles) wide, but the exact area covered by the mountain's slopes and peaks is difficult to determine due to its complex shape and the fact that it is covered in snow and ice.\n", "\n", - "If you are interested in the area of a specific region or landscape, please provide more details so I can assist you better.\n", + "Mount Everest doesn't have an area as it's a mountain peak, not a landmass. However, the base of Mount Everest covers approximately 150 square miles (389 square kilometers).\n", "\n", "==================================\u001b[1m Agent Message \u001b[0m==================================\n", "\n", "Now calculate the distance between the nearest city of the mountain. Select the closest\n", "\n", "\n", - "To calculate the distance between Mount Everest and the nearest city, we need to know the location of the city. However, since Mount Everest is located in a remote and mountainous region, the nearest city is likely to be Kathmandu, the capital of Nepal.\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Python REPL can execute arbitrary code. Use with caution.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", "\n", - "The distance between Kathmandu and Mount Everest can vary depending on the specific location of the mountain and the city. On average, the distance is approximately 150 kilometers (93 miles) as the crow flies. However, due to the terrain and the need to travel by road or trekking route, the actual distance can be much greater.\n", + "The distance between Mount Everest and Lhasa, the closest city, is approximately 190.57 kilometers.\n", "\n", - "If you have a specific city in mind, please provide more details so I can assist you better.\n", + "FINAL ANSWER: The distance between Mount Everest and Lhasa, the closest city, is approximately 190.57 kilometers.\n", "\n" ] } @@ -692,9 +723,9 @@ " - Assuming it is a perfect cone with a base radius of 6,052.8 meters, the agent uses a Python calculator tool to determine the area as approximately **1.08 million square kilometers**.\n", "\n", "3. **The agent identifies the closest city to Mount Everest** \n", - " - Using DuckDuckGo, the agent finds that Kathmandu, Nepal, is the closest city to Mount Everest.\n", + " - Using DuckDuckGo, the agent finds that Lhasa, is the closest city to Mount Everest.\n", "\n", - "4. **The agent calculates the distance from Kathmandu to Mount Everest** \n", + "4. **The agent calculates the distance from Lasha to Mount Everest** \n", " - By applying the Haversine formula, the agent determines the distance." ] }, @@ -710,7 +741,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "id": "6c7db0ed-c3ff-495b-a0a3-74e9bf524e29", "metadata": { "tags": [] @@ -730,10 +761,15 @@ "\n", "\n", "\n", - "1. The biggest mountain in the world is Mount Everest, located in the Himalayas on the border of Nepal and Tibet, with a height of approximately 8,848.86 meters (29,031.7 feet) above sea level.\n", - "2. The area of a mountain is not a well-defined concept, but the base of Mount Everest is approximately 20 kilometers (12 miles) wide.\n", - "3. The distance between Mount Everest and the nearest city, Kathmandu, is approximately 150 kilometers (93 miles) as the crow flies, but the actual distance can be much greater due to terrain and travel methods.\n", - "4. Climbing Mount Everest requires specialized equipment and training, and it is not recommended to attempt it with flip flops or any other casual footwear. Appropriate climbing boots with good ankle support, insulation, and waterproofing are essential for mountaineering at high altitudes. Additionally, crampons and ice axes may be required for certain sections of the climb.\n", + "\n", + "\n", + "The biggest mountain in the world is Mount Everest, with a height of 29,032 feet (8,849 meters). It's located on the border between Nepal and the Tibet Autonomous Region of China.\n", + "\n", + "Mount Everest doesn't have an area as it's a mountain peak, not a landmass. However, the base of Mount Everest covers approximately 150 square miles (389 square kilometers).\n", + "\n", + "The distance between Mount Everest and Lhasa, the closest city, is approximately 190.57 kilometers.\n", + "\n", + "As for climbing Mount Everest, it's not recommended to do so with flip flops. Climbers typically use specialized mountaineering boots that provide warmth, support, and traction on icy and rocky terrain. These boots are often waterproof and insulated, and they have rigid soles for better stability. Some popular choices include La Sportiva Trango Cube, Scarpa Phantom Tech, or Salewa MS Pro. Always consult with experienced mountaineers or guides before attempting such a challenging climb.\n", "\n" ] } @@ -754,7 +790,7 @@ "source": [ "Chaining multiple complex questions in a single prompt allows the ReAct Agent to provide a concise, accurate summary without detailing much each step of the process. \n", "\n", - "The agent combines its reasoning to directly address the queries, identifying Mount Everest as the biggest mountain, calculating its area as approximately 1.08 million square kilometers, and determining that the closest city, Kathmandu, is about 120 kilometers away (approx). \n", + "The agent combines its reasoning to directly address the queries, identifying Mount Everest as the biggest mountain, calculating its area as approximately 1.08 million square kilometers, and determining that the closest city, Lasha, is about 190 kilometers away (approx). \n", "And obviously thinks that we **should NOT** climb the Everest with Flip Flops, giving us some tips.\n", "\n", "This approach provides a **streamlined response, focusing on the final answers rather than the intermediate steps**." @@ -776,7 +812,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.9", + "display_name": "Python 3.11", "language": "python", "name": "python3" }, @@ -790,7 +826,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.18" + "version": "3.11.7" } }, "nbformat": 4, diff --git a/lab-materials/07-agent-frameworks/7.2-react-agents-langgraph.ipynb b/lab-materials/07-agent-frameworks/7.2-react-agents-langgraph-mistral.ipynb similarity index 100% rename from lab-materials/07-agent-frameworks/7.2-react-agents-langgraph.ipynb rename to lab-materials/07-agent-frameworks/7.2-react-agents-langgraph-mistral.ipynb