pub const MAX_JSON_SAMPLE_LENGTH: usize = 100_000;
pub const MINIFY_SIZE_LIMIT: usize = 5_000_000;
#[derive(Debug, Clone)]
pub struct ContextParams<'a> {
pub input_schema: Option<&'a str>,
pub base_query: Option<&'a str>,
pub base_query_result: Option<&'a str>,
pub is_empty_result: bool,
}
#[derive(Debug, Clone)]
pub struct QueryContext {
pub query: String,
pub cursor_pos: usize,
pub output_sample: Option<String>,
pub error: Option<String>,
pub is_success: bool,
pub is_empty_result: bool,
pub input_schema: Option<String>,
pub base_query: Option<String>,
pub base_query_result: Option<String>,
}
impl QueryContext {
pub fn new(
query: String,
cursor_pos: usize,
output: Option<String>,
error: Option<String>,
params: ContextParams,
max_context_length: usize,
) -> Self {
let is_success = error.is_none();
let output_sample = if params.is_empty_result {
None
} else {
output
.as_ref()
.map(|o| prepare_json_for_context(o, max_context_length))
};
let base_query_result = params.base_query_result.map(|s| s.to_string());
Self {
query,
cursor_pos,
output_sample,
error,
is_success,
is_empty_result: params.is_empty_result,
input_schema: params.input_schema.map(|s| s.to_string()),
base_query: params.base_query.map(|s| s.to_string()),
base_query_result,
}
}
}
fn try_minify_json(json: &str) -> Option<String> {
serde_json::from_str::<serde_json::Value>(json)
.ok()
.and_then(|v| serde_json::to_string(&v).ok())
}
pub fn prepare_json_for_context(json: &str, max_len: usize) -> String {
let content = if json.len() <= MINIFY_SIZE_LIMIT {
try_minify_json(json).unwrap_or_else(|| json.to_string())
} else {
json.to_string()
};
truncate_json(&content, max_len)
}
pub fn truncate_json(json: &str, max_len: usize) -> String {
if json.len() <= max_len {
return json.to_string();
}
let truncated = &json[..max_len];
format!("{}... [truncated]", truncated)
}
pub fn prepare_schema_for_context(schema: &str, max_context_length: usize) -> String {
truncate_json(schema, max_context_length)
}
#[cfg(test)]
#[path = "context_tests.rs"]
mod context_tests;