Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 34s
Completes the host ABI from work-queue to driver loop: the host supplies only a (kind payload) -> answer dispatch fn; flow-drive-host services one tick of pending requests, flow-run-host ticks until quiescent (bounded). Tested via the art-dag render -> human-review -> publish pipeline driven entirely by flow-run-host. The art-dag integration is now: define dispatch, call flow-run-host. 166/166, 11 suites. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
43 lines
3.6 KiB
Plaintext
43 lines
3.6 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.
|
|
;;
|
|
;; Reference driver — the host only supplies `dispatch`, a (kind payload) -> answer:
|
|
;; (flow-drive-host dispatch) — one tick: service every CURRENTLY pending
|
|
;; request (snapshot), resuming each with (dispatch kind payload); returns the
|
|
;; count serviced. Resumes may create new requests — serviced on the next tick.
|
|
;; (flow-run-host dispatch maxticks) — tick until quiescent (no pending requests)
|
|
;; or maxticks reached; returns total requests serviced. Bounded for determinism.
|
|
;;
|
|
;; 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)))\n (define (flow-drive-host-step reqs dispatch)\n (if (null? reqs)\n 0\n (begin\n (flow/resume (car (car reqs)) (dispatch (car (cdr (car reqs))) (car (cdr (cdr (car reqs))))))\n (+ 1 (flow-drive-host-step (cdr reqs) dispatch)))))\n (define (flow-drive-host dispatch) (flow-drive-host-step (flow-host-requests) dispatch))\n (define (flow-run-host dispatch maxticks)\n (if (<= maxticks 0)\n 0\n (let ((n (flow-drive-host dispatch)))\n (if (= n 0) 0 (+ n (flow-run-host dispatch (- maxticks 1)))))))")
|
|
|
|
(define
|
|
flow-load-host!
|
|
(fn
|
|
(env)
|
|
(begin (scheme-eval-program (scheme-parse-all flow-host-src) env) env)))
|