Spaces:
Runtime error
Runtime error
| import os | |
| import requests | |
| from openai import OpenAI | |
| from quiz_data import PROFILES, QUESTIONS | |
| # OpenAI lit OPENAI_API_KEY dans les variables d'environnement du Space | |
| client = OpenAI() | |
| print("OPENAI_API_KEY set:", bool(os.environ.get("OPENAI_API_KEY"))) | |
| # ⚠️ À remplacer par ton vrai Form Handler Pardot | |
| PARDOT_FORM_HANDLER_URL = " http://go.demo.pardot.com/l/718473/2025-11-20/3jhj" | |
| def start_state(): | |
| return { | |
| "current_question_index": 0, | |
| "answers": [], # list of {id, question, answer, profile} | |
| "profile_counts": { | |
| "time_saver": 0, | |
| "voice_amplifier": 0, | |
| "insight_alchemist": 0, | |
| "revenue_uplifter": 0, | |
| }, | |
| "final_profile_key": None, | |
| "finished": False, | |
| } | |
| def welcome(): | |
| return [ | |
| ( | |
| "agent", | |
| "Hi there, I’m your Agentic AI Personality Guide 🤖\n\n" | |
| "I’ll ask you 5 quick questions to understand how agentic AI should work for you: " | |
| "saving time, amplifying your brand voice, uncovering insights, or driving revenue.", | |
| ), | |
| ("agent", "Ready? Let’s start with question 1."), | |
| ] | |
| def compute_winning_profile(profile_counts): | |
| priority_order = [ | |
| "time_saver", | |
| "voice_amplifier", | |
| "insight_alchemist", | |
| "revenue_uplifter", | |
| ] | |
| best_key = None | |
| best_score = -1 | |
| for key, score in profile_counts.items(): | |
| if score > best_score: | |
| best_score = score | |
| best_key = key | |
| elif score == best_score and best_score > -1: | |
| if priority_order.index(key) < priority_order.index(best_key): | |
| best_key = key | |
| return best_key | |
| def format_messages_for_ui(messages): | |
| chat = [] | |
| for role, text in messages: | |
| if role == "user": | |
| chat.append([text, ""]) | |
| else: | |
| chat.append(["", text]) | |
| return chat | |
| def next_question_text(state): | |
| idx = state["current_question_index"] | |
| if idx >= len(QUESTIONS): | |
| return None | |
| return QUESTIONS[idx]["text"] | |
| def get_current_options(state): | |
| idx = state["current_question_index"] | |
| if idx >= len(QUESTIONS): | |
| return [] | |
| q = QUESTIONS[idx] | |
| return [opt[0] for opt in q["options"]] | |
| def generate_gpt_summary(profile, answers): | |
| answers_text = "\n".join( | |
| [f"- {a['question']}: {a['answer']}" for a in answers] | |
| ) | |
| prompt = f""" | |
| You are a friendly Merkle assistant at an event. | |
| The user's Agentic AI personality result is: {profile['result_title']}. | |
| Here is the detailed description of this profile: | |
| {profile['result_body']} | |
| Here are the answers they selected: | |
| {answers_text} | |
| Write a SHORT conversational summary (4–6 lines max), in English, as if you were speaking directly to the user. | |
| Be warm but professional. Start by naming the profile, then highlight 2–3 key ideas and 1 very concrete next step. | |
| Do not repeat the full text above, just synthesize it. | |
| """ | |
| try: | |
| completion = client.chat.completions.create( | |
| model="gpt-4.1-mini", | |
| messages=[ | |
| { | |
| "role": "system", | |
| "content": "You are a concise, friendly event assistant from Merkle.", | |
| }, | |
| {"role": "user", "content": prompt}, | |
| ], | |
| temperature=0.6, | |
| ) | |
| return completion.choices[0].message.content.strip() | |
| except Exception: | |
| return ( | |
| f"{profile['result_title']}\n\n" | |
| f"{profile['result_body']}\n\n" | |
| "(We couldn’t generate a dynamic summary, so here is the static description.)" | |
| ) | |
| def chat_step(selected_option, state, history): | |
| if state is None: | |
| state = start_state() | |
| messages = welcome() | |
| else: | |
| messages = [] | |
| for u, b in history: | |
| if u: | |
| messages.append(("user", u)) | |
| if b: | |
| messages.append(("agent", b)) | |
| if state["finished"]: | |
| messages.append( | |
| ( | |
| "agent", | |
| "You already have your Agentic AI profile. If you’d like to restart, refresh the page.", | |
| ) | |
| ) | |
| chat = format_messages_for_ui(messages) | |
| return chat, state, gr.update(choices=[], interactive=False), "", "" | |
| if state["current_question_index"] == 0 and not state["answers"] and not selected_option: | |
| q_text = next_question_text(state) | |
| messages.append(("agent", q_text)) | |
| chat = format_messages_for_ui(messages) | |
| options = get_current_options(state) | |
| return chat, state, gr.update(choices=options, value=None, interactive=True), "", "" | |
| if selected_option: | |
| idx = state["current_question_index"] | |
| q = QUESTIONS[idx] | |
| profile = None | |
| for opt_text, prof in q["options"]: | |
| if opt_text == selected_option: | |
| profile = prof | |
| break | |
| state["answers"].append( | |
| { | |
| "id": q["id"], | |
| "question": q["text"], | |
| "answer": selected_option, | |
| "profile": profile, | |
| } | |
| ) | |
| state["profile_counts"][profile] += 1 | |
| messages.append(("user", selected_option)) | |
| messages.append(("agent", "Got it, thanks. Let’s move on.")) | |
| state["current_question_index"] += 1 | |
| if state["current_question_index"] < len(QUESTIONS): | |
| q_text = next_question_text(state) | |
| messages.append(("agent", q_text)) | |
| chat = format_messages_for_ui(messages) | |
| options = get_current_options(state) | |
| return chat, state, gr.update(choices=options, value=None, interactive=True), "", "" | |
| winning_key = compute_winning_profile(state["profile_counts"]) | |
| state["final_profile_key"] = winning_key | |
| state["finished"] = True | |
| profile_data = PROFILES[winning_key] | |
| summary = generate_gpt_summary(profile_data, state["answers"]) | |
| messages.append(("agent", f"Your Agentic AI personality: {profile_data['label']}")) | |
| messages.append(("agent", summary)) | |
| chat = format_messages_for_ui(messages) | |
| email_subject = profile_data["email_subject"] | |
| email_body = profile_data["email_template"] | |
| return ( | |
| chat, | |
| state, | |
| gr.update(choices=[], value=None, interactive=False), | |
| email_subject, | |
| email_body, | |
| ) | |
| chat = format_messages_for_ui(messages) | |
| options = get_current_options(state) | |
| return chat, state, gr.update(choices=options, value=None, interactive=True), "", "" | |
| def send_to_pardot(state, first_name, email, history): | |
| messages = [] | |
| for u, b in history: | |
| if u: | |
| messages.append(("user", u)) | |
| if b: | |
| messages.append(("agent", b)) | |
| if not state["finished"] or not state["final_profile_key"]: | |
| messages.append( | |
| ("agent", "Let’s first finish the 5 questions so I can determine your profile. 🙂") | |
| ) | |
| chat = format_messages_for_ui(messages) | |
| return chat, state | |
| if not email: | |
| messages.append( | |
| ("agent", "Could you please add your work email so we can log your result?") | |
| ) | |
| chat = format_messages_for_ui(messages) | |
| return chat, state | |
| if not PARDOT_FORM_HANDLER_URL: | |
| messages.append( | |
| ("agent", | |
| "Pardot integration is not configured yet (no Form Handler URL). " | |
| "Your result is still available above.") | |
| ) | |
| chat = format_messages_for_ui(messages) | |
| return chat, state | |
| profile_key = state["final_profile_key"] | |
| profile = PROFILES[profile_key] | |
| data = { | |
| "firstname": first_name or "", | |
| "email": email, | |
| "profile_key": profile["key"], | |
| "profile_label": profile["label"], | |
| } | |
| for idx, answer in enumerate(state["answers"], start=1): | |
| data[f"q{idx}_id"] = answer["id"] | |
| data[f"q{idx}_text"] = answer["answer"] | |
| data[f"q{idx}_profile"] = answer["profile"] | |
| try: | |
| requests.post(PARDOT_FORM_HANDLER_URL, data=data, timeout=5) | |
| messages.append( | |
| ("agent", | |
| "Got it ✅ I’ve sent your profile and answers to the Merkle team. " | |
| "They can now follow up with ideas tailored to your result.") | |
| ) | |
| except Exception: | |
| messages.append( | |
| ("agent", | |
| "I’m sorry — I couldn’t send your data to our system. " | |
| "You can still copy the email template and send it manually.") | |
| ) | |
| chat = format_messages_for_ui(messages) | |
| return chat, state | |
| with gr.Blocks(css="#chatbot {height: 480px;}") as demo: | |
| gr.Markdown( | |
| "### Agentic AI Personality Chat\n" | |
| "Answer 5 quick questions to discover your Agentic AI personality." | |
| ) | |
| state = gr.State(start_state()) | |
| chatbot = gr.Chatbot( | |
| value=[["", m[1]] for m in welcome()], | |
| elem_id="chatbot" | |
| ) | |
| with gr.Row(): | |
| options = gr.Radio( | |
| choices=get_current_options(start_state()), | |
| label="Choose your answer", | |
| interactive=True, | |
| ) | |
| gr.Markdown("#### Share your result with the Merkle team") | |
| with gr.Row(): | |
| first_name_tb = gr.Textbox(label="First name") | |
| email_tb = gr.Textbox(label="Work email") | |
| send_btn = gr.Button("Send my result to Merkle") | |
| gr.Markdown("#### Optional email template") | |
| email_subject = gr.Textbox(label="Email subject", interactive=False) | |
| email_body = gr.Textbox( | |
| label="Email body (copy-paste and update with your name + email)", | |
| lines=8, | |
| interactive=False, | |
| ) | |
| options.change( | |
| fn=chat_step, | |
| inputs=[options, state, chatbot], | |
| outputs=[chatbot, state, options, email_subject, email_body], | |
| ) | |
| send_btn.click( | |
| fn=send_to_pardot, | |
| inputs=[state, first_name_tb, email_tb, chatbot], | |
| outputs=[chatbot, state], | |
| ) | |
| demo.launch() | |