with one click
orc-workflow
Build an ORC behavior tree workflow using the DSL
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Build an ORC behavior tree workflow using the DSL
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Create scheduled background jobs that run on cron schedules
Set up LLM-as-judge evaluation for ORC workflows
Implement event-driven side effects that react to domain events
Implement command handlers that validate state and emit events using the Grain framework
Create a complete Grain domain service with schemas, read models, commands, queries, and tests
Implement query handlers that read from event-sourced read models
| name | orc-workflow |
| description | Build an ORC behavior tree workflow using the DSL |
Build a behavior tree workflow using the ORC DSL. Read docs/DSL-REFERENCE.md for the full reference.
(require '[ai.obney.orc.orc-service.interface :as orc])
Every workflow has three parts:
(orc/workflow "workflow-name"
;; 1. Blackboard (input/output schema)
(orc/blackboard {:input-key :string
:output-key :string})
;; 2. Root node (tree structure)
(orc/sequence "main"
(orc/llm "step-1" ...)
(orc/code "step-2" ...)))
(orc/llm "summarize"
:instruction "Summarize the input text in 2 sentences."
:reads [:input-text]
:writes [:summary]
:model "google/gemini-2.0-flash-001") ;; optional, uses default if omitted
;; :fn must be a fully-qualified function name (resolved at runtime)
;; The function receives {:keys [inputs]} and returns {:key value}
(orc/code "transform"
:fn "my.ns/transform-fn"
:reads [:raw-data]
:writes [:processed-data])
(orc/sequence "pipeline"
(orc/llm "extract" ...)
(orc/code "validate" ...)
(orc/llm "respond" ...))
(orc/fallback "with-retry"
(orc/llm "try-gpt4" :model "openai/gpt-4o" ...)
(orc/llm "try-gemini" :model "google/gemini-2.0-flash-001" ...))
(orc/parallel "gather"
{:success-policy :all} ;; :all, :any, or :majority
(orc/llm "analysis-a" ...)
(orc/llm "analysis-b" ...))
(orc/map-each "process-items"
:source-key :items ;; blackboard key with the collection
:item-key :current-item ;; blackboard key for each item
:output-key :results ;; blackboard key for collected results
(orc/llm "process-one" ...))
(orc/condition "check-length"
:check "(fn [bb] (> (count (:text bb)) 100))"
:reads [:text])
(orc/llm-condition "is-relevant?"
:instruction "Is this text relevant to the user's question? Answer yes or no."
:reads [:text :question])
;; Build (stores in event store, returns sheet-id)
(def sheet-id (orc/build-workflow! ctx my-workflow))
;; Execute (blocking, returns result)
(orc/execute ctx sheet-id {:input-key "value"})
;; => {:status :success, :outputs {:output-key "result"}, :duration-ms 1234}
;; Execute with options
(orc/execute ctx sheet-id inputs :timeout-ms 60000)
(orc/execute ctx sheet-id inputs :use-version 2)
:reads and :writes must be declared in the blackboard:fn must be a namespace-qualified symbol string, not inline codebuild-workflow! is idempotent — same workflow name produces the same sheet-id, and unchanged definitions are a true no-op (zero events) via content hashingorc/publish-version for production snapshots(orc/workflow "with-judges"
(orc/blackboard {:question :string :answer :string})
(orc/judges
{:grounding {:type :grounding :weight 0.5}
:completeness {:type :completeness :weight 0.5}})
(orc/llm "answer"
:instruction "Answer the question."
:reads [:question]
:writes [:answer]
:judges [:grounding :completeness]))
docs/DSL-REFERENCE.md — Full DSL reference with examplesdocs/ORC-SERVICE-GUIDE.md — Execution engine internals