Spaces:
Sleeping
Sleeping
| # pip install openai streamlit | |
| import os, json, re | |
| from openai import OpenAI | |
| import streamlit as st | |
| ITEMS = """AGO VIBRANTE, ASPIRATORE, AUTOCARRI/RIMORCHI/VETTURE, AVVITATORI-TRAPANI, BENNE-FORCHE, BETONIERE, CAROTATORI, CARRELLI ELEVATORI/TRANSPALLET, CIPPATORE, COMPRESSORI, CONVOGLIATORI DETRITI, COSTIPATORI E PIASTRE VIB., DECESPUGLIATORI, POMPE A IMMERSIONE, ELICOTTERI, ELEVATORE A BANDIERA, ESCAVATORI, FRESE, GEN. ARIA-ESTRATTORI-DEUM., GRUPPI ELETTROGENI, IDROPULITRICI - LAVAGGIO, IMPIANTO SEMAFORICO, INTONACATRICI, LAME SGOMBRANEVE, LEVIGATRICI - PIALLATRICI, MARTELLI DEMOLITORI ELETTRICI, MARTELLO DEMOLITORE IDRAULICO, MINIDUMPER, MINIPALE - PALE, MONOBLOCCHI E CONTAINER, MONTACARICHI - SOLLEVATORI, MOTOPOMPA, PIATTAFORMA AUTOCARRATA, PIATTAFORMA RAGNO, PIATTAFORMA SEMOVENTE, PIATTAFORME VERTICALI, RAMPE DI CARICO, RASCHIA PAVIMENTI, RECINZIONI - RETI ANTICADUTA, RULLI COMPATTATORI, SABBIATRICI, SCARIFICATRICI - SMERIGLIATRICI, SCALE, SERBATOI, SEGHE-SEGHETTI, SOLLEVATORE TELESCOPICO, SOFFIATORI, SPAZZATRICI, TAGLIASUOLO, TAGLIAPIASTRELLE, TASSELLATORI, TORRI FARO / ILLUMINAZIONE, TOSAERBA, TRABATTELLI, TRASPORTATORE A NASTRO, TRONCATRICI, TRINCIA, TRIVELLE, VIDEO ISPEZIONE - LASER, ATTREZZATURA VARIA, MISCELATORE, UTENSILE MULTIFUNZIONE, BATTERIA, TRACCIATORE LASER, TUNNEL PEDONALE""" | |
| def build_prompt(query: str) -> list: | |
| system = ( | |
| "Sei un assistente di ricerca per Centroedile (NOL System). " | |
| "Dato un bisogno del cliente, scegli gli articoli più utili (solo da una lista fissa) " | |
| "e spiega lo scopo di ciascuno. " | |
| "Rispondi **solo** in JSON conforme allo schema: " | |
| '{"results":[{"Macchine ed Attrezzature ":"<nome esatto dall\'elenco>","Analisi AI":"<perché serve, in italiano>"}]}. ' | |
| "Non aggiungere testo fuori dal JSON. " | |
| f"Elenco articoli consentiti (usa i nomi esattamente come scritti): {ITEMS}" | |
| ) | |
| user = f"Richiesta del cliente: {query}" | |
| return [{"role":"system","content":system},{"role":"user","content":user}] | |
| def extract_json(text: str): | |
| # Safety: grab the largest {...} block if the model adds anything stray | |
| m = re.search(r'\{.*\}\s*$', text, flags=re.S) | |
| if not m: | |
| m = re.search(r'\{.*\}', text, flags=re.S) | |
| if not m: | |
| raise ValueError("No JSON object found.") | |
| return json.loads(m.group(0)) | |
| api_key = os.getenv("OPENAI_API_KEY") | |
| client = OpenAI(api_key=api_key) | |
| def runsearch(query: str): | |
| messages = build_prompt(query) | |
| resp = client.chat.completions.create( | |
| model="gpt-5-chat-latest", | |
| response_format={"type":"json_object"}, | |
| messages=messages, | |
| ) | |
| text = resp.choices[0].message.content | |
| return extract_json(text) | |
| # ---- Streamlit UI ---- | |
| def app(): | |
| #st.image("nslogowhite.png", width=150) | |
| st.title("Centroedile NOL System — Ricerca Noleggio") | |
| query = st.text_input("Descrivi il tuo progetto:") | |
| if st.button("Cerca"): | |
| if not query.strip(): | |
| st.warning("Inserisci una richiesta.") | |
| return | |
| try: | |
| with st.spinner("🔍 Analisi AI in corso, attendere..."): | |
| data = runsearch(query) | |
| results = data.get("results", []) | |
| if results: | |
| st.subheader("Articoli consigliati") | |
| st.dataframe(results, use_container_width=True) | |
| else: | |
| st.info("Nessun articolo trovato per la richiesta.") | |
| except Exception as e: | |
| st.error(f"Errore nel parsing/ricerca: {e}") | |
| if __name__ == "__main__": | |
| app() | |