You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

121 lines
3.7 KiB

use ai_core::ai::Params;
use gloo_net::http::Request;
use leptos::{
html::{Input, Option_, Select, Textarea},
*,
};
use serde_json::{json, Value};
#[component]
pub fn GenerationUI(cx: Scope) -> impl IntoView {
let input: NodeRef<Textarea> = create_node_ref(cx);
let output: NodeRef<Textarea> = create_node_ref(cx);
let ai_selector: NodeRef<Select> = create_node_ref(cx);
let temp: NodeRef<Input> = create_node_ref(cx);
let max_tokens: NodeRef<Input> = create_node_ref(cx);
let generate_action = create_action(cx, move |_: &()| async move {
// these unwraps should never fail as the elements will always exist at this point
let prompt = input.get().unwrap().value();
let output = output.get().unwrap();
let temperature = temp.get().unwrap().value_as_number();
let max_tokens = max_tokens.get().unwrap().value_as_number();
let ai_selector = ai_selector.get().unwrap().value();
output.set_value("Generating...");
let res = Request::post("/api/generate")
.json(&json!({
"ai": ai_selector,
"params": Params {
prompt,
max_tokens: max_tokens as _,
temperature: temperature as _
}
}))
.unwrap()
.send()
.await;
match res {
Ok(res) => {
if res.status() != 200 {
output.set_value("Failed to generate!");
tracing::error!("Status code not 200");
return;
}
let res = res.text().await.unwrap(); // should be safe to unwrap here?
output.set_value(&res);
}
Err(err) => {
output.set_value("Failed to generate!");
tracing::error!("{}", err);
}
}
});
_ = create_resource(cx, || (), move |_| async move {
let res = Request::get("/api/ais").send().await;
match res {
Ok(res) => {
if res.status() != 200 {
tracing::error!("Status code not 200 for AI selector fetch");
return;
}
// these should never fail in theory
let res: Value = res.json().await.unwrap();
let res = res.as_array().unwrap().to_vec();
for ai in res {
let ai = ai.as_str().unwrap(); // should never fail
let option = &Option_::default();
option.set_value(ai);
option.set_label(ai);
ai_selector.get().unwrap().append_child(&option).unwrap();
}
}
Err(err) => {
tracing::error!("Failed to get AIs for selector! {}", err);
}
}
});
view! { cx,
<main>
<div class="bar">
<button on:click=move |_| {
generate_action.dispatch(());
}>
"Generate"
</button>
<h5>"AI"</h5>
<select node_ref=ai_selector />
<h5>"Temperature"</h5>
<input type="number" min="0" max="2" step="0.1" value="1" node_ref=temp />
<h5>"Max Tokens"</h5>
<input type="number" min="0" max="2000" step="10" value="1000" node_ref=max_tokens />
</div>
<div class="io">
<textarea node_ref=input />
<textarea readonly="true" node_ref=output />
</div>
</main>
}
}