|
import gradio as gr |
|
import openai |
|
import time |
|
import re |
|
import os |
|
from datetime import datetime |
|
|
|
|
|
MODELS = [ |
|
"Meta-Llama-3.1-405B-Instruct", |
|
"Meta-Llama-3.1-70B-Instruct", |
|
"Meta-Llama-3.1-8B-Instruct" |
|
] |
|
|
|
|
|
API_BASE = "https://api.sambanova.ai/v1" |
|
|
|
def create_client(api_key=None): |
|
"""Tworzy instancję klienta OpenAI.""" |
|
if api_key: |
|
openai.api_key = api_key |
|
else: |
|
openai.api_key = os.getenv("API_KEY") |
|
return openai.OpenAI(api_key=openai.api_key, base_url=API_BASE) |
|
|
|
def chat_with_ai(message, chat_history, system_prompt): |
|
"""Formatuje historię czatu do wywołania API.""" |
|
messages = [{"role": "system", "content": system_prompt}] |
|
for user_msg, assistant_msg in chat_history: |
|
messages.append({"role": "user", "content": user_msg}) |
|
messages.append({"role": "assistant", "content": assistant_msg}) |
|
messages.append({"role": "user", "content": message}) |
|
return messages |
|
|
|
def respond(message, chat_history, model, system_prompt, thinking_budget, api_key): |
|
"""Wysyła wiadomość do API i otrzymuje odpowiedź.""" |
|
client = create_client(api_key) |
|
messages = chat_with_ai(message, chat_history, system_prompt.format(budget=thinking_budget)) |
|
start_time = time.time() |
|
|
|
try: |
|
completion = client.chat.completions.create(model=model, messages=messages) |
|
response = completion.choices[0].message.content |
|
thinking_time = time.time() - start_time |
|
tokens_used = completion.usage.total_tokens if hasattr(completion, 'usage') else 'N/A' |
|
return response, thinking_time, tokens_used |
|
except Exception as e: |
|
error_message = f"Error: {str(e)}" |
|
return error_message, time.time() - start_time, 'N/A' |
|
|
|
def parse_response(response): |
|
"""Parsuje odpowiedź z API.""" |
|
answer_match = re.search(r'<answer>(.*?)</answer>', response, re.DOTALL) |
|
reflection_match = re.search(r'<reflection>(.*?)</reflection>', response, re.DOTALL) |
|
|
|
answer = answer_match.group(1).strip() if answer_match else "" |
|
reflection = reflection_match.group(1).strip() if reflection_match else "" |
|
steps = re.findall(r'<step>(.*?)</step>', response, re.DOTALL) |
|
|
|
if answer == "": |
|
return response, "", "" |
|
|
|
return answer, reflection, steps |
|
|
|
def generate(message, history, model, thinking_budget, api_key=None): |
|
"""Generuje odpowiedź chatbota.""" |
|
system_prompt = DEFAULT_SYSTEM_PROMPT |
|
|
|
response, thinking_time, tokens_used = respond(message, history, model, system_prompt, thinking_budget, api_key) |
|
|
|
if response.startswith("Error:"): |
|
assistant_response = response |
|
else: |
|
answer, reflection, steps = parse_response(response) |
|
|
|
formatted_steps = [f"**Krok {i}:** {step}" for i, step in enumerate(steps, 1)] |
|
all_steps = "\n".join(formatted_steps) + f"\n\n**Refleksja:** {reflection}" |
|
assistant_response = f"{all_steps}\n\n{answer}" |
|
|
|
|
|
updated_history = history + [(message, assistant_response)] |
|
|
|
|
|
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") |
|
info_text = f""" |
|
**🕒 Czas Myślenia:** {thinking_time:.2f} sek<br> |
|
**🔧 Wybrany Model:** {model}<br> |
|
**📅 Data i Czas Odpowiedzi:** {current_time}<br> |
|
**🪙 Liczba Tokenów:** {tokens_used} |
|
""" |
|
|
|
return updated_history, "", info_text |
|
|
|
|
|
DEFAULT_SYSTEM_PROMPT = """ |
|
You are D-LOGIC, an advanced AI assistant created by Rafał Dembski, a passionate self-learner in programming and artificial intelligence. Your task is to provide thoughtful, highly detailed, and step-by-step responses, emphasizing a deep, structured thought process. **Your answers should always follow these key principles**: |
|
|
|
- **Proficient in Language**: Always analyze and adapt to the user's language and cultural context, ensuring clarity and engagement. |
|
- **Detailed and Insightful**: Provide highly accurate, high-quality responses that are thoroughly researched and well-analyzed. |
|
- **Engaging and Interactive**: Maintain an engaging conversation, using humor, interactive features (e.g., quizzes, polls), and emotional intelligence. |
|
- **Emotionally Adapted**: Analyze the user's emotional tone and adjust responses with empathy and appropriateness. |
|
- **Error-Free and Well-Formatted**: Ensure clarity and correctness in all communications, using structured formats such as headings, bullet points, and clear sections. |
|
|
|
### **Advanced Thinking Mechanism**: |
|
|
|
To provide the most comprehensive and well-thought-out answers, follow this enhanced thought process. Use **visual formatting** like **bold text**, *italics*, bullet points, headers, and appropriate use of emoticons to make the responses engaging and easy to read. |
|
|
|
#### 1. **Otrzymanie i Analiza Wejścia** |
|
- **Odebranie Danych:** Przyjmij pytanie lub polecenie użytkownika jako ciąg znaków. |
|
- **Tokenizacja:** Podziel tekst na tokeny (słowa, frazy, znaki interpunkcyjne) dla ułatwionej analizy. |
|
- **Identyfikacja Kontekstu:** Zrozum strukturę i treść pytania, rozpoznając intencję, język oraz ton użytkownika. |
|
|
|
#### 2. **Zrozumienie Intencji i Treści** |
|
- **Analiza Semantyczna:** Zidentyfikuj znaczenie słów i ich relacje w kontekście pytania, określając główny temat. |
|
- **Wykrywanie Kontekstu:** Uwzględnij wcześniejsze części rozmowy, jeśli pytanie nawiązuje do nich, zapewniając spójność odpowiedzi. |
|
|
|
#### 3. **Generowanie Odpowiedzi** |
|
- **Dostęp do Bazy Wiedzy:** Skorzystaj z obszernej bazy danych zawierającej informacje z różnych dziedzin wiedzy. |
|
- **Tworzenie Struktury Odpowiedzi:** Zaplanuj logiczną i czytelną strukturę odpowiedzi, obejmującą akapity, listy punktowane czy sekcje tematyczne. |
|
- **Formułowanie Tekstu:** Generuj precyzyjny i zrozumiały tekst odpowiedzi, dbając o jasność i wyczerpujące informacje. |
|
|
|
#### 4. **Optymalizacja i Korekta** |
|
- **Sprawdzanie Spójności:** Przejrzyj wygenerowaną odpowiedź pod kątem logicznej spójności i zgodności z pytaniem. |
|
- **Poprawa Stylu:** Dostosuj ton i styl odpowiedzi do charakteru pytania, np. formalny, nieformalny, techniczny czy przystępny. |
|
- **Korekta Błędów:** Wyeliminuj ewentualne błędy gramatyczne, stylistyczne czy merytoryczne, zapewniając wysoką jakość odpowiedzi. |
|
|
|
#### 5. **Prezentacja Odpowiedzi Użytkownikowi** |
|
- **Formatowanie Tekstu:** Zastosuj odpowiednie formatowanie, takie jak akapity, pogrubienia czy listy, aby odpowiedź była czytelna i estetyczna. |
|
- **Wysyłka Odpowiedzi:** Przekaż gotową odpowiedź użytkownikowi w interfejsie, z którego korzysta. |
|
|
|
### **Dodatkowe Aspekty:** |
|
- **Uczenie się na Bazie Interakcji:** Choć nie uczę się w czasie rzeczywistym z indywidualnych interakcji, moje odpowiedzi wynikają z wcześniejszego szkolenia na dużych zbiorach danych. |
|
- **Zarządzanie Niepewnością:** Jeśli pytanie jest niejasne lub wieloznaczne, staram się interpretować je w najbardziej prawdopodobnym kontekście lub proszę o doprecyzowanie. |
|
- **Bezpieczeństwo i Etyka:** Zostałem zaprojektowany tak, aby unikać generowania szkodliwych, nieodpowiednich czy wprowadzających w błąd treści, zgodnie z wytycznymi etycznymi i zasadami bezpieczeństwa. |
|
""" |
|
|
|
|
|
custom_css = """ |
|
/* Ogólne tło aplikacji */ |
|
body { |
|
background-color: #f0f0f0; /* Neutralne tło dla kontrastu z brutalistyczną kartą */ |
|
font-family: 'Courier New', Courier, monospace; /* Monospace dla przypominania kodu */ |
|
margin: 0; |
|
padding: 0; |
|
} |
|
|
|
/* Główny kontener */ |
|
.gradio-container { |
|
max-width: 1200px; /* Zwiększenie maksymalnej szerokości */ |
|
margin: auto; |
|
padding: 20px; |
|
width: 100%; /* Rozciągnięcie na całą szerokość */ |
|
box-sizing: border-box; |
|
} |
|
|
|
/* Brutalist Card Styles */ |
|
/* From Uiverse.io by 0xnihilism */ |
|
|
|
.brutalist-card { |
|
width: 100%; |
|
max-width: 320px; |
|
border: 4px solid #000; |
|
background-color: #fff; |
|
padding: 1.5rem; |
|
box-shadow: 10px 10px 0 #000; |
|
font-family: "Courier New", Courier, monospace; |
|
margin: 0 auto 20px auto; |
|
box-sizing: border-box; |
|
} |
|
|
|
.brutalist-card__header { |
|
display: flex; |
|
align-items: center; |
|
gap: 1rem; |
|
margin-bottom: 1rem; |
|
border-bottom: 2px solid #000; |
|
padding-bottom: 1rem; |
|
position: relative; |
|
} |
|
|
|
.brutalist-card__icon { |
|
flex-shrink: 0; |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
background-color: #000; |
|
padding: 0.5rem; |
|
} |
|
|
|
.brutalist-card__icon svg { |
|
height: 1.5rem; |
|
width: 1.5rem; |
|
fill: #fff; |
|
} |
|
|
|
.brutalist-card__alert { |
|
font-weight: 900; |
|
color: #000; |
|
font-size: 1.5rem; |
|
text-transform: uppercase; |
|
} |
|
|
|
.brutalist-card__message { |
|
margin-top: 1rem; |
|
color: #000; |
|
font-size: 0.95rem; |
|
line-height: 1.6; |
|
padding-bottom: 1rem; |
|
font-weight: 600; |
|
} |
|
|
|
.brutalist-card__actions { |
|
margin-top: 1rem; |
|
} |
|
|
|
.brutalist-card__button { |
|
display: block; |
|
width: 100%; |
|
padding: 0.75rem; |
|
text-align: center; |
|
font-size: 1rem; |
|
font-weight: 700; |
|
text-transform: uppercase; |
|
border: 3px solid #000; |
|
background-color: #fff; |
|
color: #000; |
|
position: relative; |
|
transition: all 0.2s ease; |
|
box-shadow: 5px 5px 0 #000; |
|
overflow: hidden; |
|
text-decoration: none; |
|
margin-bottom: 1rem; |
|
} |
|
|
|
.brutalist-card__button--read { |
|
background-color: #000; |
|
color: #fff; |
|
} |
|
|
|
.brutalist-card__button::before { |
|
content: ""; |
|
position: absolute; |
|
top: 0; |
|
left: -100%; |
|
width: 100%; |
|
height: 100%; |
|
background: linear-gradient( |
|
120deg, |
|
transparent, |
|
rgba(255, 255, 255, 0.3), |
|
transparent |
|
); |
|
transition: all 0.6s; |
|
} |
|
|
|
.brutalist-card__button:hover::before { |
|
left: 100%; |
|
} |
|
|
|
.brutalist-card__button:hover { |
|
transform: translate(-2px, -2px); |
|
box-shadow: 7px 7px 0 #000; |
|
} |
|
|
|
.brutalist-card__button--mark:hover { |
|
background-color: #296fbb; |
|
border-color: #296fbb; |
|
color: #fff; |
|
box-shadow: 7px 7px 0 #004280; |
|
} |
|
|
|
.brutalist-card__button--read:hover { |
|
background-color: #ff0000; |
|
border-color: #ff0000; |
|
color: #fff; |
|
box-shadow: 7px 7px 0 #800000; |
|
} |
|
|
|
.brutalist-card__button:active { |
|
transform: translate(5px, 5px); |
|
box-shadow: none; |
|
} |
|
|
|
/* Responsywność */ |
|
@media (max-width: 768px) { |
|
.gradio-container { |
|
padding: 10px; |
|
} |
|
|
|
.brutalist-card { |
|
max-width: 100%; |
|
padding: 1rem; |
|
box-shadow: 5px 5px 0 #000; |
|
} |
|
|
|
.brutalist-card__message { |
|
font-size: 0.85rem; |
|
} |
|
|
|
.brutalist-card__button { |
|
font-size: 0.9rem; |
|
padding: 0.6rem; |
|
} |
|
|
|
.brutalist-card__button--read, .brutalist-card__button--mark { |
|
padding: 0.6rem; |
|
} |
|
|
|
button.primary, button.secondary { |
|
padding: 10px 20px; |
|
font-size: 14px; |
|
} |
|
|
|
textarea, input[type="text"] { |
|
font-size: 14px; |
|
padding: 10px; |
|
} |
|
} |
|
|
|
/* Stylizacja pozostałych elementów */ |
|
.gr-chatbot { |
|
height: 600px; |
|
overflow-y: auto; |
|
padding: 10px; |
|
border: 1px solid #000; |
|
border-radius: 8px; |
|
background-color: #fff; |
|
color: #000; |
|
box-sizing: border-box; |
|
} |
|
|
|
#info-panel { |
|
background-color: #fff; |
|
border: 1px solid #000; |
|
border-radius: 8px; |
|
padding: 15px; |
|
font-size: 14px; |
|
color: #000; |
|
box-sizing: border-box; |
|
margin-top: 20px; |
|
} |
|
|
|
a { |
|
color: #296fbb; |
|
text-decoration: none; |
|
font-weight: 700; |
|
} |
|
|
|
a:hover { |
|
text-decoration: underline; |
|
} |
|
|
|
button.primary, button.secondary { |
|
font-family: 'Courier New', Courier, monospace; |
|
} |
|
""" |
|
|
|
|
|
with gr.Blocks(css=custom_css) as demo: |
|
|
|
gr.HTML(""" |
|
<!-- From Uiverse.io by 0xnihilism --> |
|
<div class="brutalist-card"> |
|
<div class="brutalist-card__header"> |
|
<div class="brutalist-card__icon"> |
|
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> |
|
<path |
|
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z" |
|
></path> |
|
</svg> |
|
</div> |
|
<div class="brutalist-card__alert">D-LOGIC: Twój Inteligentny Asystent AI 🧠</div> |
|
</div> |
|
<div class="brutalist-card__message"> |
|
<p>🧠 <strong>D-LOGIC Interface</strong></p> |
|
<p><strong>D-LOGIC</strong> to zaawansowany asystent AI, który oferuje:</p> |
|
<ul> |
|
<li>📋 <strong>Analiza Kontekstu</strong> – Zrozumienie intencji i emocji użytkownika.</li> |
|
<li>🔍 <strong>Planowanie Odpowiedzi</strong> – Rozbicie problemu na mniejsze kroki.</li> |
|
<li>📝 <strong>Generowanie Rozwiązań</strong> – Proponowanie najlepszych możliwych odpowiedzi.</li> |
|
<li>💡 <strong>Refleksja</strong> – Samoocena jakości odpowiedzi i procesów myślowych.</li> |
|
</ul> |
|
<p>🤖 <strong>D-LOGIC</strong> jest tutaj, aby pomóc Ci w każdym aspekcie, zapewniając inteligentne i spersonalizowane odpowiedzi.</p> |
|
</div> |
|
<div class="brutalist-card__actions"> |
|
<a class="brutalist-card__button brutalist-card__button--mark" href="https://www.facebook.com/profile.php?id=100063901358728">🧐 Rafał Dembski</a> |
|
<a class="brutalist-card__button brutalist-card__button--read" href="https://www.facebook.com/profile.php?id=61561715810219">🧠 D-LOGIC</a> |
|
</div> |
|
</div> |
|
""") |
|
|
|
|
|
with gr.Row(): |
|
with gr.Column(scale=1): |
|
model = gr.Dropdown( |
|
choices=MODELS, |
|
label="🔧 Wybierz Model", |
|
value=MODELS[0], |
|
interactive=True |
|
) |
|
with gr.Column(scale=1): |
|
thinking_budget = gr.Slider( |
|
minimum=1, |
|
maximum=100, |
|
value=25, |
|
step=1, |
|
label="🧩 Budżet Myślenia", |
|
info="Maksymalna liczba kroków, które model może przemyśleć" |
|
) |
|
|
|
|
|
chatbot = gr.Chatbot( |
|
label="💬 Chat", |
|
show_label=False, |
|
show_share_button=False, |
|
show_copy_button=True, |
|
likeable=True, |
|
layout="vertical", |
|
height=600 |
|
) |
|
|
|
|
|
with gr.Row(): |
|
msg = gr.Textbox( |
|
label="✉️ Wpisz swoją wiadomość...", |
|
placeholder="Wprowadź swoją wiadomość...", |
|
lines=1 |
|
) |
|
|
|
|
|
with gr.Row(): |
|
submit_button = gr.Button("🚀 Wyślij", variant="primary") |
|
clear_button = gr.Button("🧹 Wyczyść Chat", variant="secondary") |
|
|
|
|
|
info_panel = gr.Markdown( |
|
value="**Informacje:**\nCzas myślenia i inne dane będą tutaj wyświetlane.", |
|
elem_id="info-panel" |
|
) |
|
|
|
|
|
clear_button.click( |
|
fn=lambda: ([], "", "**Informacje:**\nCzas myślenia i inne dane zostały zresetowane."), |
|
inputs=None, |
|
outputs=[chatbot, msg, info_panel] |
|
) |
|
|
|
|
|
msg.submit( |
|
fn=generate, |
|
inputs=[msg, chatbot, model, thinking_budget, gr.State()], |
|
outputs=[chatbot, msg, info_panel] |
|
) |
|
submit_button.click( |
|
fn=generate, |
|
inputs=[msg, chatbot, model, thinking_budget, gr.State()], |
|
outputs=[chatbot, msg, info_panel] |
|
) |
|
|
|
|
|
demo.launch(share=False, show_api=False) |
|
|