Spaces:
Runtime error
Runtime error
Add automatic web search: detect search keywords in user messages, perform internet search, and return summarized results.
Browse files
app.py
CHANGED
|
@@ -25,64 +25,94 @@ def chat(user_message, chat_history, chat_pairs, sources, plan):
|
|
| 25 |
chat_history.append({"role": "user", "content": user_message})
|
| 26 |
# Build messages including system prompt for API call
|
| 27 |
messages = [{"role": "system", "content": SYSTEM_PROMPT}] + chat_history
|
| 28 |
-
#
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
#
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
)
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
# Append assistant reply to conversation history
|
| 87 |
chat_history.append({"role": "assistant", "content": assistant_reply})
|
| 88 |
# Append pair to display history for any other uses (kept for compatibility)
|
|
|
|
| 25 |
chat_history.append({"role": "user", "content": user_message})
|
| 26 |
# Build messages including system prompt for API call
|
| 27 |
messages = [{"role": "system", "content": SYSTEM_PROMPT}] + chat_history
|
| 28 |
+
# Determine if the user is requesting a web search. If so, perform the search instead
|
| 29 |
+
# of calling the language model. This allows the assistant to fetch resources when
|
| 30 |
+
# the user asks the agent to "search" or "search the internet".
|
| 31 |
+
search_triggers = ["search", "internet search", "web search"]
|
| 32 |
+
lower_msg = user_message.lower()
|
| 33 |
+
if any(trig in lower_msg for trig in search_triggers):
|
| 34 |
+
try:
|
| 35 |
+
# Perform web search using the entire user message as the query
|
| 36 |
+
results = run_web_search(user_message, num_results=5, domain_filter="")
|
| 37 |
+
# Ensure the sources list is initialised
|
| 38 |
+
if sources is None:
|
| 39 |
+
sources = []
|
| 40 |
+
sources.extend(results)
|
| 41 |
+
# Summarise results into a simple string with title and URL
|
| 42 |
+
summary_lines = []
|
| 43 |
+
for r in results:
|
| 44 |
+
title = r.get("title", "")
|
| 45 |
+
url = r.get("url", "")
|
| 46 |
+
if title or url:
|
| 47 |
+
summary_lines.append(f"{title} - {url}")
|
| 48 |
+
if summary_lines:
|
| 49 |
+
assistant_reply = "Here are some resources I found:\n" + "\n".join(summary_lines)
|
| 50 |
+
else:
|
| 51 |
+
assistant_reply = "I couldn't find any results for that query."
|
| 52 |
+
except Exception as e:
|
| 53 |
+
assistant_reply = (
|
| 54 |
+
"An error occurred during web search. Please ensure your search API key is configured.\n"
|
| 55 |
+
f"(Error: {e})"
|
| 56 |
+
)
|
| 57 |
+
else:
|
| 58 |
+
# Call OpenAI's ChatCompletion to get assistant's reply
|
| 59 |
+
try:
|
| 60 |
+
# Use a widely supported default model; older OpenAI SDKs (pinned below v1)
|
| 61 |
+
# do not recognise newer model names like gpt-5. Default to gpt-3.5-turbo
|
| 62 |
+
# but allow overriding via the OPENAI_MODEL env variable.
|
| 63 |
+
model = os.getenv("OPENAI_MODEL", "gpt-3.5-turbo")
|
| 64 |
+
temperature = float(os.getenv("TEMPERATURE", "0.7"))
|
| 65 |
+
max_tokens = int(os.getenv("MAX_OUTPUT_TOKENS", "1024"))
|
| 66 |
+
# Support alternative secret name COURSECREATOR_API_KEY as a fallback for the OpenAI API key
|
| 67 |
+
api_key = os.getenv("OPENAI_API_KEY") or os.getenv("COURSECREATOR_API_KEY")
|
| 68 |
+
if not api_key:
|
| 69 |
+
raise ValueError("OPENAI_API_KEY or COURSECREATOR_API_KEY is not set")
|
| 70 |
+
# Prefer the new OpenAI SDK (>=1.0) if available
|
| 71 |
+
if hasattr(openai, "OpenAI"):
|
| 72 |
+
client = openai.OpenAI(api_key=api_key)
|
| 73 |
+
# Try sending max_tokens; if unsupported, retry with max_completion_tokens
|
| 74 |
+
try:
|
| 75 |
+
response = client.chat.completions.create(
|
| 76 |
+
model=model,
|
| 77 |
+
messages=messages,
|
| 78 |
+
temperature=temperature,
|
| 79 |
+
max_tokens=max_tokens,
|
| 80 |
+
)
|
| 81 |
+
except Exception:
|
| 82 |
+
# Some newer models (e.g. o1 series) do not support max_tokens
|
| 83 |
+
response = client.chat.completions.create(
|
| 84 |
+
model=model,
|
| 85 |
+
messages=messages,
|
| 86 |
+
temperature=temperature,
|
| 87 |
+
max_completion_tokens=max_tokens,
|
| 88 |
+
)
|
| 89 |
+
assistant_reply = response.choices[0].message.content
|
| 90 |
+
else:
|
| 91 |
+
# Legacy OpenAI SDK (<1.0)
|
| 92 |
+
openai.api_key = api_key
|
| 93 |
+
try:
|
| 94 |
+
response = openai.ChatCompletion.create(
|
| 95 |
+
model=model,
|
| 96 |
+
messages=messages,
|
| 97 |
+
temperature=temperature,
|
| 98 |
+
max_tokens=max_tokens,
|
| 99 |
+
)
|
| 100 |
+
except Exception:
|
| 101 |
+
# Fallback for models that require max_completion_tokens
|
| 102 |
+
response = openai.ChatCompletion.create(
|
| 103 |
+
model=model,
|
| 104 |
+
messages=messages,
|
| 105 |
+
temperature=temperature,
|
| 106 |
+
max_completion_tokens=max_tokens,
|
| 107 |
+
)
|
| 108 |
+
assistant_reply = response["choices"][0]["message"]["content"]
|
| 109 |
+
except Exception as e:
|
| 110 |
+
# When the API call fails (e.g. missing API key), return an error message
|
| 111 |
+
assistant_reply = (
|
| 112 |
+
"An error occurred while processing your message. "
|
| 113 |
+
"Please ensure your OpenAI API key is configured in the Space secrets.\n"
|
| 114 |
+
f"(Error: {e})"
|
| 115 |
+
)
|
| 116 |
# Append assistant reply to conversation history
|
| 117 |
chat_history.append({"role": "assistant", "content": assistant_reply})
|
| 118 |
# Append pair to display history for any other uses (kept for compatibility)
|