rote-cli 0.4.0__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. {rote_cli-0.4.0 → rote_cli-0.5.0}/PKG-INFO +25 -9
  2. {rote_cli-0.4.0 → rote_cli-0.5.0}/README.md +24 -8
  3. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/__init__.py +1 -1
  4. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/adapters/__init__.py +16 -2
  5. rote_cli-0.5.0/src/rote/adapters/_py_common.py +642 -0
  6. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/adapters/dbos.py +65 -578
  7. rote_cli-0.5.0/src/rote/adapters/inngest.py +996 -0
  8. rote_cli-0.5.0/src/rote/adapters/python.py +671 -0
  9. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/cli.py +99 -15
  10. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/ir.py +14 -0
  11. rote_cli-0.5.0/src/rote/serve/backends.py +343 -0
  12. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/serve/registry.py +49 -2
  13. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/serve/server.py +65 -0
  14. rote_cli-0.4.0/src/rote/serve/backends.py +0 -187
  15. {rote_cli-0.4.0 → rote_cli-0.5.0}/.gitignore +0 -0
  16. {rote_cli-0.4.0 → rote_cli-0.5.0}/LICENSE +0 -0
  17. {rote_cli-0.4.0 → rote_cli-0.5.0}/pyproject.toml +0 -0
  18. {rote_cli-0.4.0 → rote_cli-0.5.0}/skills/rote-graduate/SKILL.md +0 -0
  19. {rote_cli-0.4.0 → rote_cli-0.5.0}/skills/rote-graduate/references/crystallization-heuristics.md +0 -0
  20. {rote_cli-0.4.0 → rote_cli-0.5.0}/skills/rote-graduate/references/ir-schema.md +0 -0
  21. {rote_cli-0.4.0 → rote_cli-0.5.0}/skills/rote-graduate/references/llm-judge-extraction.md +0 -0
  22. {rote_cli-0.4.0 → rote_cli-0.5.0}/skills/rote-graduate/references/node-kinds.md +0 -0
  23. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/adapters/_common.py +0 -0
  24. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/adapters/_ts_common.py +0 -0
  25. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/adapters/cloudflare.py +0 -0
  26. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/adapters/dbos_ts.py +0 -0
  27. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/adapters/temporal.py +0 -0
  28. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/graduator/__init__.py +0 -0
  29. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/graduator/drivers/__init__.py +0 -0
  30. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/graduator/drivers/anthropic_api.py +0 -0
  31. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/graduator/drivers/claude.py +0 -0
  32. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/graduator/drivers/codex.py +0 -0
  33. {rote_cli-0.4.0 → rote_cli-0.5.0}/src/rote/serve/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rote-cli
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Graduate fuzzy AI skills into deterministic, reliable workflows
5
5
  Project-URL: Homepage, https://github.com/trevhud/rote
6
6
  Project-URL: Repository, https://github.com/trevhud/rote
@@ -167,6 +167,16 @@ the target runtime's native code shape:
167
167
  Zero-orchestrator like the Python DBOS target — `node dist/main.js`
168
168
  *is* the runtime — but note the TS SDK is Postgres-only (no SQLite
169
169
  mode; `npx dbos postgres start` covers local dev).
170
+ - The **Inngest** adapter (`--runtime inngest`) emits a TypeScript
171
+ Inngest app for teams whose graduated skill should live inside the
172
+ Node/Next.js service they already deploy: `src/inngest/pipeline.ts`
173
+ is one durable `inngest.createFunction` running the DAG waves
174
+ (`step.run` per node, `Promise.all` fan-out, `step.waitForEvent`
175
+ parking each HITL gate until its namespaced resume event), plus a
176
+ framework-neutral `inngest/node` serve entrypoint. The emitted
177
+ README shows the drop-in Next.js mount (`inngest/next`). Note:
178
+ Inngest v4 retries are function-level only — the emitter sets the
179
+ max across per-node policies and documents the deltas as comments.
170
180
 
171
181
  None of the emitted code references an MCP runtime, in either
172
182
  language — the agent's crystallization step replaces tool calls with
@@ -430,14 +440,16 @@ the toolchain-dependent integration tests.
430
440
  | Cloudflare Workflows adapter | working (validated with `tsc --noEmit` over the real emitted output) |
431
441
  | DBOS adapter | working (validated against a real DBOS runtime over SQLite in the e2e test) |
432
442
  | DBOS TypeScript adapter (`dbos-ts`) | working (validated with `tsc --noEmit` over the real emitted output and a live run on the DBOS TS runtime against Docker Postgres) |
443
+ | Raw Python adapter (`python`) | working (emitted script executed as a subprocess in the e2e test: wave order, payload threading, and a live retry loop; refuses `hitl_gate` pipelines at emit time) |
433
444
  | Graduator orchestrator | working |
434
445
  | `rote graduate` / `rote emit` CLI commands | working |
435
446
  | `claude` driver | working |
436
447
  | `api` (Anthropic SDK) driver | working |
437
448
  | `codex` driver | stub (`is_available` works; `run` not implemented) |
438
- | Inngest / Restate adapters | planned |
449
+ | Inngest adapter (`inngest`) | working (validated with `tsc --noEmit` over the real emitted output and a live run through both HITL gates against the Inngest dev server) |
450
+ | Restate adapter | planned |
439
451
  | Real implementations of the extracted modules | the agent produces stubs that raise `NotImplementedError`; humans fill them in with real API client code |
440
- | Workflow data flow between activities | working — nodes declare `inputs:` bindings and all four adapters (Temporal, Cloudflare, DBOS, DBOS-TS) thread real payloads through the DAG, validated in the runtime e2e tests |
452
+ | Workflow data flow between activities | working — nodes declare `inputs:` bindings and all five adapters (Temporal, Cloudflare, DBOS, DBOS-TS, Inngest) thread real payloads through the DAG, validated in the runtime e2e tests |
441
453
  | Distribution via PyPI | published as [`rote-cli`](https://pypi.org/project/rote-cli/) (`pip install rote-cli`); tag-driven Trusted Publishing releases — see [docs/releasing.md](docs/releasing.md) |
442
454
 
443
455
  The project explicitly **does not** depend on `claude-agent-sdk`.
@@ -547,11 +559,15 @@ In rough priority order:
547
559
  graduator the new field, but no real graduator run has produced
548
560
  one yet. Re-running `rote graduate examples/bdr-outreach/skill`
549
561
  should produce the structured form natively.
550
- 3. **A third runtime adapter.** Probably Inngest, since its
551
- programming model is meaningfully different from both Temporal and
552
- Cloudflare. Each new adapter is also a stress test on whether the
553
- IR is genuinely runtime-agnostic vs. accidentally shaped like one
554
- of the existing targets.
562
+ 3. **A third runtime adapter.** *(Done — the Inngest adapter shipped,
563
+ alongside DBOS Python/TS.)* Its programming model is meaningfully
564
+ different from both Temporal and Cloudflare retries are
565
+ function-level, the platform drives execution from outside the
566
+ process — and the IR survived without changes (the per-node retry
567
+ gap is documented at emission, not papered over in the IR). Each
568
+ new adapter remains a stress test on whether the IR is genuinely
569
+ runtime-agnostic vs. accidentally shaped like one of the existing
570
+ targets.
555
571
  4. **Pre-filter as `pure_function` node.** Today the rubric lifts
556
572
  hard thresholds into a Python `forward()` method, which works for
557
573
  Temporal but not for Cloudflare. Modeling the pre-filter as a
@@ -585,7 +601,7 @@ The most useful contributions right now are:
585
601
  needs to be tested against more.
586
602
  - **Add a runtime adapter.** The Temporal adapter in
587
603
  `src/rote/adapters/temporal.py` is ~450 lines and follows a clear
588
- pattern. Inngest, Restate, and Hatchet are all good targets.
604
+ pattern. Restate and Hatchet are both good targets.
589
605
  - **Add a graduator driver.** The Protocol in
590
606
  `src/rote/graduator/drivers/__init__.py` is simple. Aider, Gemini
591
607
  CLI, and Cursor Agent are reasonable additions.
@@ -121,6 +121,16 @@ the target runtime's native code shape:
121
121
  Zero-orchestrator like the Python DBOS target — `node dist/main.js`
122
122
  *is* the runtime — but note the TS SDK is Postgres-only (no SQLite
123
123
  mode; `npx dbos postgres start` covers local dev).
124
+ - The **Inngest** adapter (`--runtime inngest`) emits a TypeScript
125
+ Inngest app for teams whose graduated skill should live inside the
126
+ Node/Next.js service they already deploy: `src/inngest/pipeline.ts`
127
+ is one durable `inngest.createFunction` running the DAG waves
128
+ (`step.run` per node, `Promise.all` fan-out, `step.waitForEvent`
129
+ parking each HITL gate until its namespaced resume event), plus a
130
+ framework-neutral `inngest/node` serve entrypoint. The emitted
131
+ README shows the drop-in Next.js mount (`inngest/next`). Note:
132
+ Inngest v4 retries are function-level only — the emitter sets the
133
+ max across per-node policies and documents the deltas as comments.
124
134
 
125
135
  None of the emitted code references an MCP runtime, in either
126
136
  language — the agent's crystallization step replaces tool calls with
@@ -384,14 +394,16 @@ the toolchain-dependent integration tests.
384
394
  | Cloudflare Workflows adapter | working (validated with `tsc --noEmit` over the real emitted output) |
385
395
  | DBOS adapter | working (validated against a real DBOS runtime over SQLite in the e2e test) |
386
396
  | DBOS TypeScript adapter (`dbos-ts`) | working (validated with `tsc --noEmit` over the real emitted output and a live run on the DBOS TS runtime against Docker Postgres) |
397
+ | Raw Python adapter (`python`) | working (emitted script executed as a subprocess in the e2e test: wave order, payload threading, and a live retry loop; refuses `hitl_gate` pipelines at emit time) |
387
398
  | Graduator orchestrator | working |
388
399
  | `rote graduate` / `rote emit` CLI commands | working |
389
400
  | `claude` driver | working |
390
401
  | `api` (Anthropic SDK) driver | working |
391
402
  | `codex` driver | stub (`is_available` works; `run` not implemented) |
392
- | Inngest / Restate adapters | planned |
403
+ | Inngest adapter (`inngest`) | working (validated with `tsc --noEmit` over the real emitted output and a live run through both HITL gates against the Inngest dev server) |
404
+ | Restate adapter | planned |
393
405
  | Real implementations of the extracted modules | the agent produces stubs that raise `NotImplementedError`; humans fill them in with real API client code |
394
- | Workflow data flow between activities | working — nodes declare `inputs:` bindings and all four adapters (Temporal, Cloudflare, DBOS, DBOS-TS) thread real payloads through the DAG, validated in the runtime e2e tests |
406
+ | Workflow data flow between activities | working — nodes declare `inputs:` bindings and all five adapters (Temporal, Cloudflare, DBOS, DBOS-TS, Inngest) thread real payloads through the DAG, validated in the runtime e2e tests |
395
407
  | Distribution via PyPI | published as [`rote-cli`](https://pypi.org/project/rote-cli/) (`pip install rote-cli`); tag-driven Trusted Publishing releases — see [docs/releasing.md](docs/releasing.md) |
396
408
 
397
409
  The project explicitly **does not** depend on `claude-agent-sdk`.
@@ -501,11 +513,15 @@ In rough priority order:
501
513
  graduator the new field, but no real graduator run has produced
502
514
  one yet. Re-running `rote graduate examples/bdr-outreach/skill`
503
515
  should produce the structured form natively.
504
- 3. **A third runtime adapter.** Probably Inngest, since its
505
- programming model is meaningfully different from both Temporal and
506
- Cloudflare. Each new adapter is also a stress test on whether the
507
- IR is genuinely runtime-agnostic vs. accidentally shaped like one
508
- of the existing targets.
516
+ 3. **A third runtime adapter.** *(Done — the Inngest adapter shipped,
517
+ alongside DBOS Python/TS.)* Its programming model is meaningfully
518
+ different from both Temporal and Cloudflare retries are
519
+ function-level, the platform drives execution from outside the
520
+ process — and the IR survived without changes (the per-node retry
521
+ gap is documented at emission, not papered over in the IR). Each
522
+ new adapter remains a stress test on whether the IR is genuinely
523
+ runtime-agnostic vs. accidentally shaped like one of the existing
524
+ targets.
509
525
  4. **Pre-filter as `pure_function` node.** Today the rubric lifts
510
526
  hard thresholds into a Python `forward()` method, which works for
511
527
  Temporal but not for Cloudflare. Modeling the pre-filter as a
@@ -539,7 +555,7 @@ The most useful contributions right now are:
539
555
  needs to be tested against more.
540
556
  - **Add a runtime adapter.** The Temporal adapter in
541
557
  `src/rote/adapters/temporal.py` is ~450 lines and follows a clear
542
- pattern. Inngest, Restate, and Hatchet are all good targets.
558
+ pattern. Restate and Hatchet are both good targets.
543
559
  - **Add a graduator driver.** The Protocol in
544
560
  `src/rote/graduator/drivers/__init__.py` is simple. Aider, Gemini
545
561
  CLI, and Cursor Agent are reasonable additions.
@@ -1,3 +1,3 @@
1
1
  """rote — graduate fuzzy AI skills into deterministic workflows."""
2
2
 
3
- __version__ = "0.4.0"
3
+ __version__ = "0.5.0"
@@ -6,8 +6,8 @@ adapters are template substitution.
6
6
 
7
7
  The "two adapters minimum" rule applies: until at least two adapters
8
8
  work end-to-end, assume the IR shape is secretly leaking the first
9
- runtime's mental model. Inngest is the planned second target after
10
- Temporal.
9
+ runtime's mental model. (Satisfied five adapters share the IR today:
10
+ Temporal, Cloudflare, DBOS Python, DBOS TypeScript, and Inngest.)
11
11
 
12
12
  Adapters are registered in :data:`ADAPTERS` and dispatched by name from
13
13
  the CLI (``rote emit --runtime <name>``).
@@ -54,6 +54,18 @@ def _dbos_ts_adapter_factory() -> Adapter:
54
54
  return DbosTsAdapter()
55
55
 
56
56
 
57
+ def _inngest_adapter_factory() -> Adapter:
58
+ from rote.adapters.inngest import InngestAdapter
59
+
60
+ return InngestAdapter()
61
+
62
+
63
+ def _python_adapter_factory() -> Adapter:
64
+ from rote.adapters.python import PythonAdapter
65
+
66
+ return PythonAdapter()
67
+
68
+
57
69
  #: Name → factory. Keep the values as zero-arg callables so adapters can
58
70
  #: lazy-import their heavy dependencies.
59
71
  ADAPTERS: dict[str, Callable[[], Adapter]] = {
@@ -61,6 +73,8 @@ ADAPTERS: dict[str, Callable[[], Adapter]] = {
61
73
  "cloudflare": _cloudflare_adapter_factory,
62
74
  "dbos": _dbos_adapter_factory,
63
75
  "dbos-ts": _dbos_ts_adapter_factory,
76
+ "inngest": _inngest_adapter_factory,
77
+ "python": _python_adapter_factory,
64
78
  }
65
79
 
66
80