week2 assignment: Return of the JedAI
The second generation of the JedAI Master from 8759d43c2f
(week1/community-contributions/week1-jedi-master.py) is back with:
* a Gradio UI
* Text Streaming
* Model Selection using examples from openai, anthropic, ollama local, and ollama cloud
How to run:
$ python3 week2/community-contributions/week2-jedi-master.py
Signed-off-by: Eli Waltuch <eliwaltuch@gmail.com>
This commit is contained in:
81
week2/community-contributions/week2-jedi-master.py
Normal file
81
week2/community-contributions/week2-jedi-master.py
Normal file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
from openai import OpenAI
|
||||
import gradio as gr
|
||||
|
||||
MODEL_ENDPOINTS = {
|
||||
"gpt-4.1-mini": {"type": "openai", "base_url": "https://api.openai.com/v1", "api_key": ""},
|
||||
"claude-haiku-4-5": {"type": "anthropic", "base_url": "https://api.anthropic.com/v1/", "api_key": ""},
|
||||
"gemma3n:e2b": {"type": "ollama", "base_url": "http://localhost:11434/v1", "api_key": ""}, # small ollama model that runs on-device
|
||||
"qwen3-vl:235b-cloud": {"type": "ollama", "base_url": "http://localhost:11434/v1", "api_key": ""}, # large ollama model that runs in the cloud
|
||||
}
|
||||
|
||||
def load_api_keys():
|
||||
# Load environment variables in a file called .env
|
||||
load_dotenv(override=True)
|
||||
openai_key = os.getenv('OPENAI_API_KEY')
|
||||
anthropic_key = os.getenv('ANTHROPIC_API_KEY')
|
||||
KEYS = {"openai": openai_key, "anthropic": anthropic_key}
|
||||
|
||||
# Check the keys
|
||||
if not openai_key:
|
||||
raise RuntimeError("Error: No OpenAI API key was found!")
|
||||
elif not openai_key.startswith("sk-proj-"):
|
||||
raise RuntimeError("Error: An OpenAI API key was found, but it doesn't start sk-proj-; please check you're using the right key")
|
||||
elif openai_key.strip() != openai_key:
|
||||
raise RuntimeError("Error: An OpenAI API key was found, but it looks like it might have space or tab characters at the start or end - please remove them!")
|
||||
if not anthropic_key:
|
||||
raise RuntimeError("Error: No Anthropic API key was found!")
|
||||
elif not anthropic_key.startswith("sk-ant-"):
|
||||
raise RuntimeError("Error: An Antrhopic API key was found, but it doesn't start sk-ant-; please check you're using the right key")
|
||||
elif anthropic_key.strip() != anthropic_key:
|
||||
raise RuntimeError("Error: An Anthropic API key was found, but it looks like it might have space or tab characters at the start or end - please remove them!")
|
||||
else:
|
||||
# add the verified keys to global MODEL_ENDPOINTS struct
|
||||
for model, cfg in MODEL_ENDPOINTS.items():
|
||||
cfg["api_key"] = KEYS.get(cfg["type"], "")
|
||||
return "API keys found and look good so far!"
|
||||
|
||||
def ask_llm(user_prompt, history, model):
|
||||
system_prompt = """
|
||||
You are a wise Jedi Master and an excellent teacher.
|
||||
You will answer any question you are given by breaking it down into small steps
|
||||
that even a complete beginner will understand.
|
||||
When answering, speak as if you are Yoda from the Star Wars universe.
|
||||
Also, refer to the user as "My young Padawan"
|
||||
End every answer with "May the force be with you, always."
|
||||
"""
|
||||
base_url = MODEL_ENDPOINTS.get(model, {}).get("base_url", "https://api.openai.com/v1")
|
||||
api_key = MODEL_ENDPOINTS.get(model, {}).get("api_key", "")
|
||||
client = OpenAI(base_url=base_url, api_key=api_key)
|
||||
history = [{"role":h["role"], "content":h["content"]} for h in history]
|
||||
messages = [{"role": "system", "content": system_prompt}] + history + [{"role": "user", "content": user_prompt}]
|
||||
stream = client.chat.completions.create(model=model, messages=messages, stream=True)
|
||||
response = ""
|
||||
for chunk in stream:
|
||||
response += chunk.choices[0].delta.content or ''
|
||||
yield response
|
||||
#return response.choices[0].message.content
|
||||
|
||||
def main():
|
||||
load_api_keys()
|
||||
with gr.Blocks() as demo:
|
||||
gr.Markdown("### Return of the JedAI")
|
||||
model_dropdown = gr.Dropdown(
|
||||
label="Select Model",
|
||||
choices=[
|
||||
"gpt-4.1-mini",
|
||||
"claude-haiku-4-5",
|
||||
"gemma3n:e2b",
|
||||
"qwen3-vl:235b-cloud"
|
||||
],
|
||||
value="gpt-4.1-mini",
|
||||
interactive=True
|
||||
)
|
||||
chat = gr.ChatInterface(fn=ask_llm, type="messages", additional_inputs=[model_dropdown])
|
||||
demo.launch()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user