Two changes: parity with nanoodle-js 0.8.0 (#11), and a timed-out run no longer hangs your process (#12).
⚠️ Breaking: a named node now advertises its own name as the input key
If you renamed a node in the editor, that name is now the input key — it used to fall back to a generic label. This matches nanoodle-js 0.8.0, so the same graph finally takes the same input names in both executors.
Confirmed renames on published workflows:
| Workflow | Was | Now |
|---|---|---|
| pr-describe | System prompt / System prompt 2 / System prompt 3 |
Drafter / Auditor / Final PR body |
| jingle | System prompt / System prompt 2 |
Lyric writer / Style writer |
| visual-judge | System prompt |
Verdict |
| narrated-poem | System prompt |
Poet |
| video-teaser | System prompt |
Shot writer |
Run nanoodle-py inspect <graph> to see what any graph advertises now. Old keys still resolve where a label fallback covers them, but do not rely on that — use what inspect prints.
Parity with nanoodle-js 0.8.0 (#11)
- Optional inputs. A node the author marked optional can be left unset, and consumers drop the empty value instead of failing.
- Prompt caps. An over-cap prompt is trimmed to fit and the trim is reported — in the progress stream, in
result.prompt_trims, and in--json. Your prompt text is never rewritten or paraphrased, only cut. Lengths are measured in UTF-16 code units so a prompt with emoji or CJK trims identically in Python and JavaScript. --jsonon a failed run. A failed run now prints the same JSON object as a successful one — per-node status and error, the outputs that did complete, and the cost already spent — then exits non-zero. Pre-run validation failures print it too.
A timed-out run releases the process (#12)
run(timeout=…) used to return promptly and then leave the process alive, in the worst case for the full 600-second video timeout. It now exits in about 0.6 seconds.
- Poll loops and their sleeps honour the run deadline, so an abandoned node stops instead of running to its own timeout.
- A local ffmpeg or ffprobe child is killed at exit rather than orphaned.
- Settled x402 deposits stay traceable.
result.paymentsand--jsoncarry every payment id, amount and explorer URL, with a status ofsending,sentorfailed— so a deposit that left your wallet is never silently lost, and a wallet callback that failed never claims money moved. A settled deposit still gets its request sent. - A paid retry that answers with a non-2xx status keeps the deposit unredeemed and names the payment id in the error you read.
Media fetching is deliberately not governed by the run deadline: a MediaRef you hold after run() returns still fetches its bytes, including partial results from a run that timed out.
Full diff: v0.4.0...v0.5.0