Compare commits

...

1 Commits

Author SHA1 Message Date
camilleAND 693bc0e116 📝(new tool): add service public tool, add metadata to rag 2025-10-27 15:11:27 +01:00
13 changed files with 177 additions and 27 deletions
+2 -1
View File
@@ -22,6 +22,7 @@ class RAGWebResult(BaseModel):
score: float = Field(
..., description="Relevance score of the web result, typically between 0 and 1."
)
metadata: dict = Field(..., description="Metadata of the web result.")
class RAGWebResults(BaseModel):
@@ -38,4 +39,4 @@ class RAGWebResults(BaseModel):
_format.format(url=result.url, content=result.content) for result in self.data
)
+ "\n\n"
)
)
@@ -3,7 +3,7 @@
import json
import logging
from io import BytesIO
from typing import Optional
from typing import List, Optional
from urllib.parse import urljoin
from django.conf import settings
@@ -150,22 +150,30 @@ class AlbertRagBackend(BaseRagBackend): # pylint: disable=too-many-instance-att
logger.debug(response.json())
response.raise_for_status()
def search(self, query, results_count: int = 4) -> RAGWebResults:
def search(self, query, results_count: int = 4, collections: Optional[List[int]] = None) -> RAGWebResults:
"""
Perform a search using the Albert API based on the provided query.
Args:
query (str): The search query.
results_count (int): The number of results to return.
collections (Optional[List[int]]): List of collection IDs to search in.
If None, uses the current collection_id.
Returns:
RAGWebResults: The search results.
"""
# Use provided collections or fall back to current collection_id
if collections is not None:
collection_list = collections
else:
collection_list = [int(self.collection_id)]
response = requests.post(
urljoin(self._base_url, self._search_endpoint),
headers=self._headers,
json={
"collections": [int(self.collection_id)],
"collections": collection_list,
"prompt": query,
"score_threshold": 0.6,
"k": results_count, # Number of chunks to return from the search
@@ -182,6 +190,7 @@ class AlbertRagBackend(BaseRagBackend): # pylint: disable=too-many-instance-att
url=result.chunk.metadata["document_name"],
content=result.chunk.content,
score=result.score,
metadata=result.chunk.metadata,
)
for result in searches.data
],
@@ -189,4 +198,4 @@ class AlbertRagBackend(BaseRagBackend): # pylint: disable=too-many-instance-att
prompt_tokens=searches.usage.prompt_tokens,
completion_tokens=searches.usage.completion_tokens,
),
)
)
@@ -198,6 +198,7 @@ class AlbertRagDocumentSearch:
url=result.chunk.metadata["document_name"],
content=result.chunk.content,
score=result.score,
metadata=result.chunk.metadata,
)
for result in searches.data
],
@@ -103,6 +103,7 @@ class AlbertWebSearchManager(BaseWebSearchManager):
url=self._clean_url(result.chunk.metadata["document_name"]),
content=result.chunk.content,
score=result.score,
metadata=result.chunk.metadata,
)
for result in searches.data
],
@@ -9,28 +9,33 @@ logger = logging.getLogger(__name__)
result_1 = {
"url": "https://www.lemonde.fr/sciences/article/2025/06/25/le-telescope-james-webb-decouvre-sa-premiere-exoplanete-identifiee-comme-une-petite-planete-froide_6615888_1650684.html",
"content": "+ [La beauté créatrice](https://la-beaute-creatrice.lemonde.fr/ \"La beauté créatrice\")\n\t+ [Perspectives](https://www.lemonde.fr/perspectives/ \"Perspectives\") \n\t+ [Gestion des cookies](#)\n* [Recherche](https://www.lemonde.fr/recherche/)\n\n Cet article vous est offert Pour lire gratuitement cet article réservé aux abonnés, connectez\\-vous [Se connecter](https://secure.lemonde.fr/sfuser/connexion?gift=true) Vous n'êtes pas inscrit sur Le Monde ? \n [Inscrivez\\-vous gratuitement](https://secure.lemonde.fr/sfuser/register?gift=true) * [Sciences Sciences](https://www.lemonde.fr/sciences/)\n* [Astronomie Astronomie](https://www.lemonde.fr/cosmos/)\n\n \n\nLe télescope James\\-Webb dcouvre sa première exoplanète, identifiée comme une petite planète froide\n====================================================================================================\n\n Lobservation a été faite grâce à une méthode prometteuse pour détecter des planètes dune taille similaire à celles du système solaire. Le Monde avec AFP \n\n Publié le 25 juin 2025 à 17h49, modifié le 26 juin 2025 à 03h24 Temps de Lecture 2 min. \n\n Lire plus tard Partager * Partager sur Messenger\n* Partager sur Facebook\n* Envoyer par e\\-mail\n* Partager sur Linkedin\n* Copier le lien\n\n <img src='https://img.lemde.fr/2025/06/25/0/0/866/867/664/0/75/0/1173df3_upload-1-g41rmpa9cg0l-902429.jpg' alt='Une image du disque protoplanétaire autour de létoile TWA 7, enregistrée à laide de linstrument Sphere du télescope basé au Chili, est présentée le 25\xa0juin 2025 avec une image superposée capturée par linstrument MIRI du télescope spatial James-Webb.' title='' width='664' height='443' /> ![Une image du disque protoplanétaire autour de létoile TWA 7, enregistrée à laide de linstrument Sphere du télescope basé au Chili, est présentée le 25\xa0juin 2025 avec une image superposée capturée par linstrument MIRI du télescope spatial James-Webb.](https://img.lemde.fr/2025/06/25/0/0/866/867/664/0/75/0/1173df3_upload-1-g41rmpa9cg0l-902429.jpg) \n\nUne image du disque protoplanétaire autour de létoile TWA 7, enregistrée à laide de linstrument Sphere du télescope basé au Chili, est présentée le 25\xa0juin 2025 avec une image superposée capturée par linstrument MIRI du télescope spatial James\\-Webb. WST/ESO/REUTERS \n\n Le télescope spatial James\\-Webb (JWST) a découvert sa première exoplanète dans lunivers proche. Une observation faite grâce à une méthode prometteuse pour détecter des planètes dune taille similaire à celles du système solaire.\n\n Depuis 2022, à 1,5\xa0million de kilomètres de la Terre, le JWST a aidé à caractériser plusieurs exoplanètes. *«\xa0Il a passé énormément de temps à observer des planètes qui nont jamais été imagées\xa0»*, explique lastrophysicienne Anne\\-Marie Lagrange, première autrice de létude sur le sujet, parue dans [*Nature*](https://www.nature.com/articles/s41550-024-02401-w?utm_source=chatgpt.com \"Nouvelle fenêtre\") mercredi 25\xa0juin.\n\n Lexercice est compliqué du fait que les exoplanètes *«\xa0sont très peu lumineuses parce quelles ne sont pas chaudes\xa0»*, mais aussi et surtout du fait qu\xa0on est aveuglé par la lumière de létoile autour de laquelle elles tournent\xa0»*, ajoute cette chercheuse du CNRS au Laboratoire dinstrumentation et de recherche en astrophysique de lObservatoire de Paris.\n\n La parade du James\\-Webb repose sur son coronographe, un instrument qui sinspire du phénomène de léclipse solaire en masquant létoile pour mieux révéler ce qui lentoure, et sur son spectrographe MIRI, capable dimager les astres les plus discrets grâce à une vision infrarouge. Ses utilisateurs ont pointé le télescope vers létoile TWA 7, située dans notre galaxie à une centaine dannées\\-lumière de la Terre, autrement dit sa très petite banlieue. La cible, initialement détectée par le télescope Hubble, était prometteuse à double titre.",
"content": "+ [La beauté créatrice](https://la-beaute-creatrice.lemonde.fr/ \"La beauté créatrice\")\n\t+ [Perspectives](https://www.lemonde.fr/perspectives/ \"Perspectives\") \n\t+ [Gestion des cookies](#)\n* [Recherche](https://www.lemonde.fr/recherche/)\n\n Cet article vous est offert Pour lire gratuitement cet article réservé aux abonnés, connectez\\-vous [Se connecter](https://secure.lemonde.fr/sfuser/connexion?gift=true) Vous n'êtes pas inscrit sur Le Monde ? \n [Inscrivez\\-vous gratuitement](https://secure.lemonde.fr/sfuser/register?gift=true) * [Sciences Sciences](https://www.lemonde.fr/sciences/)\n* [Astronomie Astronomie](https://www.lemonde.fr/cosmos/)\n\n \n\nLe télescope James\\-Webb dcouvre sa première exoplanète, identifiée comme une petite planète froide\n====================================================================================================\n\n L'observation a été faite grâce à une méthode prometteuse pour détecter des planètes d'une taille similaire à celles du système solaire. Le Monde avec AFP \n\n Publié le 25 juin 2025 à 17h49, modifié le 26 juin 2025 à 03h24 Temps de Lecture 2 min. \n\n Lire plus tard Partager * Partager sur Messenger\n* Partager sur Facebook\n* Envoyer par e\\-mail\n* Partager sur Linkedin\n* Copier le lien\n\n <img src='https://img.lemde.fr/2025/06/25/0/0/866/867/664/0/75/0/1173df3_upload-1-g41rmpa9cg0l-902429.jpg' alt='Une image du disque protoplanétaire autour de l'étoile TWA 7, enregistrée à l'aide de l'instrument Sphere du télescope basé au Chili, est présentée le 25\xa0juin 2025 avec une image superposée capturée par l'instrument MIRI du télescope spatial James-Webb.' title='' width='664' height='443' /> ![Une image du disque protoplanétaire autour de l'étoile TWA 7, enregistrée à l'aide de l'instrument Sphere du télescope basé au Chili, est présentée le 25\xa0juin 2025 avec une image superposée capturée par l'instrument MIRI du télescope spatial James-Webb.](https://img.lemde.fr/2025/06/25/0/0/866/867/664/0/75/0/1173df3_upload-1-g41rmpa9cg0l-902429.jpg) \n\nUne image du disque protoplanétaire autour de l'étoile TWA 7, enregistrée à l'aide de l'instrument Sphere du télescope basé au Chili, est présentée le 25\xa0juin 2025 avec une image superposée capturée par l'instrument MIRI du télescope spatial James\\-Webb. WST/ESO/REUTERS \n\n Le télescope spatial James\\-Webb (JWST) a découvert sa première exoplanète dans l'univers proche. Une observation faite grâce à une méthode prometteuse pour détecter des planètes d'une taille similaire à celles du système solaire.\n\n Depuis 2022, à 1,5\xa0million de kilomètres de la Terre, le JWST a aidé à caractériser plusieurs exoplanètes. *«\xa0Il a passé énormément de temps à observer des planètes qui n'ont jamais été imagées\xa0»*, explique l'astrophysicienne Anne\\-Marie Lagrange, première autrice de l'étude sur le sujet, parue dans [*Nature*](https://www.nature.com/articles/s41550-024-02401-w?utm_source=chatgpt.com \"Nouvelle fenêtre\") mercredi 25\xa0juin.\n\n L'exercice est compliqué du fait que les exoplanètes *«\xa0sont très peu lumineuses parce qu'elles ne sont pas chaudes\xa0»*, mais aussi et surtout du fait qu'\xa0on est aveuglé par la lumière de l'étoile autour de laquelle elles tournent\xa0»*, ajoute cette chercheuse du CNRS au Laboratoire d'instrumentation et de recherche en astrophysique de l'Observatoire de Paris.\n\n La parade du James\\-Webb repose sur son coronographe, un instrument qui s'inspire du phénomène de l'éclipse solaire en masquant l'étoile pour mieux révéler ce qui l'entoure, et sur son spectrographe MIRI, capable d'imager les astres les plus discrets grâce à une vision infrarouge. Ses utilisateurs ont pointé le télescope vers l'étoile TWA 7, située dans notre galaxie à une centaine d'années\\-lumière de la Terre, autrement dit sa très petite banlieue. La cible, initialement détectée par le télescope Hubble, était prometteuse à double titre.",
"score": 0.51039016,
"metadata": {},
}
result_2 = {
"url": "https://www.lemonde.fr/sciences/article/2025/06/25/le-telescope-james-webb-decouvre-sa-premiere-exoplanete-identifiee-comme-une-petite-planete-froide_6615888_1650684.html",
"content": "Le télescope James\\-Webb découvre sa première exoplanète, identifiée comme une petite planète froide",
"score": 0.49020067,
"metadata": {},
}
result_3 = {
"url": "https://www.lemonde.fr/sciences/article/2025/06/25/le-telescope-james-webb-decouvre-sa-premiere-exoplanete-identifiee-comme-une-petite-planete-froide_6615888_1650684.html",
"content": "---------------\n\n Dabord, parce quelle est jeune de seulement 6,4\xa0millions dannées et donc très susceptible de voir se former des corps planétaires dans le disque de matière la ceinturant. Ensuite, parce que le télescope voit ce disque protoplanétaire par le dessus. Son observation avec linstrument Sphere du Très Grand Télescope (VLT), situé au Chili, avait permis dy distinguer trois anneaux s’étageant sur une distance allant jusqu’à plus de cent fois celle séparant la Terre du Soleil.\n\n Et cest dans la partie dégarnie du deuxième anneau que linstrument du James\\-Webb a détecté une *«\xa0source\xa0»* lumineuse, baptisée TWA 7b. Ayant exclu que la découverte savère être un objet du système solaire ou une galaxie lointaine, les astronomes lont identifiée comme une petite planète froide, dune masse dix fois inférieure à celles imagées jusquici avec dautres instruments. Ils estiment sa masse comparable à celle de Saturne, une planète gazeuse qui ne *«\xa0pèse\xa0»* que le tiers de Jupiter, géante gazeuse et poids lourd de notre système solaire.\n\n Avec le James\\-Webb, *«\xa0on est tombé dun facteur dix en capacité de détection\xa0»*, explique Anne\\-Marie Lagrange, car les planètes les plus *«\xa0légères\xa0»* imagées jusquici depuis le sol pesaient à peu près trois fois la masse de Jupiter. *«\xa0La plupart des autres exoplanètes imagées sont ce quon appelle des super\\-Jupiter\xa0»*, ayant de huit à douze fois la masse de cette dernière.\n\n Lire aussi \\| Article réservé à nos abonnés [Potentielle présence de vie sur lexoplanète K2\\-18b\xa0: anatomie dun faux positif](https://www.lemonde.fr/sciences/article/2025/05/13/potentielle-presence-de-vie-sur-l-exoplanete-k2-18b-anatomie-d-un-faux-positif_6605670_1650684.html) Lire plus tard \n\nUn télescope prometteur attendu pour 2028",
"score": 0.48312354,
"metadata": {},
}
result_4 = {
"url": "https://www.lemonde.fr/sciences/article/2025/06/25/le-telescope-james-webb-decouvre-sa-premiere-exoplanete-identifiee-comme-une-petite-planete-froide_6615888_1650684.html",
"content": "-----------------------------------------\n\n La performance a dautant plus dintérêt que dans le bestiaire planétaire, les planètes rocheuses comme la Terre ou Mars ont des masses beaucoup plus faibles que les planètes gazeuses. Or ces exoplanètes rocheuses constituent une cible ultime des découvreurs de mondes potentiellement habitables.\n\n Le Monde Guides dachat [Aspirateurs robots Les meilleurs aspirateurs robots Lire](https://www.lemonde.fr/guides-d-achat/article/2021/10/25/les-meilleurs-aspirateurs-robots_6099813_5306571.html) Anne\\-Marie Lagrange souhaiterait désormais *«\xa0découvrir les planètes les plus légères et peut\\-être de trouver des Terres\xa0»*. Avant dajouter aussitt que si *«\xa0on veut comprendre comment les systèmes planétaires se forment, il ne suffit pas de voir les planètes très ou pas massives\xa0»*. Car il faut pouvoir détecter tous les types de planètes, afin de déterminer in fine si notre système solaire est unique ou pas.\n\n Les astronomes estiment que le JWST a le potentiel de détecter et dimager des planètes ayant une masse encore plus faible que TWA 7b. Mais il faudra de futurs instruments, comme le Télescope extrêmement large (ELT) attendu pour 2028, pour espérer saisir limage de mondes dune taille similaire au nôtre.\n\n Lire aussi \\| Article réservé à nos abonnés [La traque des axions, nouvelle coqueluche des physiciens](https://www.lemonde.fr/sciences/article/2025/06/09/la-traque-des-axions-nouvelle-coqueluche-des-physiciens_6611759_1650684.html) Lire plus tard Le Monde avec AFP \n\n Lespace des contributions est réservé aux abonnés. Abonnez\\-vous pour accéder à cet espace d’échange et contribuer à la discussion. [Sabonner](https://abo.lemonde.fr/?lmd_medium=BOUTONS_LMFR&lmd_campaign=CONTRIBUTION_ARTICLE) Contribuer\n\n [Réutiliser ce contenu](https://www.lemonde.fr/syndication/ \"Réutiliser ce contenu\") Édition du jour\n\n Daté du jeudi 31 juillet\n\n <img src='data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 276 201'%3E%3C/svg%3E' alt='' title='' width='276' height='201' /> [Lire le journal numérique](https://journal.lemonde.fr/) [<img src='' alt='' title='' width='' height='36' /> ![]() Culture générale Des leçons interactives par la rédaction pour tester vos connaissances. Découvrir](https://www.lemonde.fr/memorable/quiz-et-questions-de-culture-generale) [<img src='' alt='' title='' width='300' height='280' />](https://www.lemonde.fr/chaleur-humaine/article/2025/01/30/mesurez-votre-impact-environnement-avec-le-calculateur-d-empreinte-carbone-et-eau_6523433_6125299.html?lmd_medium=bizdev&lmd_campaign=services_partenaire_lmfr&lmd_creation=ademe)",
"score": 0.42882082,
"metadata": {},
}
result_5 = {
"url": "https://www.franceinfo.fr/economie/budget/",
"content": "Budget 2025 de la France \\- actualité et info en direct\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ncontenu principal\n\n\n\n\n\n[<img src='https://www.franceinfo.fr/assets/components/headers/header/img/franceinfo-1d7b76a5.svg' alt='' title='' width='161' height='40' />\n\n<img src='data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 161 40\"%3E%3C/svg%3E' alt='' title='' width='161' height='40' />\nAccueil France Info](/ \"Accueil France Info\")\n\n* [Rechercher une actualité\nRecherche](/recherche/)\n* [Direct TV\nTV](/en-direct/tv.html)\n* [Direct radio\nRadio](/en-direct/radio.html)\n* [Le live\nLive](/en-direct/)\n* Services\n\n\n\n\n\t+ [Newsletters\n\t (Nouvelle fenêtre)](https://www.francetelevisions.fr/abonnements/information)\n\t+ [Météo\n\t (Nouvelle fenêtre)](https://meteo.franceinfo.fr/)\n\t+ [Jeux\n\t (Nouvelle fenêtre)](https://jeux.franceinfo.fr)\n\t+ [Scolarité](/societe/education/scolarite/)\n* Mon\xa0espace\n\n\n\n\n\t+ [S'inscrire](javascript:void(0))\n\t+ [Se connecter](javascript:void(0))\n\t+ [À lire plus tard](/mon-compte/lire-plus-tard)\n\t+ [Mes commentaires](/mon-compte/interactions)\n\t+ [Mes newsletters](/mon-compte/newsletters)\n\t+ [Mes informations](javascript:void(0))\n\t+ [Se déconnecter](javascript:void(0))\n\n\n\n\n\n\n* [Accueil](/)\n* Menu\n* [Grands formats](/grands-formats/)\n* [Enquêtes](/enquetes-franceinfo/)\n* [Vrai ou faux](/vrai-ou-fake/)\n* [Droits de douane](/monde/usa/droits-de-douane/)\n* [Guerre dans la bande de Gaza](/monde/proche-orient/israel-palestine/)\n* [Loi Duplomb](/environnement/loi-duplomb/)\n\n\n\n\n\n\n\n<img src='https://www.franceinfo.fr/assets/components/headers/header/img/franceinfo-1d7b76a5.svg' alt='France Info' title='' width='129' height='32' />\n\n<img src='data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 129 32\"%3E%3C/svg%3E' alt='France Info' title='' width='129' height='32' />\n\n\n\n\n\n\n\n\n\n\n\nRechercher sur franceinfo\n\n\n\n\n\n\nAnnuler la saisie\n\n\n\n\n* [Accueil](/)\n\n\n\n\n En ce moment\n \n\n* [Droits de douane](/monde/usa/droits-de-douane/)\n* [Guerre dans la bande de Gaza](/monde/proche-orient/israel-palestine/)\n* [Loi Duplomb](/environnement/loi-duplomb/)\n\n\n\n\n* [Grands formats](/grands-formats/)\n* [Enquêtes](/enquetes-franceinfo/)\n* [Vrai ou faux](/vrai-ou-fake/)\n\n\n\n\n Rubriques\n \n\n* [L'actu pour les jeunes](/l-actu-pour-les-jeunes/)\n* [Une info transparente](/une-information-transparente-franceinfo/)\n* Monde\n* Europe\n* Faits\\-divers\n* Politique\n* Société\n* Environnement\n* Sport\n* Culture\n* Éco / Conso\n* Santé\n* Sciences \\& technologies\n* Météo\nMétéo\n* Jeux\nJeux\n\n\n\n* Services\n\n\n\nRecevez l'essentiel de l'actualité et restez à jour avec nos newsletters\n\n\n[découvrir nos newsletters\n(Nouvelle fenêtre)](https://www.francetelevisions.fr/abonnements/information)\n\n\n\n Continuez votre exploration\n \n\n* [France 3 régions (nouvelle fenêtre)\nFrance 3 régions](https://france3-regions.franceinfo.fr/)\n* [Outremer la 1ère (nouvelle fenêtre)\nOutremer la 1ère](https://la1ere.franceinfo.fr/)\n* france TV\nfrance TV\n* radio france\nradio france\n\n\n\n\n\n\nServices\n\nServices\n* [Newsletters (nouvelle fenêtre)\nNewsletters](https://www.francetelevisions.fr/abonnements/information)\n* [Météo (nouvelle fenêtre)\nMétéo](https://meteo.franceinfo.fr/)\n* [Jeux (nouvelle fenêtre)\nJeux](https://jeux.franceinfo.fr)\n* [Scolarité](/societe/education/scolarite/)\n\n\n\n\n\n\nMonde\n\nMonde\n\n[voir toute l'actu Monde](/monde/)\n\n\n\n En ce moment\n \n\n* [Droits de douane](/monde/usa/droits-de-douane/)\n* [Guerre dans la bande de Gaza](/monde/proche-orient/israel-palestine/)\n* [Guerre en Ukraine](/monde/europe/manifestations-en-ukraine/)\n* [Affaire Jeffrey Epstein](/monde/usa/affaire-jeffrey-epstein/)\n* [Guerre au Proche\\-Orient](/monde/proche-orient/guerre/)\n* [Donald Trump \\- Président des États\\-Unis](/monde/usa/presidentielle/donald-trump/)\n* [Yémen](/monde/proche-orient/yemen/)\n* [Voir plus de sujets monde](/monde/)\n\n\n\n\n Rubriques",
"score": 0.6129482,
"metadata": {},
}
+25 -13
View File
@@ -531,6 +531,7 @@ class AIAgentService: # pylint: disable=too-many-instance-attributes
_final_output_from_tool = None
_ui_sources = []
_seen_source_urls = set() # Track seen URLs to avoid duplicates
# Help Mistral to prevent `Unexpected role 'user' after role 'tool'` error.
if history and history[-1].kind == "request":
@@ -642,19 +643,30 @@ class AIAgentService: # pylint: disable=too-many-instance-attributes
if event.result.metadata and (
sources := event.result.metadata.get("sources")
):
for source_url in sources:
url_source = LanguageModelV1Source(
sourceType="url",
id=str(uuid.uuid4()),
url=source_url,
providerMetadata={},
)
_new_source_ui = SourceUIPart(
type="source", source=url_source
)
_ui_sources.append(_new_source_ui)
yield events_v4.SourcePart(
**_new_source_ui.source.model_dump()
for source_item in sources:
# Handle both old format (string) and new format (dict)
if isinstance(source_item, dict):
source_url = source_item.get("url", "")
source_title = source_item.get("title", "")
else:
# Fallback for old string format
source_url = source_item
source_title = ""
if source_url and source_url not in _seen_source_urls:
_seen_source_urls.add(source_url)
url_source = LanguageModelV1Source(
sourceType="url",
id=str(uuid.uuid4()),
url=source_url,
providerMetadata={"title": source_title} if source_title else {},
)
_new_source_ui = SourceUIPart(
type="source", source=url_source
)
_ui_sources.append(_new_source_ui)
yield events_v4.SourcePart(
**_new_source_ui.source.model_dump()
)
yield events_v4.ToolResultPart(
@@ -62,7 +62,7 @@ def test_web_search_success(settings):
results = AlbertWebSearchManager().web_search("test query")
assert results == RAGWebResults(
data=[
RAGWebResult(url="http://example.com/test", content="This is a test chunk.", score=0.9)
RAGWebResult(url="http://example.com/test", content="This is a test chunk.", score=0.9, metadata={})
],
usage=RAGWebUsage(prompt_tokens=10, completion_tokens=20),
)
+4
View File
@@ -6,6 +6,7 @@ from .fake_current_weather import get_current_weather
from .web_seach_albert_rag import web_search_albert_rag
from .web_search_brave import web_search_brave, web_search_brave_with_document_backend
from .web_search_tavily import web_search_tavily
from .service_public import service_public
async def only_if_web_search_enabled(ctx, tool_def: ToolDefinition) -> ToolDefinition | None:
@@ -31,6 +32,9 @@ def get_pydantic_tools_by_name(name: str) -> Tool:
"web_search_albert_rag": Tool(
web_search_albert_rag, takes_ctx=True, prepare=only_if_web_search_enabled
),
"service_public": Tool(
service_public, takes_ctx=True, prepare=only_if_web_search_enabled
),
}
return tool_dict[name] # will raise on purpose if name is not found
@@ -36,7 +36,7 @@ def add_document_rag_search_tool(agent: Agent) -> None:
return ToolReturn(
return_value=rag_results.data,
content="",
metadata={"sources": {result.url for result in rag_results.data}},
metadata={"sources": [result.url for result in rag_results.data]},
)
@agent.system_prompt
+83
View File
@@ -0,0 +1,83 @@
"""Service Public RAG search tool using Albert API pre-defined collections.
This tool reuses the existing AlbertRagBackend to query curated collections
(e.g. Service-Public, Travail-Emploi) without creating temporary collections.
"""
import logging
from typing import List
from django.conf import settings
from django.utils.module_loading import import_string
from pydantic_ai import RunContext, RunUsage
from pydantic_ai.messages import ToolReturn
logger = logging.getLogger(__name__)
# Default curated collections (Albert IDs)
DEFAULT_COLLECTION_IDS: List[int] = [784, 785] # travail-emploi, service-public
INSTRUCTIONS = "Voilà les informations trouvées, résume les pour répondre à la question de l'utilisateur si c'est pertinent, si tu manques d'informations cherche encore ou utilise une autre tool si nécessaire: \n"
async def service_public(ctx: RunContext, query: str) -> ToolReturn:
"""Search curated Service-Public collections on Albert and return snippets.
Use this tool when the user asks for information about French public services, the French labor market, employment laws, social benefits, or assistance with administrative procedures.
Args:
ctx: Run context (usage metering is updated here)
query: The query to search within the curated collections
"""
try:
# Use AlbertRagBackend to search in specific collections
backend_class = import_string(settings.RAG_DOCUMENT_SEARCH_BACKEND)
backend = backend_class()
# Search in the curated collections
rag_results = backend.search(query, collections=DEFAULT_COLLECTION_IDS)
# Convert to compact format for the model
compact = []
sources = []
for result in rag_results.data:
# AlbertRagBackend.search() returns RAGWebResult objects with {url, content, score, metadata}
document_name = result.metadata.get("document_name", "Document")
url = result.metadata.get("url", "")
compact.append(
{
"title": document_name,
"snippet": result.content,
"url": url,
}
)
# Create rich source with title and URL
if url:
source_info = {
"title": document_name,
"url": url
}
sources.append(source_info)
# Update run usage
ctx.usage += RunUsage(
input_tokens=rag_results.usage.prompt_tokens,
output_tokens=rag_results.usage.completion_tokens,
)
# Remove duplicate sources based on URL
unique_sources = []
seen_urls = set()
for source in sources:
if source["url"] not in seen_urls:
unique_sources.append(source)
seen_urls.add(source["url"])
return ToolReturn(
return_value=INSTRUCTIONS + str(compact),
content='',
metadata={"sources": unique_sources},
)
except Exception as exc: # pylint: disable=broad-except
logger.exception("Albert Service Public search failed: %s", exc)
return ToolReturn(return_value=[], content="", metadata={"error": str(exc)})
@@ -27,5 +27,5 @@ async def web_search_albert_rag(ctx: RunContext, query: str) -> ToolReturn:
return ToolReturn(
return_value=rag_results.data,
metadata={"sources": {result.url for result in rag_results.data}},
metadata={"sources": [result.url for result in rag_results.data]},
)
+2 -2
View File
@@ -133,9 +133,9 @@ def format_tool_return(raw_search_results: List[dict]) -> ToolReturn:
if result.get("extra_snippets", [])
},
metadata={
"sources": {
"sources": [
result["url"] for result in raw_search_results if result.get("extra_snippets", [])
}
]
},
)
@@ -5,7 +5,11 @@
"model_name": "settings.AI_MODEL",
"human_readable_name": "Default Model",
"provider_name": "default-provider",
"profile": null,
"profile": {
"openai_supports_strict_tool_definition": false,
"openai_supports_tool_choice_required": false
},
"supports_streaming": false,
"settings": {},
"is_active": true,
"icon": [
@@ -24,12 +28,36 @@
"model_name": "settings.AI_MODEL",
"human_readable_name": "Default Summarization Model",
"provider_name": "default-provider",
"profile": null,
"profile": {
"openai_supports_strict_tool_definition": false,
"openai_supports_tool_choice_required": false
},
"supports_streaming": false,
"settings": {},
"is_active": true,
"icon": null,
"system_prompt": "settings.SUMMARIZATION_SYSTEM_PROMPT",
"tools": []
},
{
"hrid": "etalab-plateform-mistral-medium-2508",
"model_name": "mistral-medium-2508",
"human_readable_name": "Mistral Medium 2508 (Plateforme Etalab)",
"provider_name": "mistral-plateform-etalab",
"profile": null,
"supports_streaming": false,
"settings": {},
"is_active": true,
"icon": [
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAMAAABF0y+mAAAAn1BMVEUALosAKoovTZjw8vb////+9/jlPUniAAz",
"iABUAGIWbpsTwq7HhAAAAI4dle7DrdX4AJohRaaboXWj7+/zn6On5//9NZaT29vfoWmVHYKDoUl/k5OUAIYddc6vpbHYCM47Y3+v53+LiFCUA",
"HIWnsckYPJHi6PL77O7jJjW3wdf1w8jre4QgQ5TZ2txwg7Pr3+I8WZ6OnsTuoamClL7tlZ5xz5y8AAAAzUlEQVR4AZ3RRQKDQBBEUSTu7h5c4",
"vc/W6Yp3KG2Dz4ynDdeEBvOmq12xx2E1u0B+4NOEocj4DgNJ1PgLAvni8WyBq5Yc71ubFJx23C2q4P7dRYejg1xzvCUgvz5guz11k7gXYKF/1",
"8oyiYuvHAYeVkhXCzolVStHcGDjiQzNmMQxsMI5rEJRdQSPZvbpE2E8aY6gC6Z+2Hg4dFA0Yb4YedNL/v4Fk8WJuwiGhrChJNXI210rnib9Fs",
"JlXRUC/HwTscPIXf/iklq/tjb/gHAdxkCUjAg2QAAAABJRU5ErkJggg=="
],
"system_prompt": "settings.AI_AGENT_INSTRUCTIONS",
"tools": "settings.AI_AGENT_TOOLS"
}
],
"providers": [
@@ -38,6 +66,12 @@
"base_url": "settings.AI_BASE_URL",
"api_key": "settings.AI_API_KEY",
"kind": "openai"
},
{
"hrid": "mistral-plateform-etalab",
"base_url": "https://api.mistral.etalab.gouv.fr/",
"api_key": "environ.MISTRAL_ETALAB_API_KEY",
"kind": "mistral"
}
]
}
}