File size: 7,362 Bytes
c69a8c3 76fb66f c69a8c3 9fae0c6 bc2ac28 9fae0c6 bc2ac28 9fae0c6 9e0330e 9fae0c6 9e0330e c69a8c3 9fae0c6 1b711ea 9e0330e 9fae0c6 2598bd9 9fae0c6 2598bd9 9fae0c6 2598bd9 9fae0c6 2598bd9 9fae0c6 2598bd9 9fae0c6 7e37a85 9fae0c6 7e37a85 9fae0c6 7e37a85 9e0330e 9fae0c6 9e0330e 9fae0c6 7e37a85 9e0330e 9fae0c6 7a7801e 9fae0c6 4426eaf 9fae0c6 4426eaf 76fb66f 9fae0c6 7e37a85 76fb66f 9fae0c6 e6a2928 9fae0c6 d759883 9fae0c6 e6a2928 9fae0c6 d759883 9fae0c6 d759883 9fae0c6 d759883 9fae0c6 d759883 9fae0c6 d759883 9fae0c6 d759883 9fae0c6 d759883 9fae0c6 d759883 9fae0c6 c69a8c3 76fb66f c69a8c3 76fb66f 9fae0c6 c69a8c3 76fb66f c69a8c3 9fae0c6 c69a8c3 9fae0c6 c69a8c3 9fae0c6 c69a8c3 9fae0c6 c69a8c3 9fae0c6 c69a8c3 9fae0c6 c69a8c3 9fae0c6 bc2ac28 c69a8c3 8d24498 44667fe 7e37a85 c69a8c3 8d24498 c69a8c3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | import os
import time
import gradio as gr
from neo_rest import start_server
from logica import (
find_custom_response, generate_game_explanation,
detect_roblox, calculator_mode_active, extract_text_content,
)
from buscador import search as web_search, ERROR_NETWORK, ERROR_RATE_LIMIT, ERROR_LICENSE
from resumidor import summarize
from roblox_api import search_player, search_game, format_player, format_game
from matematicas import (
is_calculator_request, is_math_operation,
solve_operation, format_result, extract_username,
)
def add_turn(history, user_msg, bot_msg=""):
return history + [
{"role": "user", "content": user_msg},
{"role": "assistant", "content": bot_msg},
]
def stream_tokens(text, history):
"""
Emits the response token by token (word by word),
simulating the generation process of a real language model.
Longer tokens = slightly longer pauses (more semantic weight).
"""
tokens = text.split(" ")
accumulated = ""
for i, token in enumerate(tokens):
accumulated += token
if i < len(tokens) - 1:
accumulated += " "
history[-1]["content"] = accumulated
delay = 0.055 if len(token) > 4 else 0.030
time.sleep(delay)
yield history
def respond(message, history):
text = message.strip().lower()
if is_calculator_request(message):
name = extract_username(history)
greeting = (
f"Sure! ๐ {name}, here's our calculator:\n\n"
"๐งฎ **NEO-1 Virtual Calculator**\n"
"Type any math operation and I'll solve it instantly.\n\n"
"**Examples:**\n"
"- `5 + 3`\n- `12 * 7`\n- `100 / 4`\n"
"- `2 ** 8` (power)\n- `144 ** 0.5` (square root)\n\n"
"_Type your operation or say 'exit calculator' to go back._"
)
history = add_turn(history, message)
for h in stream_tokens(greeting, history):
yield h, ""
return
if text in ("exit calculator", "close calculator", "quit calculator", "back to chat"):
history = add_turn(history, message, "Alright, back to normal chat. Ask me anything! ๐")
yield history, ""
return
if calculator_mode_active(history) or is_math_operation(message):
result = solve_operation(message)
if result is not None:
response = format_result(message, result)
history = add_turn(history, message)
for h in stream_tokens(response, history):
yield h, ""
return
roblox_type, roblox_name = detect_roblox(message)
if roblox_type == "player":
history = add_turn(history, message, "๐ Searching for player on Roblox...")
yield history, ""
data = search_player(roblox_name)
result = format_player(data)
history[-1]["content"] = result
yield history, ""
return
if roblox_type == "game":
history = add_turn(history, message, "๐ Searching for game on Roblox...")
yield history, ""
data = search_game(roblox_name)
result = format_game(data)
if data and "error" not in data:
explanation = generate_game_explanation(data)
result = result + "\n\n๐ก **What is this game about?**\n" + explanation
history[-1]["content"] = result
yield history, ""
return
custom_response = find_custom_response(message)
if custom_response:
history = add_turn(history, message)
for h in stream_tokens(custom_response, history):
yield h, ""
return
# โโ NEO-2: web search fallback โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
history = add_turn(history, message, "๐ Searching the web...")
yield history, ""
web_result = web_search(message)
if web_result.get("found"):
summary = summarize(message, web_result)
if summary:
history[-1]["content"] = ""
for h in stream_tokens(summary, history):
yield h, ""
return
# โโ User-facing error messages based on failure type โโโโโโโโโโโโโโโโโโโโโโ
error_type = web_result.get("error_type", "")
if error_type == ERROR_NETWORK:
msg = (
"โ ๏ธ **No internet connection**\n\n"
"I couldn't reach the web search engine right now. "
"I also checked my knowledge base but found nothing on that topic.\n\n"
"_Please try again in a few seconds or rephrase your question._"
)
elif error_type == ERROR_RATE_LIMIT:
msg = (
"โณ **Too many searches in a short time**\n\n"
"The search engine asked me to slow down for a moment. "
"Please wait a few seconds and try again. ๐"
)
elif error_type == ERROR_LICENSE:
msg = (
"๐ **Sources unavailable**\n\n"
"I found results online, but all sources use restrictive licenses "
"(All Rights Reserved, CC BY-ND, etc.) that don't allow me to use their content.\n\n"
"_Try rephrasing your question to find open-licensed sources._"
)
else:
msg = (
"๐ค **No results found**\n\n"
"I couldn't find information on that topic in my knowledge base "
"or on the web. Try rephrasing your question."
)
history[-1]["content"] = msg
yield history, ""
with gr.Blocks(title="mdfjbots-neo-1") as demo:
gr.Markdown(
"""
# ๐ค mdfjbots-neo-1
### Conversational AI assistant
"""
)
chatbot = gr.Chatbot(
show_label=False,
height=500,
avatar_images=(None, "https://api.dicebear.com/7.x/bottts/svg?seed=mdfjbots"),
)
with gr.Row():
input_box = gr.Textbox(
placeholder="Type your message here... (e.g. 'search player Builderman')",
show_label=False,
scale=9,
container=False,
autofocus=True,
)
btn_send = gr.Button("Send", scale=1, variant="primary")
with gr.Row():
btn_clear = gr.Button("๐๏ธ Clear conversation", size="sm")
gr.Examples(
examples=[
"Hello, who are you?",
"search player Builderman",
"search game Adopt Me",
"definition of history",
"calculator",
"what is linux",
"korean war",
],
inputs=input_box,
label="Example questions",
)
input_box.submit(fn=respond, inputs=[input_box, chatbot], outputs=[chatbot, input_box])
btn_send.click(fn=respond, inputs=[input_box, chatbot], outputs=[chatbot, input_box])
btn_clear.click(fn=lambda: ([], ""), outputs=[chatbot, input_box])
if __name__ == "__main__":
start_server()
port = int(os.environ.get("PORT", 5000))
dev_domain = os.environ.get("REPLIT_DEV_DOMAIN", "")
root_path = f"https://{dev_domain}/__neo1" if dev_domain else ""
demo.queue()
demo.launch(
server_name="0.0.0.0",
server_port=port,
share=False,
theme=gr.themes.Soft(primary_hue="blue"),
root_path=root_path,
)
|