Codync
무료 오픈소스 1:1 대안, Grok Bot과 Muse 대신
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗You write a module of ordinary, typed functions. fnloom reads the graph straight from them: a function's name is a node, and its parameter names are the edges. Ask for the outputs you want, and fnloom runs exactly the functions needed to produce them, in a fixed order, with your mistakes caught before anything runs.
prepare, then run
it as often as you like. A 1,000-node graph runs in about 0.2 ms.async def node in a sync build raises a clear error naming the culprit. Hamilton accepts several of these
silently.RecursionError at around 1,000.fnloom-core has no dependencies and no unsafe, and it doesn't care what a node
runs.# file: pricing.py
def total(price: float, quantity: int) -> float:
"""What the line costs before any discount."""
return price * quantity
def discounted(total: float, discount: float = 0.0) -> float:
"""The total after the discount, if one is given."""
return total * (1 - discount)
def label(discounted: float, currency: str = "EUR") -> str:
"""The price as shown to a customer."""
return f"{discounted:.2f} {currency}"
That module is this graph. price and quantity aren't the name of any function, so they're inputs. discount and
currency have defaults, so they're optional:
flowchart TD
price([price]) --> total
quantity([quantity]) --> total
total --> discounted
discount([discount?]) -.-> discounted
discounted --> label
currency([currency?]) -.-> label
Build a driver and ask for what you need:
import fnloom
import pricing
driver = fnloom.build(pricing)
driver.execute(["label"], inputs={"price": 2.5, "quantity": 4})
# -> {'label': '10.00 EUR'}
# Running the same request in a loop? Compile it once.
plan = driver.prepare(["label"], inputs={"price": 0.0, "quantity": 0})
plan.run(inputs={"price": 4.0, "quantity": 3})
# -> {'label': '12.00 EUR'}
Next, the guides cover which functions become nodes, overrides, prepared plans, type checks, lineage and every error message.
fnloom uses Hamilton's model, so a module of Hamilton functions is already a module of fnloom nodes. The difference is in what happens when you run it.
| Hamilton 1.90.0 | fnloom | |
|---|---|---|
| A chain of 1,000+ nodes | RecursionError | ✅ Runs at any depth |
| A dependency cycle | RecursionError when executed | ✅ ValueError naming the cycle, at build |
| A misspelled input or override | Silently ignored | ✅ ValueError naming it |
An async def node | The un-awaited coroutine is the value | ✅ ValueError at build(); build_async() awaits it |
| Execution order | Depends on how you list outputs | ✅ Always the same |
| Running a request again | Re-planned on every call | ✅ prepare once, run many times |
| Runtime dependencies | numpy, pandas and more | ✅ None |
Hamilton is fnloom's test oracle: the shared behaviour runs through both, and every deliberate difference is a row in the register. Most rows have a test that checks Hamilton and fnloom side by side. Moving over? Read Coming from Hamilton.
Milliseconds on an Apple M2 Pro, lower is better, from the full benchmarks:
| Graph | Build (Hamilton → fnloom) | Repeat run (Hamilton → fnloom) |
|---|---|---|
| 1,000 nodes, layered | 21.6 → 7.2 | 4.35 → 0.21 (21×) |
| 1,000-input fan-in | 3.02 → 1.47 | 2.73 → 0.31 (9×) |
| 10,000-node chain | 207.5 → 63.4 | RecursionError → 1.34 |
10,000 @parameterize rows | 5,285 → 128 | RecursionError → 1.35 |
Your node functions still run at Python speed. fnloom removes the overhead around them: planning, validation and dispatch.
Yes, if you compute many derived values from a few inputs (features, metrics, pricing, signals), want each step to be a small function you can test on its own, and run the same graph many times in one process.
Not yet, if you need dynamic execution, or an adapter that wraps how a node is called, such
as GracefulErrorAdapter. They're on the roadmap. fnloom is also not a scheduler. It doesn't retry,
distribute or schedule work, so pair it with an orchestrator if you need that.
fnloom isn't on PyPI yet. Build it from source with Python 3.14 or newer, uv and a stable Rust toolchain:
git clone https://github.com/kelsayed17/fnloom.git
cd fnloom
uv sync
uv run maturin develop --release
Pre-alpha. Done so far:
@parameterize and its sugar, @tag, @exclude, graph inspection, validate and type checksrebuild(), and one driver shared between threads@config.when*, @extract_fields, @extract_columns, and an async driver that caches toofnloom
command@check_output validators,
steps, @inject, @resolve and
node wrappersbind=, and a written
recipe for each Hamilton
feature left outThe design has the full plan. The name is provisional, pending a trademark check before the first release.
CONTRIBUTING.md covers the setup and the one check script. Please report security problems privately, as SECURITY.md describes.
Licensed under Apache-2.0. Not affiliated with or endorsed by the Apache Software Foundation or the Apache Hamilton (incubating) project.