OrbitMC commited on
Commit
7ae216c
·
verified ·
1 Parent(s): 17da9eb

Upload 2 files

Browse files
Files changed (2) hide show
  1. ai_studio_code (3).py +215 -0
  2. ai_studio_code.txt +38 -0
ai_studio_code (3).py ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import gradio as gr
3
+ from openai import OpenAI
4
+ from duckduckgo_search import DDGS
5
+ import json
6
+
7
+ # --- Logic Functions ---
8
+
9
+ client = OpenAI(base_url="http://localhost:8080/v1", api_key="no-key-required")
10
+
11
+ def search_web(query):
12
+ try:
13
+ with DDGS() as ddgs:
14
+ results = [r for r in ddgs.text(query, max_results=5)]
15
+ if not results:
16
+ return None
17
+ context = "\n".join([f"Source: {r['title']}\nContent: {r['body']}" for r in results])
18
+ return context
19
+ except Exception as e:
20
+ print(f"Search error: {e}")
21
+ return None
22
+
23
+ def format_time(seconds_float):
24
+ total_seconds = int(round(seconds_float))
25
+ m, s = divmod(total_seconds, 60)
26
+ h, m = divmod(m, 60)
27
+ return f"{h}h {m}m {s}s" if h > 0 else f"{m}m {s}s" if m > 0 else f"{s}s"
28
+
29
+ class ParserState:
30
+ __slots__ = ['answer', 'thought', 'in_think', 'start_time', 'last_pos', 'total_think_time']
31
+ def __init__(self):
32
+ self.answer = ""
33
+ self.thought = ""
34
+ self.in_think = False
35
+ self.start_time = 0
36
+ self.last_pos = 0
37
+ self.total_think_time = 0.0
38
+
39
+ def parse_response(text, state):
40
+ buffer = text[state.last_pos:]
41
+ state.last_pos = len(text)
42
+ while buffer:
43
+ if not state.in_think:
44
+ think_start = buffer.find('<think>')
45
+ if think_start != -1:
46
+ state.answer += buffer[:think_start]
47
+ state.in_think = True
48
+ state.start_time = time.perf_counter()
49
+ buffer = buffer[think_start + 7:]
50
+ else:
51
+ state.answer += buffer
52
+ break
53
+ else:
54
+ think_end = buffer.find('</think>')
55
+ if think_end != -1:
56
+ state.thought += buffer[:think_end]
57
+ state.total_think_time += (time.perf_counter() - state.start_time)
58
+ state.in_think = False
59
+ buffer = buffer[think_end + 8:]
60
+ else:
61
+ state.thought += buffer
62
+ break
63
+ return state
64
+
65
+ def format_ui_response(state):
66
+ collapsible = ""
67
+ if state.thought or state.in_think:
68
+ status = f"🌀 Thinking ({format_time(state.total_think_time)})" if state.in_think else f"✅ Thought for {format_time(state.total_think_time)}"
69
+ open_tag = "open" if state.in_think else ""
70
+ collapsible = f"<details {open_tag}><summary>{status}</summary><div class='thinking-container'>{state.thought}</div></details>"
71
+ return f"{collapsible}\n\n{state.answer}"
72
+
73
+ # --- Gradio UI Handlers ---
74
+
75
+ def user_msg(user_input, history):
76
+ return "", history + [[user_input, None]]
77
+
78
+ def generate_response(history, search_enabled, temp, top_p, max_tok, active_gen):
79
+ if not history: return history
80
+
81
+ query = history[-1][0]
82
+ full_prompt = query
83
+
84
+ # Perform Search if enabled
85
+ if search_enabled:
86
+ history[-1][1] = "🔍 Searching the web..."
87
+ yield history
88
+ search_results = search_web(query)
89
+ if search_results:
90
+ full_prompt = f"User Query: {query}\n\nWeb Search Results:\n{search_results}\n\nInstruction: Use the search results to provide a comprehensive answer."
91
+ else:
92
+ history[-1][1] = "🔍 No search results found. Proceeding with internal knowledge..."
93
+ yield history
94
+
95
+ messages = [{"role": "user", "content": full_prompt}]
96
+ state = ParserState()
97
+ full_text = ""
98
+
99
+ try:
100
+ stream = client.chat.completions.create(
101
+ model="local",
102
+ messages=messages,
103
+ temperature=temp,
104
+ top_p=top_p,
105
+ max_tokens=max_tok,
106
+ stream=True
107
+ )
108
+
109
+ for chunk in stream:
110
+ if not active_gen[0]: break
111
+ if chunk.choices[0].delta.content:
112
+ full_text += chunk.choices[0].delta.content
113
+ state = parse_response(full_text, state)
114
+ history[-1][1] = format_ui_response(state)
115
+ yield history
116
+ except Exception as e:
117
+ history[-1][1] = f"Error: {str(e)}"
118
+ yield history
119
+ finally:
120
+ active_gen[0] = False
121
+
122
+ # --- UI Setup ---
123
+
124
+ CSS = """
125
+ .thinking-container {
126
+ border-left: 3px solid #facc15;
127
+ padding: 10px;
128
+ margin: 5px 0;
129
+ background: rgba(250, 204, 21, 0.05);
130
+ font-style: italic;
131
+ color: #666;
132
+ }
133
+ details {
134
+ border: 1px solid #ddd;
135
+ border-radius: 8px;
136
+ padding: 5px 10px;
137
+ margin-bottom: 10px;
138
+ }
139
+ summary {
140
+ cursor: pointer;
141
+ font-weight: bold;
142
+ color: #444;
143
+ }
144
+ """
145
+
146
+ with gr.Blocks(css=CSS, theme=gr.themes.Soft()) as demo:
147
+ active_gen = gr.State([False])
148
+
149
+ with gr.Row():
150
+ with gr.Column(scale=8):
151
+ gr.Markdown("# 🧠 Qwen3 Web Explorer\n*High-speed reasoning with real-time web access*")
152
+ with gr.Column(scale=2):
153
+ search_toggle = gr.Checkbox(label="🌐 Enable Web Search", value=False)
154
+
155
+ chatbot = gr.Chatbot(height=550, show_label=False, bubble_full_width=False)
156
+
157
+ with gr.Row():
158
+ msg = gr.Textbox(
159
+ placeholder="Ask me anything...",
160
+ container=False,
161
+ scale=7
162
+ )
163
+ submit_btn = gr.Button("Send", variant="primary", scale=1)
164
+
165
+ with gr.Row():
166
+ stop_btn = gr.Button("⏹ Stop", variant="secondary")
167
+ regen_btn = gr.Button("🔄 Regenerate", variant="secondary")
168
+ undo_btn = gr.Button("↩️ Undo", variant="secondary")
169
+ clear_btn = gr.Button("🗑 Clear Chat", variant="secondary")
170
+
171
+ with gr.Accordion("Advanced Settings", open=False):
172
+ with gr.Row():
173
+ temp = gr.Slider(0.1, 1.5, 0.6, label="Temperature")
174
+ top_p = gr.Slider(0.1, 1.0, 0.95, label="Top-p")
175
+ max_tok = gr.Slider(1024, 32768, 4096, step=128, label="Max Tokens")
176
+
177
+ # Functions
178
+ def start_gen(): return [True]
179
+ def stop_gen(): return [False]
180
+ def undo(history):
181
+ if len(history) > 0: history.pop()
182
+ return history
183
+
184
+ submit_event = submit_btn.click(
185
+ user_msg, [msg, chatbot], [msg, chatbot], queue=False
186
+ ).then(
187
+ start_gen, None, active_gen
188
+ ).then(
189
+ generate_response, [chatbot, search_toggle, temp, top_p, max_tok, active_gen], chatbot
190
+ )
191
+
192
+ msg.submit(
193
+ user_msg, [msg, chatbot], [msg, chatbot], queue=False
194
+ ).then(
195
+ start_gen, None, active_gen
196
+ ).then(
197
+ generate_response, [chatbot, search_toggle, temp, top_p, max_tok, active_gen], chatbot
198
+ )
199
+
200
+ regen_btn.click(
201
+ lambda history: (history[-1][0], history[:-1]), [chatbot], [msg, chatbot], queue=False
202
+ ).then(
203
+ user_msg, [msg, chatbot], [msg, chatbot], queue=False
204
+ ).then(
205
+ start_gen, None, active_gen
206
+ ).then(
207
+ generate_response, [chatbot, search_toggle, temp, top_p, max_tok, active_gen], chatbot
208
+ )
209
+
210
+ stop_btn.click(stop_gen, None, active_gen, cancels=[submit_event])
211
+ undo_btn.click(undo, [chatbot], [chatbot])
212
+ clear_btn.click(lambda: None, None, chatbot)
213
+
214
+ if __name__ == "__main__":
215
+ demo.launch(server_name="0.0.0.0", server_port=7860)
ai_studio_code.txt ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM ubuntu:22.04
2
+
3
+ # Install system dependencies
4
+ RUN apt-get update && \
5
+ apt-get install -y \
6
+ build-essential \
7
+ libssl-dev \
8
+ zlib1g-dev \
9
+ libboost-all-dev \
10
+ libopenblas-dev \
11
+ libomp-dev \
12
+ cmake \
13
+ pkg-config \
14
+ git \
15
+ python3-pip \
16
+ curl \
17
+ wget && \
18
+ rm -rf /var/lib/apt/lists/*
19
+
20
+ # Install Python dependencies (Added duckduckgo-search)
21
+ RUN pip3 install huggingface-hub openai gradio duckduckgo-search
22
+
23
+ # Build llama.cpp
24
+ RUN git clone https://github.com/ggerganov/llama.cpp && \
25
+ cd llama.cpp && \
26
+ cmake -B build -S . -DLLAMA_BUILD_SERVER=ON -DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS -DCMAKE_BUILD_TYPE=Release && \
27
+ cmake --build build --config Release --target llama-server -j $(nproc)
28
+
29
+ # Download model
30
+ RUN mkdir -p /models && \
31
+ wget -O /models/model.q8_k_xl.gguf https://huggingface.co/unsloth/Qwen3-0.6B-GGUF/resolve/main/Qwen3-0.6B-UD-Q8_K_XL.gguf
32
+
33
+ COPY app.py /app.py
34
+ COPY start.sh /start.sh
35
+ RUN chmod +x /start.sh
36
+
37
+ EXPOSE 7860 8080
38
+ CMD ["/start.sh"]