Spaces:
Runtime error
Runtime error
from typing import AsyncGenerator | |
import gradio as gr | |
from anthropic import AI_PROMPT, HUMAN_PROMPT | |
from gradio.components import Checkbox, Dropdown, IOComponent, Markdown, Textbox | |
from gradio.utils import async_iteration | |
from claude_space.ai import AnthropicCustom | |
from claude_space.const import ( | |
ClaudeDefaultFormatter, | |
ClaudeModels, | |
ModelTokenLength, | |
Prompts, | |
) | |
from claude_space.settings import settings | |
conversation_history = "" | |
async def interact_with_ai( | |
user_question, token, model, token_length, prompt, prompt_input, memory | |
): | |
global conversation_history | |
if token is None or token == "" and settings.ANTHROPIC_API_KEY is None: | |
raise TypeError( | |
"You have not provided an API key. Please provide one in the textbox." | |
) | |
if memory: | |
finalPrompt = ClaudeDefaultFormatter.memory.value.format( | |
memory=conversation_history, | |
question=user_question, | |
prompt=Prompts[prompt].value, | |
) | |
else: | |
finalPrompt = ClaudeDefaultFormatter.memory.value.format( | |
memory="", question=user_question, prompt=Prompts[prompt].value | |
) | |
if prompt_input != Prompts[prompt].value: | |
prompt = ClaudeDefaultFormatter.memory.value.format( | |
memory=conversation_history, question=user_question, prompt=prompt_input | |
) | |
anth = AnthropicCustom( | |
api_key=token, model=model, max_tokens=token_length, prompt=finalPrompt | |
) | |
response_accumulated = "" | |
async for response in anth.get_anthropic_response_async(): | |
response_accumulated += response | |
conversation_history = f"{conversation_history} {HUMAN_PROMPT} {user_question} {AI_PROMPT} {response_accumulated}" | |
yield response_accumulated | |
async def chat_with_ai( | |
message, | |
history, | |
token, | |
model, | |
token_length, | |
prompt, | |
prompt_input, | |
memory, | |
): | |
global conversation_history | |
if token is None or token == "" and settings.ANTHROPIC_API_KEY is None: | |
raise TypeError( | |
"You have not provided an API key. Please provide one in the textbox." | |
) | |
if memory: | |
for conversation in history: | |
user_question, response_accumulated = conversation | |
conversation_history = f"{conversation_history} {HUMAN_PROMPT} {user_question} {AI_PROMPT} {response_accumulated}" | |
finalPrompt = ClaudeDefaultFormatter.memory.value.format( | |
memory=conversation_history, question=message, prompt=Prompts[prompt].value | |
) | |
else: | |
finalPrompt = ClaudeDefaultFormatter.memory.value.format( | |
memory="", question=message, prompt=Prompts[prompt].value | |
) | |
if prompt_input != Prompts[prompt].value: | |
prompt = ClaudeDefaultFormatter.memory.value.format( | |
memory=conversation_history, question=message, prompt=prompt_input | |
) | |
anth = AnthropicCustom( | |
api_key=token, model=model, max_tokens=token_length, prompt=finalPrompt | |
) | |
response_accumulated = "" | |
async for response in anth.get_anthropic_response_async(): | |
response_accumulated += response | |
yield response_accumulated | |
def add_file(history, file): | |
history = history + [((file.name,), None)] | |
return history | |
def clear_and_save_textbox(message: str) -> tuple[str, str]: | |
return "", message | |
def display_input( | |
message: str, history: list[list[str | None]] | |
) -> tuple[list[list[str | None]], list[list[str | None]]]: | |
history.append([message, None]) | |
return history, history | |
async def stream_fn( | |
message: str, | |
history_with_input: list[list[str | None]], | |
*args, | |
) -> AsyncGenerator: | |
history = history_with_input[:-1] | |
generator = chat_with_ai(message, history, *args) | |
try: | |
first_response = await async_iteration(generator) | |
update = history + [[message, first_response]] | |
yield update, update | |
except StopIteration: | |
update = history + [[message, None]] | |
yield update, update | |
async for response in generator: | |
update = history + [[message, response]] | |
yield update, update | |
with gr.Blocks() as cface: | |
with gr.Row(variant="compact", equal_height=True): | |
with gr.Column(scale=1): | |
t: IOComponent = Textbox( | |
label="Token", | |
info="You'll get this token from Anthropic console and this is mandatory", | |
placeholder="Enter a token here", | |
type="password", | |
) | |
m: IOComponent = Dropdown( | |
choices=[model.value for model in ClaudeModels], | |
label="Model", | |
value=[model.value for model in ClaudeModels][0], | |
) | |
dL: IOComponent = Dropdown( | |
choices=[token.value for token in ModelTokenLength], | |
label="Token Length", | |
value=[token.value for token in ModelTokenLength][0], | |
) | |
pd: IOComponent = Dropdown( | |
choices=list(Prompts.__members__.keys()), | |
label="Prompt", | |
value=list(Prompts.__members__.keys())[0], | |
) | |
pi: IOComponent = Textbox( | |
label="Custom Prompt", | |
placeholder="Enter a custom prompt here", | |
lines=3, | |
value=Prompts[pd.value].value, | |
) | |
c: IOComponent = Checkbox(label="Memory", value=True) | |
btn: IOComponent = gr.Button("Send") | |
with gr.Column(scale=3): | |
chatbot = gr.Chatbot( | |
[], | |
elem_id="chatbot", | |
) | |
with gr.Row(): | |
msg = gr.Textbox( | |
scale=4, | |
show_label=False, | |
placeholder="Enter text and press enter, or upload an image", | |
container=False, | |
) | |
btn = gr.UploadButton("📁", file_types=["image"]) | |
clear = gr.ClearButton([msg, chatbot]) | |
pd.change( | |
lambda choice: gr.update(value=Prompts[choice].value), inputs=pd, outputs=pi | |
) | |
saved_input = gr.State() | |
chatbot_state = gr.State([]) | |
text_msg = ( | |
msg.submit( | |
clear_and_save_textbox, | |
[msg], | |
[msg, saved_input], | |
api_name=False, | |
queue=False, | |
) | |
.then( | |
display_input, | |
[saved_input, chatbot_state], | |
[chatbot, chatbot_state], | |
api_name=False, | |
queue=False, | |
) | |
.then( | |
stream_fn, | |
[saved_input, chatbot_state, t, m, dL, pd, pi, c], | |
[chatbot, chatbot_state], | |
api_name=False, | |
) | |
) | |
# file_msg = btn.upload(add_file, [chatbot, btn], [chatbot], queue=False).then( | |
# chat_with_ai, chatbot, chatbot, t, m, dL, pd, pi, c | |
# ) | |
with gr.Blocks() as iface: | |
with gr.Row(variant="compact", equal_height=True): | |
with gr.Column(scale=1): | |
q: IOComponent = Textbox( | |
label="Question", placeholder="Enter a question here" | |
) | |
t: IOComponent = Textbox( | |
label="Token", | |
info="You'll get this token from Anthropic console and this is mandatory", | |
placeholder="Enter a token here", | |
type="password", | |
) | |
m: IOComponent = Dropdown( | |
choices=[model.value for model in ClaudeModels], | |
label="Model", | |
value=[model.value for model in ClaudeModels][0], | |
) | |
dL: IOComponent = Dropdown( | |
choices=[token.value for token in ModelTokenLength], | |
label="Token Length", | |
value=[token.value for token in ModelTokenLength][0], | |
) | |
pd: IOComponent = Dropdown( | |
choices=list(Prompts.__members__.keys()), | |
label="Prompt", | |
value=list(Prompts.__members__.keys())[0], | |
) | |
pi: IOComponent = Textbox( | |
label="Custom Prompt", | |
placeholder="Enter a custom prompt here", | |
lines=3, | |
value=Prompts[pd.value].value, | |
) | |
c: IOComponent = Checkbox(label="Memory", value=False) | |
btn: IOComponent = gr.Button("Send") | |
with gr.Column(scale=3): | |
mk: IOComponent = Markdown(" ") | |
pd.change( | |
lambda choice: gr.update(value=Prompts[choice].value), inputs=pd, outputs=pi | |
) | |
btn.click( | |
interact_with_ai, | |
inputs=[q, t, m, dL, pd, pi, c], | |
outputs=mk, | |
) | |
gd = gr.TabbedInterface( | |
[iface, cface], tab_names=["Claude Evals", "Claude Chat"], title="Claude Space" | |
) | |
gd.queue(concurrency_count=75, max_size=100).launch( | |
debug=True, | |
share=False, | |
server_name="0.0.0.0", | |
server_port=7860, | |
show_error=True, | |
show_tips=True, | |
) | |