Skip to content

Commit 9b957cf

Browse files
add sleep, str_similarity, omc_eval_file, file_ls, llm_judge, llm_compare builtins + docs
- Fix omc_eval_file: inline eval_omc logic instead of invalid Expression::StringLiteral call - Add sleep(ms), str_similarity(a,b), omc_eval_file(path) to is_known_builtin + ALL_BUILTINS - Add docs entries for: llm_judge, llm_compare, sleep, str_similarity, omc_eval_file, file_ls Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 876a171 commit 9b957cf

2 files changed

Lines changed: 126 additions & 1 deletion

File tree

omnimcode-core/src/docs.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,77 @@ h v2 = substrate_embed("hello there", 16)
13971397
# compute cosine similarity in OMC..."#,
13981398
unique_to_omc: true,
13991399
},
1400+
BuiltinDoc {
1401+
name: "llm_judge", category: "llm_workflow",
1402+
signature: "(responses: string[], criteria: string, model?: string) -> dict[]",
1403+
description: concat!(
1404+
"Score an array of LLM response strings against a criteria string. ",
1405+
"Sends a structured prompt to the LLM asking it to rate each response 0-10. ",
1406+
"Returns an array of dicts, each with keys `idx` (int), `score` (float), `reason` (string). ",
1407+
"Useful as the evaluation step in best-of-N improvement loops."
1408+
),
1409+
example: r#"h responses = ["Paris", "London", "Berlin"]
1410+
h scores = llm_judge(responses, "Which is the capital of France?")
1411+
print(scores[0]["score"])"#,
1412+
unique_to_omc: true,
1413+
},
1414+
BuiltinDoc {
1415+
name: "llm_compare", category: "llm_workflow",
1416+
signature: "(a: string, b: string, criteria: string, model?: string) -> dict",
1417+
description: concat!(
1418+
"Compare two LLM responses head-to-head against a criteria string. ",
1419+
"Returns a dict `{winner: \"A\"|\"B\", reason: string}`. ",
1420+
"Useful for tournament-style selection in multi-agent systems."
1421+
),
1422+
example: r#"h r = llm_compare("short answer", "detailed answer", "clarity and correctness")
1423+
print(r["winner"]) # "A" or "B"
1424+
print(r["reason"])"#,
1425+
unique_to_omc: true,
1426+
},
1427+
// ── Utility builtins ─────────────────────────────────────────────────────
1428+
BuiltinDoc {
1429+
name: "sleep", category: "io",
1430+
signature: "(ms: int) -> null",
1431+
description: "Sleep for the specified number of milliseconds. Useful for rate-limiting LLM calls or polling loops.",
1432+
example: r#"sleep(500) # pause 0.5 seconds"#,
1433+
unique_to_omc: false,
1434+
},
1435+
BuiltinDoc {
1436+
name: "str_similarity", category: "string",
1437+
signature: "(a: string, b: string) -> float",
1438+
description: concat!(
1439+
"Compute cosine similarity between two strings using phi-pi-fibonacci harmonic embeddings (32 dims). ",
1440+
"Returns a float in [-1, 1]. Values near 1.0 indicate high similarity. ",
1441+
"No API call required — uses the same offline substrate_embed algorithm."
1442+
),
1443+
example: r#"h sim = str_similarity("hello world", "hello there")
1444+
print(sim) # ~0.95"#,
1445+
unique_to_omc: true,
1446+
},
1447+
BuiltinDoc {
1448+
name: "omc_eval_file", category: "meta",
1449+
signature: "(path: string) -> any",
1450+
description: concat!(
1451+
"Read and evaluate an OMC source file at `path` within the current interpreter context. ",
1452+
"Functions defined in the file are registered into the caller's scope. ",
1453+
"Returns the last expression value of the evaluated file. ",
1454+
"Like `eval_omc(read_file(path))` but atomic."
1455+
),
1456+
example: r#"omc_eval_file("examples/lib/llm.omc")
1457+
h reply = llm_call("hello") # function defined in lib file"#,
1458+
unique_to_omc: true,
1459+
},
1460+
BuiltinDoc {
1461+
name: "file_ls", category: "io",
1462+
signature: "(path?: string) -> string[]",
1463+
description: concat!(
1464+
"List entries in a directory. `path` defaults to \".\" (current directory). ",
1465+
"Returns a sorted array of filename strings (not full paths)."
1466+
),
1467+
example: r#"h files = file_ls("examples/demos")
1468+
print(files) # ["best_of_n_improve.omc", "multi_agent_debate.omc", ...]"#,
1469+
unique_to_omc: true,
1470+
},
14001471
// ── HTTP builtins ─────────────────────────────────────────────────────────
14011472
BuiltinDoc {
14021473
name: "http_get", category: "http",

omnimcode-core/src/interpreter.rs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2314,7 +2314,8 @@ impl Interpreter {
23142314
// I/O
23152315
| "read_file" | "write_file" | "file_exists" | "print"
23162316
| "println" | "print_raw"
2317-
// Time, conversion, introspection
2317+
// Time, sleep, conversion, introspection
2318+
| "sleep" | "str_similarity" | "omc_eval_file"
23182319
| "now_ms" | "to_int" | "int" | "to_float" | "float"
23192320
| "to_string" | "string" | "len" | "type_of" | "error"
23202321
| "defined_functions" | "call"
@@ -4885,6 +4886,57 @@ impl Interpreter {
48854886
names.sort_by(|a, b| a.to_display_string().cmp(&b.to_display_string()));
48864887
Ok(Value::Array(HArray::from_vec(names)))
48874888
}
4889+
"sleep" => {
4890+
let ms = if args.is_empty() { 0i64 } else {
4891+
match self.eval_expr(&args[0])? {
4892+
Value::HInt(n) => n.value,
4893+
Value::HFloat(f) => f as i64,
4894+
_ => 0,
4895+
}
4896+
};
4897+
if ms > 0 {
4898+
std::thread::sleep(std::time::Duration::from_millis(ms as u64));
4899+
}
4900+
Ok(Value::Null)
4901+
}
4902+
"omc_eval_file" => {
4903+
if args.is_empty() {
4904+
return Err("omc_eval_file requires (path)".to_string());
4905+
}
4906+
let path = self.eval_expr(&args[0])?.to_display_string();
4907+
let src = std::fs::read_to_string(&path)
4908+
.map_err(|e| format!("omc_eval_file: {}", e))?;
4909+
let mut parser = crate::parser::Parser::new(&src);
4910+
let stmts = parser.parse().map_err(|e| format!("omc_eval_file parse error: {}", e))?;
4911+
self.register_user_functions(&stmts);
4912+
let pre_last = self.last_expression_value.take();
4913+
self.execute(stmts)?;
4914+
let result = self.last_expression_value.take().unwrap_or(Value::Null);
4915+
self.last_expression_value = pre_last;
4916+
Ok(result)
4917+
}
4918+
"str_similarity" => {
4919+
if args.len() < 2 {
4920+
return Err("str_similarity requires (a, b)".to_string());
4921+
}
4922+
let a = self.eval_expr(&args[0])?.to_display_string();
4923+
let b = self.eval_expr(&args[1])?.to_display_string();
4924+
let va = crate::llm_builtins::substrate_embed(&a, 32);
4925+
let vb = crate::llm_builtins::substrate_embed(&b, 32);
4926+
if let (Value::Array(av), Value::Array(bv)) = (va, vb) {
4927+
let mut dot = 0.0f64;
4928+
let ai = av.items.borrow();
4929+
let bi = bv.items.borrow();
4930+
for (x, y) in ai.iter().zip(bi.iter()) {
4931+
if let (Value::HFloat(xf), Value::HFloat(yf)) = (x, y) {
4932+
dot += xf * yf;
4933+
}
4934+
}
4935+
Ok(Value::HFloat(dot.clamp(-1.0, 1.0)))
4936+
} else {
4937+
Ok(Value::HFloat(0.0))
4938+
}
4939+
}
48884940
// Introspection and utility.
48894941
"type_of" => {
48904942
if args.is_empty() {
@@ -14688,6 +14740,8 @@ pub(crate) const HEAL_BUILTIN_NAMES: &[&str] = &[
1468814740
// I/O
1468914741
"read_file", "write_file", "file_exists", "file_ls", "print",
1469014742
"println", "print_raw",
14743+
// Time / sleep / similarity / eval
14744+
"sleep", "str_similarity", "omc_eval_file",
1469114745
// Time / random / conversion / introspection
1469214746
"now_ms", "random_int", "random_float", "random_seed",
1469314747
"to_int", "int", "to_float", "float",

0 commit comments

Comments
 (0)