|
| 1 | +# self_evolve.omc |
| 2 | +# OMC code that reads its own source, generates N improved variants, |
| 3 | +# judges them with llm_judge, and writes the winner back. |
| 4 | +# The best variant scores higher on correctness, clarity, and efficiency. |
| 5 | +# This is the core of OMC recursive self-improvement. |
| 6 | + |
| 7 | +import "examples/lib/llm.omc" |
| 8 | + |
| 9 | +h MODEL = "claude-opus-4-5" |
| 10 | +h N_VARIANTS = 3 |
| 11 | +h TARGET_FILE = "examples/demos/self_evolve.omc" |
| 12 | + |
| 13 | +# ── Helpers ─────────────────────────────────────────────────────────────────── |
| 14 | + |
| 15 | +fn strip_fences(text) { |
| 16 | + if str_contains(text, "```omc") { |
| 17 | + h a = str_split(text, "```omc") |
| 18 | + h b = str_split(a[1], "```") |
| 19 | + return str_trim(b[0]) |
| 20 | + } |
| 21 | + if str_contains(text, "```") { |
| 22 | + h a = str_split(text, "```") |
| 23 | + if arr_len(a) >= 3 { return str_trim(a[1]) } |
| 24 | + } |
| 25 | + return str_trim(text) |
| 26 | +} |
| 27 | + |
| 28 | +fn measure_quality(code) { |
| 29 | + h lines = str_split(code, "\n") |
| 30 | + h n = arr_len(lines) |
| 31 | + h fn_count = 0 |
| 32 | + h comment_count = 0 |
| 33 | + h i = 0 |
| 34 | + while i < n { |
| 35 | + h line = str_trim(lines[i]) |
| 36 | + if str_starts_with(line, "fn ") { fn_count = fn_count + 1 } |
| 37 | + if str_starts_with(line, "#") { comment_count = comment_count + 1 } |
| 38 | + i = i + 1 |
| 39 | + } |
| 40 | + return {lines: n, functions: fn_count, comments: comment_count} |
| 41 | +} |
| 42 | + |
| 43 | +# ── Generate N variant improvements in parallel ─────────────────────────────── |
| 44 | + |
| 45 | +fn generate_variants(source_code, n) { |
| 46 | + h styles = [ |
| 47 | + "Improve clarity and documentation without changing functionality.", |
| 48 | + "Optimize for performance: reduce redundant operations, tighten loops.", |
| 49 | + "Improve error handling and edge cases throughout.", |
| 50 | + "Refactor for modularity: extract repeated patterns into helper functions.", |
| 51 | + "Add type-safety: validate all function inputs before use." |
| 52 | + ] |
| 53 | + h sys = str_concat( |
| 54 | + "You are an expert OMC programmer. OMC syntax:\n", |
| 55 | + " h varname = value (declare variable)\n", |
| 56 | + " fn name(args) { ... return val } (define function)\n", |
| 57 | + " while cond { ... } (loop)\n", |
| 58 | + " arr_push(arr, val), arr_len(arr), str_concat(...)\n", |
| 59 | + " llm_call(prompt, model, system), batch_llm_call(prompts, model)\n", |
| 60 | + " llm_judge(responses, criteria), substrate_embed(text, dims)\n", |
| 61 | + "Return ONLY valid OMC code. No markdown, no explanation." |
| 62 | + ) |
| 63 | + h prompts = [] |
| 64 | + h i = 0 |
| 65 | + while i < n { |
| 66 | + h style = styles[i % arr_len(styles)] |
| 67 | + h p = str_concat( |
| 68 | + style, "\n\n", |
| 69 | + "Improve this OMC source file:\n\n", |
| 70 | + source_code |
| 71 | + ) |
| 72 | + arr_push(prompts, {prompt: p, system: sys}) |
| 73 | + i = i + 1 |
| 74 | + } |
| 75 | + print(str_concat("Generating ", to_str(n), " variants in parallel...")) |
| 76 | + h raw = batch_llm_call(prompts, MODEL) |
| 77 | + h variants = [] |
| 78 | + h ri = 0 |
| 79 | + while ri < arr_len(raw) { |
| 80 | + arr_push(variants, strip_fences(raw[ri])) |
| 81 | + ri = ri + 1 |
| 82 | + } |
| 83 | + return variants |
| 84 | +} |
| 85 | + |
| 86 | +# ── Judge variants and pick best ───────────────────────────────────────────── |
| 87 | + |
| 88 | +fn pick_best_variant(source, variants) { |
| 89 | + # Include original as baseline (index 0) |
| 90 | + h candidates = [source] |
| 91 | + h vi = 0 |
| 92 | + while vi < arr_len(variants) { |
| 93 | + arr_push(candidates, variants[vi]) |
| 94 | + vi = vi + 1 |
| 95 | + } |
| 96 | + |
| 97 | + h criteria = str_concat( |
| 98 | + "This is OMC source code for a self-improvement loop. ", |
| 99 | + "Score each version 0-10 on: (1) clarity and documentation, ", |
| 100 | + "(2) correct OMC syntax (h for vars, fn for functions, while for loops), ", |
| 101 | + "(3) completeness (all original functionality preserved), ", |
| 102 | + "(4) improvement quality over the original. ", |
| 103 | + "Penalize heavily for missing functions or broken syntax." |
| 104 | + ) |
| 105 | + |
| 106 | + print(str_concat("Judging ", to_str(arr_len(candidates)), " candidates (including original)...")) |
| 107 | + h scores = llm_judge(candidates, criteria, MODEL) |
| 108 | + |
| 109 | + # Find best non-original |
| 110 | + h best_idx = 0 |
| 111 | + h best_score = -1.0 |
| 112 | + h si = 0 |
| 113 | + while si < arr_len(scores) { |
| 114 | + h entry = scores[si] |
| 115 | + h idx = entry["idx"] |
| 116 | + h score = entry["score"] |
| 117 | + print(str_concat(" Candidate ", to_str(idx), " score: ", to_str(score))) |
| 118 | + if idx > 0 and score > best_score { |
| 119 | + best_score = score |
| 120 | + best_idx = idx |
| 121 | + } |
| 122 | + si = si + 1 |
| 123 | + } |
| 124 | + |
| 125 | + h original_score = 0.0 |
| 126 | + h oi = 0 |
| 127 | + while oi < arr_len(scores) { |
| 128 | + if scores[oi]["idx"] == 0 { original_score = scores[oi]["score"] } |
| 129 | + oi = oi + 1 |
| 130 | + } |
| 131 | + |
| 132 | + print(str_concat("Original score: ", to_str(original_score))) |
| 133 | + print(str_concat("Best variant score: ", to_str(best_score), " (idx=", to_str(best_idx), ")")) |
| 134 | + |
| 135 | + if best_score > original_score { |
| 136 | + return {improved: true, code: candidates[best_idx], score: best_score, delta: best_score - original_score} |
| 137 | + } |
| 138 | + return {improved: false, code: source, score: original_score, delta: 0.0} |
| 139 | +} |
| 140 | + |
| 141 | +# ── Main: read self, improve, optionally write back ─────────────────────────── |
| 142 | + |
| 143 | +print("=== OMC Recursive Self-Evolution ===") |
| 144 | +print(str_concat("Target: ", TARGET_FILE)) |
| 145 | +print(str_concat("Variants: ", to_str(N_VARIANTS))) |
| 146 | +print("") |
| 147 | + |
| 148 | +h source = read_file(TARGET_FILE) |
| 149 | +h initial = measure_quality(source) |
| 150 | +print(str_concat("Source: ", to_str(initial["lines"]), " lines, ", to_str(initial["functions"]), " functions")) |
| 151 | +print("") |
| 152 | + |
| 153 | +h variants = generate_variants(source, N_VARIANTS) |
| 154 | +print("") |
| 155 | + |
| 156 | +h result = pick_best_variant(source, variants) |
| 157 | +print("") |
| 158 | + |
| 159 | +if result["improved"] { |
| 160 | + h final = measure_quality(result["code"]) |
| 161 | + print(str_concat("Improvement delta: +", to_str(result["delta"]), " points")) |
| 162 | + print(str_concat("Improved: ", to_str(final["lines"]), " lines, ", to_str(final["functions"]), " functions")) |
| 163 | + print("") |
| 164 | + print("Writing improved version...") |
| 165 | + write_file(TARGET_FILE, result["code"]) |
| 166 | + print("Done. The file has improved itself.") |
| 167 | +} else { |
| 168 | + print("No variant beat the original — source unchanged.") |
| 169 | + print(str_concat("Original score: ", to_str(result["score"]))) |
| 170 | +} |
| 171 | + |
| 172 | +print("") |
| 173 | +print("=== Self-evolution cycle complete ===") |
0 commit comments