Skip to content

Commit 24b7b6c

Browse files
Python integration docs: 13 py_* builtins + python category
Closes the discoverability gap I found while answering "what do we have on Python integration." The FFI layer was solid (701-line python_embed.rs, default-on, 6 wrapper libs) but NONE of the 13 py_* builtins had docs entries. So: omc_help("py_import") → NOT IN DOCS omc_list_builtins("python") → empty omc_find_by_signature("handle") → no hits omc_search_builtins("python") → empty onboarding_token.json → no mention of Python After this commit, all five discovery paths surface every py_* builtin. Verified end-to-end: $ omc_help("py_import") → found, signature returned $ omc_categories() includes "python" → true $ omc_list_builtins("python") → 13 entries $ omc_find_by_signature("handle", 5) → 5 py_* matches $ bootstrap_pack now mentions py_* → true Added BuiltinDoc entries with full signature + description + example for: py_import, py_call, py_call_kw, py_call_fn, py_call_fn_kw, py_call_raw, py_get, py_eval, py_exec, py_repr, py_clear_registry, py_fetch_text, py_callback py_callback marked unique_to_omc=true (REVERSE FFI: Python calls OMC; no other lang-bridge exposes this). Onboarding token regenerated: 78,212 bytes (up from 77,637 — +575 for the new docs). bootstrap_pack 42,242 bytes (+536). Library manifest unchanged at 193 fns (we didn't add new libs). The 6 OMC wrapper libraries (np, pd, sklearn, torch, requests, sqlite) already exist under examples/lib/ — they're now reachable via the standard discovery path: from "examples/lib/np.omc" import array, mean, dot, ... A fresh LLM dropping the onboarding token into context now knows that ANY Python package is one `py_import` call away. The integration story matches the OMC story: discoverable through the same introspection layer as everything else. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 952b298 commit 24b7b6c

2 files changed

Lines changed: 97 additions & 1 deletion

File tree

docs/onboarding_token.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

omnimcode-core/src/docs.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,6 +1808,102 @@ pub const BUILTINS: &[BuiltinDoc] = &[
18081808
BuiltinDoc { name: "lerp", category: "math", signature: "(a, b, t) -> float", description: "Linear interpolation: a + t*(b-a).", example: "lerp(0, 10, 0.5) // 5", unique_to_omc: false },
18091809
BuiltinDoc { name: "smooth_step", category: "math", signature: "(edge0, edge1, x) -> float", description: "Smoothstep 3t²-2t³ interpolation.", example: "smooth_step(0, 1, 0.5)", unique_to_omc: false },
18101810
BuiltinDoc { name: "wrap_pi", category: "math", signature: "(angle: float) -> float", description: "Wrap angle into [-π, π].", example: "wrap_pi(7.0) // ~0.717", unique_to_omc: false },
1811+
// ---- python: embedded CPython FFI (the "any-package adapter") ----
1812+
// OMC ships with embedded CPython via PyO3. py_import any Python
1813+
// module, py_call its methods, py_callback to let Python call OMC.
1814+
// This is how numpy, pandas, sklearn, torch, requests, sqlite, and
1815+
// anything else with a pip release become available to OMC code.
1816+
BuiltinDoc {
1817+
name: "py_import", category: "python",
1818+
signature: "(module_name: string) -> handle",
1819+
description: "Import a Python module via embedded CPython. Returns an opaque handle (int) that py_call / py_get / py_call_kw operate on. Any installed pip package works. Set OMC_NO_PYTHON=1 to disable embedded Python at startup.",
1820+
example: "h np = py_import(\"numpy\"); h pd = py_import(\"pandas\");",
1821+
unique_to_omc: false,
1822+
},
1823+
BuiltinDoc {
1824+
name: "py_call", category: "python",
1825+
signature: "(handle, method_name: string, args?: array) -> value",
1826+
description: "Call a method on a Python object. Args are auto-converted OMC→Python; the return value is auto-converted Python→OMC (int/float/str/list/dict pass through; complex objects are wrapped in a new handle). Use py_call_raw if you need to keep the result as a Python handle for chaining.",
1827+
example: "h arr = py_call(np, \"array\", [[1, 2, 3]]); h n = py_call(arr, \"sum\", []);",
1828+
unique_to_omc: false,
1829+
},
1830+
BuiltinDoc {
1831+
name: "py_call_kw", category: "python",
1832+
signature: "(handle, method_name: string, args: array, kwargs: dict) -> value",
1833+
description: "Like py_call but with a kwargs dict for Python APIs that take named arguments (sklearn, matplotlib, etc.). Pass null for empty kwargs.",
1834+
example: "h split = py_call_kw(sk_ms, \"train_test_split\", [X, y], dict_from([[\"test_size\", 0.3]]));",
1835+
unique_to_omc: false,
1836+
},
1837+
BuiltinDoc {
1838+
name: "py_call_fn", category: "python",
1839+
signature: "(callable_handle, args?: array) -> value",
1840+
description: "Call a Python callable (function, lambda, or any __call__-able). Same conversion semantics as py_call. Use this for top-level functions (e.g. py_get a module attribute that's a function, then py_call_fn it).",
1841+
example: "h sqrt = py_get(math, \"sqrt\"); h r = py_call_fn(sqrt, [16]); // 4.0",
1842+
unique_to_omc: false,
1843+
},
1844+
BuiltinDoc {
1845+
name: "py_call_fn_kw", category: "python",
1846+
signature: "(callable_handle, args: array, kwargs: dict) -> value",
1847+
description: "py_call_fn with a kwargs dict. Pass null for empty kwargs.",
1848+
example: "h cfg = py_call_fn_kw(open_fn, [\"file.txt\"], dict_from([[\"mode\", \"r\"]]));",
1849+
unique_to_omc: false,
1850+
},
1851+
BuiltinDoc {
1852+
name: "py_call_raw", category: "python",
1853+
signature: "(handle, method_name: string, args?: array) -> handle",
1854+
description: "Like py_call but ALWAYS returns a Python handle (no auto-conversion). Use when the result is a Python object you want to keep operating on (pandas Series that would otherwise collapse to an OMC array, etc.).",
1855+
example: "h ser = py_call_raw(df, \"groupby\", [\"col\"]); // stays a pandas GroupBy",
1856+
unique_to_omc: false,
1857+
},
1858+
BuiltinDoc {
1859+
name: "py_get", category: "python",
1860+
signature: "(handle, attr_name: string) -> value",
1861+
description: "Attribute access on a Python object. Like Python's `obj.attr`. Returns auto-converted Python→OMC value (handle for complex objects).",
1862+
example: "h shape = py_get(arr, \"shape\"); h pi = py_get(py_import(\"math\"), \"pi\");",
1863+
unique_to_omc: false,
1864+
},
1865+
BuiltinDoc {
1866+
name: "py_eval", category: "python",
1867+
signature: "(code: string) -> value",
1868+
description: "Evaluate a Python EXPRESSION string. Returns the auto-converted result. For statements (assignments, imports, loops) use py_exec.",
1869+
example: "h n = py_eval(\"2 ** 10\"); // 1024",
1870+
unique_to_omc: false,
1871+
},
1872+
BuiltinDoc {
1873+
name: "py_exec", category: "python",
1874+
signature: "(code: string) -> null",
1875+
description: "Execute a Python STATEMENT string (assignments, loops, imports, function defs). Returns null. Side effects persist in the embedded interpreter's global namespace across calls.",
1876+
example: "py_exec(\"import math; x = math.pi * 2\"); h x = py_eval(\"x\");",
1877+
unique_to_omc: false,
1878+
},
1879+
BuiltinDoc {
1880+
name: "py_repr", category: "python",
1881+
signature: "(handle) -> string",
1882+
description: "Python repr() of a handle. Useful for inspection / debugging.",
1883+
example: "print(py_repr(df)); // <pandas.DataFrame ...>",
1884+
unique_to_omc: false,
1885+
},
1886+
BuiltinDoc {
1887+
name: "py_clear_registry", category: "python",
1888+
signature: "() -> null",
1889+
description: "Drop all stored Python handles. Use to free memory after a heavy session. Existing handles become invalid; subsequent py_call on them errors.",
1890+
example: "py_clear_registry(); // after a big batch is done",
1891+
unique_to_omc: false,
1892+
},
1893+
BuiltinDoc {
1894+
name: "py_fetch_text", category: "python",
1895+
signature: "(url: string) -> string",
1896+
description: "HTTP GET via embedded Python `requests`. Returns body string on 2xx. The convenience used internally by `omc --install`; for richer HTTP use `examples/lib/requests.omc` wrappers.",
1897+
example: "h body = py_fetch_text(\"https://example.com/data.json\");",
1898+
unique_to_omc: false,
1899+
},
1900+
BuiltinDoc {
1901+
name: "py_callback", category: "python",
1902+
signature: "(omc_fn_name: string) -> handle",
1903+
description: "REVERSE FFI: returns a Python callable that, when invoked from Python with positional args, dispatches to the named OMC fn with auto-converted args and returns the converted result. Enables df.apply(omc_fn) patterns. Lifecycle: callback is valid only while the OMC interpreter is on the stack.",
1904+
example: "h add_one = py_callback(\"add_one\"); py_call(df, \"apply\", [add_one]);",
1905+
unique_to_omc: true,
1906+
},
18111907
];
18121908

18131909
/// Look up a builtin by name. Returns None when there's no docs entry

0 commit comments

Comments
 (0)