Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 38s
The seam for hooking flow to art-dag and human-in-the-loop later. (request kind payload) suspends with a typed (flow-request kind payload) envelope and returns the host's resume value; await-human/await-render sugar. (flow-host-requests) is the host work queue: (id kind payload) for every suspended flow awaiting a host effect; request?/request-kind/request-payload parse a tag. Tests include the art-dag-shaped driver loop (render -> human-review -> publish). Host owns IO+persistence; flow only requests (replay-safe). 162/162 across 11 suites. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
36 lines
2.5 KiB
Plaintext
36 lines
2.5 KiB
Plaintext
;; lib/flow/host.sx — the host integration ABI (Phase 8).
|
|
;;
|
|
;; `suspend` is flow's seam to the outside world, but a bare (suspend tag) is just a
|
|
;; signal — every author would invent their own tag shape. This layer defines a
|
|
;; stable request/response contract so a host (e.g. an art-dag driver, or a human
|
|
;; review UI) can hook in WITHOUT reverse-engineering ad-hoc tags.
|
|
;;
|
|
;; A flow asks the host to do something and waits for the answer:
|
|
;; (request kind payload) — suspend with a typed envelope (flow-request kind
|
|
;; payload); evaluates to the host's resume value.
|
|
;; (await-human prompt) — request kind=human (a decision point)
|
|
;; (await-render recipe) — request kind=render (e.g. an art-dag job)
|
|
;; (await-effect kind p) — request of an arbitrary kind
|
|
;;
|
|
;; The host drives flows by polling its work queue and resuming:
|
|
;; (flow-host-requests) — ((id kind payload) ...) for every SUSPENDED flow whose
|
|
;; waiting tag is a host request. The host dispatches by kind (render -> submit a
|
|
;; Celery job; human -> show UI), then calls (flow/resume id answer).
|
|
;; (request? tag) / (request-kind tag) / (request-payload tag) — parse one tag.
|
|
;;
|
|
;; Contract: the host owns IO and persistence. flow stays deterministic — a flow
|
|
;; never performs IO itself, it only `request`s; the host performs the effect and
|
|
;; feeds the result back via resume (which the replay log records, so the effect is
|
|
;; not re-run on recovery). Persist with flow-store-export after each transition and
|
|
;; flow-store-import! on boot.
|
|
|
|
(define
|
|
flow-host-src
|
|
"(define (request kind payload) (suspend (list (quote flow-request) kind payload)))\n (define (request? tag) (and (pair? tag) (eq? (car tag) (quote flow-request))))\n (define (request-kind tag) (car (cdr tag)))\n (define (request-payload tag) (car (cdr (cdr tag))))\n (define (await-human prompt) (request (quote human) prompt))\n (define (await-render recipe) (request (quote render) recipe))\n (define (await-effect kind payload) (request kind payload))\n (define (flow-host-req-step pend)\n (if (null? pend)\n (list)\n (let ((id (car (car pend))) (tag (car (cdr (car pend)))))\n (if (request? tag)\n (cons (list id (request-kind tag) (request-payload tag))\n (flow-host-req-step (cdr pend)))\n (flow-host-req-step (cdr pend))))))\n (define (flow-host-requests) (flow-host-req-step (flow/pending)))")
|
|
|
|
(define
|
|
flow-load-host!
|
|
(fn
|
|
(env)
|
|
(begin (scheme-eval-program (scheme-parse-all flow-host-src) env) env)))
|