OverviewVue d'ensemble
The DEC Chatbot is a conversational AI assistant that lets researchers and scientists search Canadian Earth Observation (EO) data catalogues using plain-language queries in English or French. It is live at dec-chat-dev.csadecai.com.
Le clavardage DEC est un assistant d'intelligence artificielle conversationnel qui permet aux chercheurs et aux scientifiques d'effectuer des recherches dans les catalogues de données d'observation de la Terre (OT) canadiens à l'aide de requêtes en langage naturel, en anglais ou en français. Il est accessible à dec-chat-dev.csadecai.com.
Users can ask questions like:
Les utilisateurs peuvent poser des questions telles que :
- "Show me RCM SAR imagery over the Canadian Arctic from last month"
- "Show me recent SAR data for Quebec"
- "What lake water quality data is available for Lake Erie in 2024?"
- « Montre-moi les images SAR RCM au-dessus de l'Arctique canadien du mois dernier »
- « Montre-moi les données SAR récentes pour le Québec »
- « Quelles données sur la qualité de l'eau des lacs sont disponibles pour le lac Érié en 2024 ? »
The chatbot returns a text summary of what was found, a satellite image thumbnail (when available), and a Source link to the verified catalogue record — so every response is traceable back to real data.
Le chatbot retourne un résumé textuel de ce qui a été trouvé, une vignette d'image satellite (lorsque disponible) et un lien Source vers l'enregistrement de catalogue vérifié — ainsi, chaque réponse est traçable jusqu'aux données réelles.
Architecture
↓
Nova Lite (ca-central-1) — intent + bbox + datetime extraction— extraction d'intention, bbox et datetime
↓
STAC Search — DEC catalogue + EODMS (parallel)— catalogue DEC + EODMS (en parallèle)
↓
DataAccessClient — enriches each item (preview URL, metadata)— enrichit chaque élément (URL d'aperçu, métadonnées)
↓
Claude Sonnet 4.6 (ca-central-1, cross-region inference) — synthesizes response— synthétise la réponse
↓
SSE stream → frontendFlux SSE → client
Backend files (mounted as ConfigMap in the pod)Fichiers du serveur (montés comme ConfigMap dans le pod)
| File | Role |
|---|---|
bedrock_client.py | Full pipeline: Nova Lite → STAC → DataAccess → Claude. Also contains model IDs, system prompts, conversation memory. |
data_access.py | Enriches STAC items: finds image preview URLs, constructs llm_summary for each item. |
stac_client.py | STAC catalogue client for DEC and EODMS. |
server.py | Flask/Gunicorn HTTP server. Handles /chat/stream (SSE), /proxy/image, /stt, /health. Contains the _ImageSanitizer that strips hallucinated image URLs. |
| Fichier | Rôle |
|---|---|
bedrock_client.py | Pipeline complet : Nova Lite → STAC → DataAccess → Claude. Contient aussi les identifiants de modèles, les invites système et la mémoire de conversation. |
data_access.py | Enrichit les éléments STAC : trouve les URL d'aperçu d'image, construit le llm_summary pour chaque élément. |
stac_client.py | Client du catalogue STAC pour DEC et EODMS. |
server.py | Serveur HTTP Flask/Gunicorn. Gère /chat/stream (SSE), /proxy/image, /stt, /health. Contient l'_ImageSanitizer qui supprime les URL d'images hallucinées. |
Kubernetes
| Resource | Details |
|---|---|
| Cluster | devdec-cluster, namespace dec-chatbot-dev |
| Backend deployment | chat-backend — python:3.11-slim, Gunicorn gthread, 8 workers |
| Frontend deployment | chat-frontend — nginx serving static HTML |
| ConfigMaps | chat-backend-app (4 Python files), chat-frontend (index.html + manual.html) |
| IAM role | dec-chatbot-backend-role — Bedrock invoke permissions via IRSA |
| Docker image | ECR: 043309328117.dkr.ecr.ca-central-1.amazonaws.com/dec-chatbot-backend:latest |
| Ressource | Détails |
|---|---|
| Cluster | devdec-cluster, espace de noms dec-chatbot-dev |
| Déploiement serveur | chat-backend — python:3.11-slim, Gunicorn gthread, 8 workers |
| Déploiement client | chat-frontend — nginx servant le HTML statique |
| ConfigMaps | chat-backend-app (4 fichiers Python), chat-frontend (index.html + manual.html) |
| Rôle IAM | dec-chatbot-backend-role — permissions d'invocation Bedrock via IRSA |
| Image Docker | ECR : 043309328117.dkr.ecr.ca-central-1.amazonaws.com/dec-chatbot-backend:latest |
AI ModelsModèles d'IA
| Role | Model | Region |
|---|---|---|
| Intent extractor | Amazon Nova Lite (ca.amazon.nova-lite-v1:0) | ca-central-1 |
| Response synthesizer | Claude Sonnet 4.6 (us.anthropic.claude-sonnet-4-6) | ca-central-1 (cross-region inference) |
| Fallback synthesizer | Claude 3 Sonnet (anthropic.claude-3-sonnet-20240229-v1:0) | ca-central-1 |
| Rôle | Modèle | Région |
|---|---|---|
| Extracteur d'intention | Amazon Nova Lite (ca.amazon.nova-lite-v1:0) | ca-central-1 |
| Synthétiseur de réponses | Claude Sonnet 4.6 (us.anthropic.claude-sonnet-4-6) | ca-central-1 (inférence inter-région) |
| Synthétiseur de secours | Claude 3 Sonnet (anthropic.claude-3-sonnet-20240229-v1:0) | ca-central-1 |
Using the ChatbotUtilisation du chatbot
Searching for dataRecherche de données
Ask in plain language. Include a location and/or time period for best results. The chatbot searches DEC and EODMS in parallel.
Posez votre question en langage naturel. Incluez un lieu et/ou une période pour de meilleurs résultats. Le chatbot effectue des recherches simultanément dans DEC et EODMS.
- Geographic references (provinces, cities, "Arctic", "Canada-wide") are automatically converted to bounding boxes.
- Relative dates ("last month", "summer 2024") are converted to ISO 8601 intervals.
- If the query is too vague, the chatbot will ask a clarifying question.
- Les références géographiques (provinces, villes, « Arctique », « à l'échelle du Canada ») sont automatiquement converties en boîtes englobantes.
- Les dates relatives (« le mois dernier », « été 2024 ») sont converties en intervalles ISO 8601.
- Si la requête est trop vague, le chatbot posera une question de clarification.
Source linksLiens vers les sources
Every response with real data includes a Source: Catalogue record link. Clicking it opens the STAC item record in the DEC or EODMS catalogue, which shows full metadata, download links, and provenance. This is how you verify the response is not hallucinated.
Chaque réponse contenant de vraies données inclut un lien Source : Enregistrement de catalogue. En cliquant dessus, vous ouvrez l'enregistrement STAC dans le catalogue DEC ou EODMS, qui affiche les métadonnées complètes, les liens de téléchargement et la provenance. C'est ainsi que vous vérifiez que la réponse n'est pas hallucinée.
Satellite imagesImages satellites
Preview thumbnails are served through /proxy/image. GeoTIFF files are
converted to PNG on the fly. Some collections (SENTINEL-5P, Landsat, climate normals)
do not have thumbnail assets in the catalogue — those return text-only responses.
Les vignettes d'aperçu sont servies via /proxy/image. Les fichiers GeoTIFF sont
convertis en PNG à la volée. Certaines collections (SENTINEL-5P, Landsat, normales climatiques)
n'ont pas de vignettes dans le catalogue — celles-ci retournent des réponses textuelles uniquement.
Conversation memoryMémoire de conversation
The chatbot remembers the last 10 turns of your conversation so you can ask follow-ups like "show me more" or "what about July?". Memory is per-session and is lost if the pod restarts.
Le chatbot se souvient des 10 derniers échanges de votre conversation, ce qui vous permet de poser des questions de suivi comme « montre-moi plus » ou « qu'en est-il de juillet ? ». La mémoire est par session et est perdue si le pod redémarre.
Available Data CollectionsCollections de données disponibles
Digital Earth Canada (DEC)
| Collection | Description | Image preview |
|---|---|---|
canada_wide_lakes | Canada-wide lake algae monitoring (Jun 2024) | Yes (GeoTIFF) |
SENTINEL-5P | TROPOMI atmospheric data: NO₂, methane, ozone (Jan 2025–present) | No |
rcm | RADARSAT Constellation Mission SAR | Yes (JPEG) |
rcm-ard | RCM Analysis-Ready Data | Yes (PNG) |
sentinel-2-l2a | Sentinel-2 Level-2A optical imagery | Yes (JPEG) |
sentinel-1-rtc | Sentinel-1 SAR (RTC) | No |
landsat-c2l2-sr | Landsat Collection 2 Level-2 Surface Reflectance | No |
landsat-c2l1 | Landsat Collection 2 Level-1 | No |
venus-l2a | VENµS Level-2A surface reflectance | No |
SGBAirPhotos | Aerial photography | Yes (JPEG) |
Radarsat1RawProducts | RADARSAT-1 archive | Yes (JPEG) |
aqhi-forecasts-realtime | Air Quality Health Index forecasts | No |
climate-normals | Climate normals | No |
NAPL | National Air Photo Library (large, slow) | No |
ai-ready-mosaics | AI-ready mosaics | No |
| Collection | Description | Aperçu d'image |
|---|---|---|
canada_wide_lakes | Surveillance des algues lacustres à l'échelle du Canada (juin 2024) | Oui (GeoTIFF) |
SENTINEL-5P | Données atmosphériques TROPOMI : NO₂, méthane, ozone (jan. 2025–présent) | Non |
rcm | Données SAR de la Mission de la Constellation RADARSAT | Oui (JPEG) |
rcm-ard | Données prêtes à l'analyse de la MCR | Oui (PNG) |
sentinel-2-l2a | Imagerie optique Sentinel-2 niveau 2A | Oui (JPEG) |
sentinel-1-rtc | SAR Sentinel-1 (RTC) | Non |
landsat-c2l2-sr | Réflectance de surface Landsat Collection 2 niveau 2 | Non |
landsat-c2l1 | Landsat Collection 2 niveau 1 | Non |
venus-l2a | Réflectance de surface VENµS niveau 2A | Non |
SGBAirPhotos | Photographie aérienne | Oui (JPEG) |
Radarsat1RawProducts | Archive RADARSAT-1 | Oui (JPEG) |
aqhi-forecasts-realtime | Prévisions de la Cote air santé | Non |
climate-normals | Normales climatiques | Non |
NAPL | Bibliothèque nationale de photos aériennes (volumineux, lent) | Non |
ai-ready-mosaics | Mosaïques prêtes pour l'IA | Non |
EODMS (NRCan)
| Collection | Description | Image preview |
|---|---|---|
rcm | RADARSAT Constellation Mission SAR (1.1M+ items) | Yes (JPEG) |
rcm-ard | RCM Analysis-Ready Data (19K items) | Yes (PNG) |
sentinel-1 | Sentinel-1 SAR (75K items) | Yes (PNG) |
| Collection | Description | Aperçu d'image |
|---|---|---|
rcm | SAR de la Mission de la Constellation RADARSAT (1,1 M+ éléments) | Oui (JPEG) |
rcm-ard | Données prêtes à l'analyse de la MCR (19 K éléments) | Oui (PNG) |
sentinel-1 | SAR Sentinel-1 (75 K éléments) | Oui (PNG) |
Updating the ChatbotMise à jour du chatbot
Backend logic lives in four Python files mounted via ConfigMap. No Docker image rebuild is needed for code changes — just update the ConfigMap and restart the deployment.
La logique du serveur réside dans quatre fichiers Python montés via ConfigMap. Aucune reconstruction de l'image Docker n'est nécessaire pour les modifications de code — il suffit de mettre à jour le ConfigMap et de redémarrer le déploiement.
chat-backend-app does NOT update what users see at the root URL.
Always deploy frontend changes to the chat-frontend ConfigMap.
Remarque : Le client et le serveur sont déployés séparément.
Modifier chat-backend-app ne met PAS à jour ce que les utilisateurs voient à l'URL racine.
Déployez toujours les modifications du client vers le ConfigMap chat-frontend.
Update backend Python filesMettre à jour les fichiers Python du serveur
kubectl -n dec-chatbot-dev create configmap chat-backend-app \
--from-file=bedrock_client.py=/c/Users/lwang/bedrock_client.py \
--from-file=data_access.py=/c/Users/lwang/data_access.py \
--from-file=stac_client.py=/c/Users/lwang/stac_client.py \
--from-file=server.py=/c/Users/lwang/server.py \
--dry-run=client -o yaml | kubectl apply -f - && \
kubectl -n dec-chatbot-dev rollout restart deployment/chat-backend
Update frontend HTMLMettre à jour le HTML du client
kubectl -n dec-chatbot-dev create configmap chat-frontend \
--from-file=index.html=/c/Users/lwang/chat-frontend-index.html \
--from-file=manual.html=/c/Users/lwang/manual.html \
--dry-run=client -o yaml | kubectl apply -f - && \
kubectl -n dec-chatbot-dev rollout restart deployment/chat-frontend
Rebuild the Docker image (after pip dependency changes)Reconstruire l'image Docker (après des modifications de dépendances pip)
Only needed if you add or update Python packages. The image is pre-baked (no pip install on startup).
Nécessaire uniquement si vous ajoutez ou mettez à jour des paquets Python. L'image est préconstruite (aucun pip install au démarrage).
aws codebuild start-build \
--profile "DEC AI" \
--region ca-central-1 \
--project-name dec-chatbot-backend-build
Check rollout statusVérifier l'état du déploiement
kubectl -n dec-chatbot-dev rollout status deployment/chat-backend
kubectl -n dec-chatbot-dev rollout status deployment/chat-frontend
View pod logsConsulter les journaux du pod
kubectl -n dec-chatbot-dev logs -l app=chat-backend --tail=100 -f
Run the audit regression testExécuter le test de régression d'audit
Run after every deploy to confirm nothing broke. Baseline: 104 passed, 1 warned, 0 failed.
À exécuter après chaque déploiement pour confirmer que rien n'est cassé. Référence : 104 réussis, 1 avertissement, 0 échec.
POD=$(kubectl -n dec-chatbot-dev get pod -l app=chat-backend \
-o jsonpath='{.items[0].metadata.name}')
kubectl -n dec-chatbot-dev exec -i "$POD" -- \
bash -c 'cat > /tmp/audit_test.py' < /c/Users/lwang/audit_test.py
kubectl -n dec-chatbot-dev exec "$POD" -- \
bash -c 'python3 /tmp/audit_test.py' 2>&1
Updating EODMS CredentialsMise à jour des identifiants EODMS
The EODMS catalogue requires Basic Auth to fetch thumbnail images and search certain collections.
Credentials are stored as a Kubernetes Secret and injected into the pod as environment variables
(EODMS_USERNAME and EODMS_PASSWORD).
Le catalogue EODMS requiert une authentification Basic Auth pour récupérer les vignettes et
rechercher certaines collections. Les identifiants sont stockés comme un Secret Kubernetes et
injectés dans le pod sous forme de variables d'environnement
(EODMS_USERNAME et EODMS_PASSWORD).
Step 1 — Update the Kubernetes SecretÉtape 1 — Mettre à jour le Secret Kubernetes
kubectl -n dec-chatbot-dev create secret generic eodms-credentials \
--from-literal=username=YOUR_EODMS_USERNAME \
--from-literal=password=YOUR_NEW_PASSWORD \
--dry-run=client -o yaml | kubectl apply -f -
Step 2 — Restart the backend pod to pick up the new secretÉtape 2 — Redémarrer le pod serveur pour prendre en compte le nouveau secret
kubectl -n dec-chatbot-dev rollout restart deployment/chat-backend
Step 3 — VerifyÉtape 3 — Vérifier
POD=$(kubectl -n dec-chatbot-dev get pod -l app=chat-backend \
-o jsonpath='{.items[0].metadata.name}')
kubectl -n dec-chatbot-dev exec "$POD" -- \
bash -c 'echo "user=$EODMS_USERNAME pass=${EODMS_PASSWORD:0:3}***"'
Current EODMS accountCompte EODMS actuel
The EODMS account used is a shared service account managed by the CSA DEC AI team. For account issues or password resets, contact NRCan EODMS support.
Le compte EODMS utilisé est un compte de service partagé géré par l'équipe IA DEC de l'ASC. Pour les problèmes de compte ou les réinitialisations de mot de passe, contactez le soutien EODMS de RNCan.
AI Model ConfigurationConfiguration du modèle d'IA
The synthesizer model is set by the SYNTHESIZER constant at the top of
bedrock_client.py. To switch models, update this line and redeploy.
Le modèle synthétiseur est défini par la constante SYNTHESIZER en haut de
bedrock_client.py. Pour changer de modèle, modifiez cette ligne et redéployez.
# In bedrock_client.py — line ~55
SYNTHESIZER = "us.anthropic.claude-sonnet-4-6" # current
SYNTHESIZER_FALLBACK) is used automatically if the primary model
returns an AccessDeniedException due to marketplace policy. No manual intervention needed.
Le modèle de secours (SYNTHESIZER_FALLBACK) est utilisé automatiquement si le modèle
principal retourne une AccessDeniedException en raison de la politique de la place de marché. Aucune intervention manuelle n'est nécessaire.
TroubleshootingDépannage
Images not displaying (broken image icon)Images non affichées (icône d'image brisée)
- Check
/proxy/image?url=<encoded-url>directly — should return 200 withimage/pngorimage/jpeg. - If EODMS thumbnails are broken, EODMS credentials may have expired — see Updating EODMS Credentials.
- Run the audit test: Section 4 (Image Proxy) tests every preview URL.
- Vérifiez
/proxy/image?url=<url-encodée>directement — doit retourner 200 avecimage/pngouimage/jpeg. - Si les vignettes EODMS sont brisées, les identifiants EODMS ont peut-être expiré — voir Mise à jour des identifiants EODMS.
- Exécutez le test d'audit : la Section 4 (Proxy d'images) teste toutes les URL d'aperçu.
Chatbot returns "no data found" for queries that should have resultsLe chatbot retourne « aucune donnée trouvée » pour des requêtes qui devraient avoir des résultats
- Check DEC STAC connectivity:
curl "https://resource-catalogue.dec.alpha.canada.ca/stac/search?limit=1" - Check EODMS connectivity: requires Basic Auth, test with the audit script Section 2.
- The bbox may be wrong — Nova Lite occasionally extracts incorrect coordinates. Check the pod logs for the parsed intent JSON.
- Vérifiez la connectivité DEC STAC :
curl "https://resource-catalogue.dec.alpha.canada.ca/stac/search?limit=1" - Vérifiez la connectivité EODMS : nécessite Basic Auth, testez avec la Section 2 du script d'audit.
- La bbox est peut-être incorrecte — Nova Lite extrait parfois des coordonnées erronées. Consultez les journaux du pod pour le JSON d'intention analysé.
Pod logs show Bedrock errorsLes journaux du pod affichent des erreurs Bedrock
AccessDeniedException: private marketplace— primary model is marketplace-blocked; fallback should activate automatically.ValidationException: invalid model identifier— model ID is wrong or not available in this region. Check the Model Configuration section.ThrottlingException— request rate too high; Bedrock will retry automatically via the SDK.
AccessDeniedException: private marketplace— le modèle principal est bloqué par la place de marché ; le secours doit s'activer automatiquement.ValidationException: invalid model identifier— l'identifiant du modèle est incorrect ou non disponible dans cette région. Consultez la section Configuration du modèle d'IA.ThrottlingException— taux de requêtes trop élevé ; Bedrock réessaiera automatiquement via le SDK.
Health checkVérification de l'état
curl https://dec-chat-dev.csadecai.com/health
Expected response: {"status":"ok","model":"Claude Sonnet 4.6 (DEC)"}
Réponse attendue : {"status":"ok","model":"Claude Sonnet 4.6 (DEC)"}
Pod is stuck / not respondingLe pod est bloqué / ne répond pas
# Force restart
kubectl -n dec-chatbot-dev rollout restart deployment/chat-backend
# Check pod status
kubectl -n dec-chatbot-dev get pods -l app=chat-backend
# Tail logs
kubectl -n dec-chatbot-dev logs -l app=chat-backend --tail=200 -f
Developer Handover ReferenceRéférence de passation aux développeurs
This section captures institutional knowledge for a developer or administrator taking over maintenance of the platform — things that are not obvious from reading the code alone.
Cette section capture les connaissances institutionnelles pour un développeur ou un administrateur prenant en charge la maintenance de la plateforme — des éléments qui ne sont pas évidents à la seule lecture du code.
AWS environmentEnvironnement AWS
| Property | Value |
|---|---|
| Account ID | 043309328117 |
| Default region | ca-central-1 |
| AWS CLI profile | DEC AI (configured via SSO) |
| Environment type | GC Science ASEA-managed (shared SSC cloud) |
| Operator IAM role | PowerSysadmin — account-wide, boundary: SSCPowerSysadminBoundaryPolicy |
| Workload IAM role | dec-chatbot-backend-role — boundary: SSCCustomRoleBoundaryPolicy (IRSA) |
| Propriété | Valeur |
|---|---|
| Identifiant de compte | 043309328117 |
| Région par défaut | ca-central-1 |
| Profil AWS CLI | DEC AI (configuré via SSO) |
| Type d'environnement | GC Science géré par ASEA (nuage SSC partagé) |
| Rôle IAM opérateur | PowerSysadmin — à l'échelle du compte, limite : SSCPowerSysadminBoundaryPolicy |
| Rôle IAM de charge de travail | dec-chatbot-backend-role — limite : SSCCustomRoleBoundaryPolicy (IRSA) |
iam:CreateUser is blocked by the boundary — you cannot
create IAM users directly. New IAM roles must use SSCCustomRoleBoundaryPolicy as a
permission boundary or they will be denied. Route tables are managed by CloudFormation — do not
manually add IGW routes to private subnets. Contact Kevin White (SSC) for account-level access issues.
Contraintes IAM : iam:CreateUser est bloqué par la limite — vous ne pouvez pas
créer d'utilisateurs IAM directement. Les nouveaux rôles IAM doivent utiliser SSCCustomRoleBoundaryPolicy comme
limite de permissions, sinon ils seront refusés. Les tables de routage sont gérées par CloudFormation — ne pas
ajouter manuellement des routes IGW aux sous-réseaux privés. Contactez Kevin White (SSC) pour les problèmes d'accès au niveau du compte.
Kubernetes cluster accessAccès au cluster Kubernetes
The EKS cluster is devdec-cluster in ca-central-1. All chatbot resources live in the dec-chatbot-dev namespace.
Le cluster EKS est devdec-cluster dans ca-central-1. Toutes les ressources du chatbot se trouvent dans l'espace de noms dec-chatbot-dev.
# Configure kubectl (run once, after SSO login)
aws eks update-kubeconfig \
--profile "DEC AI" \
--region ca-central-1 \
--name devdec-cluster
# Verify access
kubectl -n dec-chatbot-dev get pods
Source files (local working copies)Fichiers sources (copies de travail locales)
All working copies live in C:\Users\lwang\. There is no git repository for the backend
Python files — the ConfigMap is the source of truth once deployed. Keep local copies in sync manually.
Toutes les copies de travail se trouvent dans C:\Users\lwang\. Il n'y a pas de dépôt git pour les fichiers
Python du serveur — le ConfigMap est la source de vérité une fois déployé. Gardez les copies locales synchronisées manuellement.
| File | Deployed to |
|---|---|
bedrock_client.py | chat-backend-app ConfigMap |
data_access.py | chat-backend-app ConfigMap |
stac_client.py | chat-backend-app ConfigMap |
server.py | chat-backend-app ConfigMap |
chat-frontend-index.html | chat-frontend ConfigMap (what users see at /) |
manual.html | chat-frontend ConfigMap (accessible at /manual.html) |
audit_test.py | Copied to pod at runtime — not a deployed artifact |
| Fichier | Déployé vers |
|---|---|
bedrock_client.py | ConfigMap chat-backend-app |
data_access.py | ConfigMap chat-backend-app |
stac_client.py | ConfigMap chat-backend-app |
server.py | ConfigMap chat-backend-app |
chat-frontend-index.html | ConfigMap chat-frontend (ce que les utilisateurs voient à /) |
manual.html | ConfigMap chat-frontend (accessible à /manual.html) |
audit_test.py | Copié dans le pod à l'exécution — pas un artefact déployé |
chat-frontend-index.html.
chat-frontend-live.html was deleted and is not used. Do not create a new
chat-frontend-live.html by mistake.
Important : Le seul fichier client est chat-frontend-index.html.
chat-frontend-live.html a été supprimé et n'est pas utilisé. Ne créez pas par erreur un nouveau
chat-frontend-live.html.
Request pipeline (step by step)Pipeline de requêtes (étape par étape)
-
User message arrives at
POST /chat/stream(SSE endpoint inserver.py). Body:{"message": "...", "conversation_id": "..."}. -
Nova Lite extracts intent (
bedrock_client.py). Returns a JSON object withquery_type,collections,bbox(decimal degrees), anddatetime(ISO 8601 interval). Known issue: Nova Lite occasionally returns a null bbox or wrong-hemisphere coordinates — bbox validation guards are in place but not foolproof. Check pod logs for the parsed intent JSON when debugging "no results" queries. -
STAC search runs in parallel against the DEC catalogue
(
https://resource-catalogue.dec.alpha.canada.ca/stac/search) and EODMS (https://www.eodms-sgdot.nrcan-rncan.gc.ca/api/v1/stac/search). Max 10 results per source, sorted by date descending. -
DataAccessClient enriches each item (
data_access.py). Resolves the best preview URL (checksthumbnail,overview,visualassets in order) and builds anllm_summarydict with key metadata and an embedded image markdown tag pointing at/proxy/image?url=.... -
Claude Sonnet 4.6 synthesizes the final response, receiving all enriched items plus
conversation history (last 10 turns). Text tokens are streamed back as SSE
(
data: {"token": "..."}). -
map_action event is emitted after the text stream, before
{"done": true}:
The frontend is intended to use this to pan/zoom a map viewer. The event is deployed but the frontend JS handler is not yet wired up.data: {"type": "map_action", "url": "<asset href>", "bounds": [west, south, east, north], "item_id": "...", "collection": "..."} -
ImageSanitizer in
server.pypost-processes every response to strip any hallucinatedimage tags invented by Claude. Only URLs that came from real catalogue assets during the enrichment step are allowed through.
-
Le message de l'utilisateur arrive à
POST /chat/stream(point de terminaison SSE dansserver.py). Corps :{"message": "...", "conversation_id": "..."}. -
Nova Lite extrait l'intention (
bedrock_client.py). Retourne un objet JSON avecquery_type,collections,bbox(degrés décimaux) etdatetime(intervalle ISO 8601). Problème connu : Nova Lite retourne parfois une bbox nulle ou des coordonnées dans le mauvais hémisphère — des gardes de validation bbox sont en place mais ne sont pas infaillibles. Consultez les journaux du pod pour le JSON d'intention analysé lors du débogage des requêtes « aucun résultat ». -
La recherche STAC s'exécute en parallèle sur le catalogue DEC
(
https://resource-catalogue.dec.alpha.canada.ca/stac/search) et EODMS (https://www.eodms-sgdot.nrcan-rncan.gc.ca/api/v1/stac/search). Maximum 10 résultats par source, triés par date décroissante. -
DataAccessClient enrichit chaque élément (
data_access.py). Résout la meilleure URL d'aperçu (vérifie les assetsthumbnail,overview,visualdans l'ordre) et construit un dictllm_summaryavec les métadonnées clés et une balise markdown d'image intégrée pointant vers/proxy/image?url=.... -
Claude Sonnet 4.6 synthétise la réponse finale, recevant tous les éléments enrichis plus
l'historique de conversation (10 derniers échanges). Les tokens de texte sont diffusés en SSE
(
data: {"token": "..."}). -
L'événement map_action est émis après le flux de texte, avant
{"done": true}:
Le client est censé utiliser ceci pour déplacer/zoomer un visualiseur de carte. L'événement est déployé mais le gestionnaire JS du client n'est pas encore câblé.data: {"type": "map_action", "url": "<asset href>", "bounds": [west, south, east, north], "item_id": "...", "collection": "..."} -
ImageSanitizer dans
server.pypost-traite chaque réponse pour supprimer toute balise d'imagehallucinée inventée par Claude. Seules les URL provenant de vrais assets du catalogue lors de l'étape d'enrichissement sont autorisées.
Image proxy (/proxy/image)Proxy d'images (/proxy/image)
Fetches the upstream image URL (with EODMS Basic Auth if needed), detects format via magic bytes,
and converts GeoTIFFs to 800×800 PNG using tifffile + numpy + Pillow.
HTML responses (e.g. login redirects returned as 200) are detected and rejected.
Récupère l'URL d'image en amont (avec Basic Auth EODMS si nécessaire), détecte le format via les octets magiques
et convertit les GeoTIFF en PNG 800×800 à l'aide de tifffile + numpy + Pillow.
Les réponses HTML (ex. redirections de connexion retournées comme 200) sont détectées et rejetées.
Blocked domains: Some image hosts require session cookies or redirect to login pages
and cannot be proxied. If a new collection's thumbnails are broken, check the pod logs for the raw
upstream response — the domain may need to be added to the blocked list in server.py.
Domaines bloqués : Certains hôtes d'images nécessitent des cookies de session ou redirigent vers des pages de connexion
et ne peuvent pas être proxifiés. Si les vignettes d'une nouvelle collection sont brisées, consultez les journaux du pod pour la réponse
brute en amont — le domaine devra peut-être être ajouté à la liste bloquée dans server.py.
Performance note: The proxy downloads the full GeoTIFF before converting. For large COG files this can be slow. A future improvement is to use HTTP range requests for overview tiles only.
Note de performance : Le proxy télécharge le GeoTIFF complet avant de le convertir. Pour les grands fichiers COG, cela peut être lent. Une amélioration future consiste à utiliser des requêtes HTTP range pour les tuiles d'aperçu uniquement.
Speech-to-text (STT)Reconnaissance vocale (STT)
Voice input is handled by a separate AWS Lambda accessed via API Gateway. The frontend POSTs audio
to /stt on the backend, which proxies it to the Lambda. The Lambda is managed separately
from the Kubernetes deployment.
La saisie vocale est gérée par une fonction AWS Lambda distincte accessible via API Gateway. Le client envoie l'audio
en POST à /stt sur le serveur, qui le proxifie vers la Lambda. La Lambda est gérée séparément
du déploiement Kubernetes.
STT Lambda: https://lyrtolu416.execute-api.ca-central-1.amazonaws.com/stt
Docker imageImage Docker
The image is pre-baked — all Python dependencies are installed at build time, not on startup. The Python application files are not baked into the image; they are mounted from the ConfigMap at runtime. This means code changes only require a ConfigMap update + rollout restart, not an image rebuild. Only rebuild when adding or changing Python package dependencies.
L'image est préconstruite — toutes les dépendances Python sont installées au moment de la construction, pas au démarrage. Les fichiers de l'application Python ne sont pas intégrés dans l'image ; ils sont montés depuis le ConfigMap à l'exécution. Cela signifie que les modifications de code nécessitent uniquement une mise à jour du ConfigMap + un redémarrage du déploiement, pas une reconstruction de l'image. Ne reconstruisez que lors de l'ajout ou de la modification de dépendances de paquets Python.
| Resource | Ressource | Value |
|---|---|---|
| ECR repository | Référentiel ECR | 043309328117.dkr.ecr.ca-central-1.amazonaws.com/dec-chatbot-backend:latest |
| CodeBuild project | Projet CodeBuild | dec-chatbot-backend-build (ca-central-1) |
Conversation memoryMémoire de conversation
History is stored in an in-memory Python dict keyed by conversation_id, capped at 10 turns.
Memory is lost when the pod restarts — any deployment or pod crash resets all active
conversations. A DynamoDB-backed persistence layer is the planned solution but has not been implemented yet.
L'historique est stocké dans un dict Python en mémoire, indexé par conversation_id, limité à 10 échanges.
La mémoire est perdue lors du redémarrage du pod — tout déploiement ou crash du pod réinitialise toutes les
conversations actives. Une couche de persistance DynamoDB est la solution prévue mais n'a pas encore été mise en œuvre.
AuthenticationAuthentification
The API is currently completely open — there is no authentication on
/chat/stream or /stt. Anyone who knows the URL can use it.
Adding an API key header check is the minimum recommended step before broader rollout.
L'API est actuellement complètement ouverte — il n'y a pas d'authentification sur
/chat/stream ou /stt. Quiconque connaît l'URL peut l'utiliser.
L'ajout d'une vérification d'en-tête de clé API est l'étape minimale recommandée avant un déploiement plus large.
Contacts
| Role | Name | Org | |
|---|---|---|---|
| Project Manager | Joey Martin | ASC/CSA | joey.martin@asc-csa.gc.ca |
| Engineering lead | Hany Fawzy | ASC/CSA | hany.fawzy@asc-csa.gc.ca |
| AWS infrastructure & account | Kevin White | SSC/SPC | kevin.white@ssc-spc.gc.ca |
| EODMS account / credentials | NRCan EODMS support (contact via the EODMS portal) | ||
| Rôle | Nom | Org | Courriel |
|---|---|---|---|
| Gestionnaire de projet | Joey Martin | ASC/CSA | joey.martin@asc-csa.gc.ca |
| Responsable technique | Hany Fawzy | ASC/CSA | hany.fawzy@asc-csa.gc.ca |
| Infrastructure AWS et compte | Kevin White | SSC/SPC | kevin.white@ssc-spc.gc.ca |
| Compte / identifiants EODMS | Soutien EODMS de RNCan (contactez via le portail EODMS) | ||