use wasmtime::{Caller, Val};
use crate::MangledName;
pub(crate) const MAX_SCHEMA_BYTES: usize = crate::runtime::llm::DEFAULT_MAX_PROMPT_BYTES as usize;
use crate::runtime::StoreData;
use crate::runtime::fuel;
use crate::runtime::host::{read_string_arg, type_error};
use crate::runtime::prelude::undefined;
pub(crate) fn read_written_schema(
caller: &mut Caller<'_, StoreData>,
val: &Val,
api: &str,
) -> wasmtime::Result<Option<String>> {
if undefined::is_undefined(caller, val)? {
return Ok(None);
}
let schema = read_string_arg(caller, val, &format!("{api} (schema)"))?;
fuel::charge(&mut *caller, fuel::PARSE, schema.len() as u64)?;
match serde_json::from_str::<serde_json::Value>(&schema) {
Ok(serde_json::Value::Object(_)) => Ok(Some(schema)),
_ => Err(type_error(format!(
"{api}: `schema` is not a JSON Schema: write a JSON object"
))),
}
}
pub(crate) struct SchemaCheckedCall {
pub callee: &'static str,
pub example: &'static str,
pub checks: &'static str,
pub answerer: &'static str,
pub text_hint: &'static str,
}
pub(crate) fn schema_checked_call(mangled: &MangledName) -> Option<SchemaCheckedCall> {
if super::llm::declaration::is_checked_batch(mangled) {
return Some(SchemaCheckedCall {
callee: "llm.batch",
example: "llm.batch<Severity>(model, prompts)",
checks: "each model response",
answerer: "the model",
text_hint: "call `llm.texts(model, prompts)` for the completion texts",
});
}
if super::llm::declaration::is_checked_call(mangled) {
return Some(SchemaCheckedCall {
callee: "llm.call",
example: "llm.call<Severity>(model, prompt)",
checks: "the model's response",
answerer: "the model",
text_hint: "call `llm.text(model, prompt)` for the completion text",
});
}
if super::agents::declaration::is_checked_run(mangled) {
return Some(SchemaCheckedCall {
callee: "agents.run",
example: "agents.run<Report>(agent, input)",
checks: "the agent's result",
answerer: "the agent",
text_hint: "call `agents.runText(agent, input)` for the answer as text",
});
}
None
}