Skip to content

Declarative pipeline definition + durable runner (#97) - #106

Merged
serge-ivo merged 1 commit into
mainfrom
feat/97-pipeline-runner
Aug 1, 2026
Merged

Declarative pipeline definition + durable runner (#97)#106
serge-ivo merged 1 commit into
mainfrom
feat/97-pipeline-runner

Conversation

@serge-ivo

Copy link
Copy Markdown
Contributor

Closes #97. Part of #94. Builds on #85 (ToolDef) + #86 (connectorClient).

A pipeline is JSON data: {name, params?, steps:[{tool, inputs?, bind?, forEach?}], sink?}. inputs take literals or refs — {$ref:'bind.dotted.path'} (prior step) / {$param:'name'} (run param); forEach fans a step over an array (concurrency deferred to #96). Definitions live per-instance in config.pipelines[name] (no migration).

PipelineRunWorkflow (WorkflowEntrypoint, mirrors job-apply.ts): linear walk, each step its own step.do for durability past the 30s DO limit; results journaled by bind. Connector tokens re-minted inside each step (never captured across steps) so resume/replay is safe. Every step dispatches via the single runRegistryTool path — auth/grant/consent enforced identically to direct tool calls. Optional sink upserts final output into an instance collection (clean seam for #96 dedupe/upsert).

Start paths: run_pipeline LLM tool (in BASE allowlist → 'sweep Sydney' works) + owner-scoped, audited POST /v1/instances/:id/pipelines/:name/run. Trigger(#92) seam: startPipelineRun(...trigger) present, wiring deferred.

Verify: tsc clean · 818 api tests pass (0 regressions) · biome clean.

🤖 Generated with Claude Code

A pipeline is JSON DATA — an ordered list of steps, each dispatching a
registry tool (#85/#86) through the SINGLE runRegistryTool path so connector
auth/grant/consent (#86/#90) are enforced identically to a direct tool call.
Outputs thread between steps by `bind`; inputs reference prior outputs + run
params via a $ref/$param convention. A source→transform→sink agent is now
configuration, not code.

- lib/pipeline.ts: schema { name, params?, steps:[{tool,inputs,bind?,forEach?}], sink? },
  validatePipeline, resolveInputs ($ref/$param + recursion + forEach item),
  executePipelineStep (pure, unit-testable), loadPipeline (from instance config).
- workflows/pipeline-run.ts: PipelineRunWorkflow (WorkflowEntrypoint) — walks steps,
  each in its own step.do for durability/resumability past the 30s DO limit
  (mirrors JobApplyWorkflow). Connector tokens re-minted inside each step, never
  captured across steps (resume-determinism caveat). Optional sink upserts the
  final output into an instance collection via the AgentDO records route.
- lib/pipeline-run-start.ts: the single kick path (audit + create), shared by the
  tool + the API route; the clean hook for cron/webhook triggers (#92, not built here).
- run_pipeline first-party ToolDef (registry) so an agent can start a declared
  pipeline on request ("sweep Sydney"); added to BASE so every agent may call it.
- POST /v1/instances/:id/pipelines/:name/run (owner-scoped + audited) +
  GET /v1/instances/:id/pipelines. PIPELINE_RUN workflow binding (Env, wrangler,
  index export).

Definitions stored per instance in agent_instances.config.pipelines[name] — the
least-invasive store (reuses the row requireOwnedInstance already reads; no new
migration; editable via the existing settings/MCP config round-trip).

Tests: schema validation, input resolution + fan-out, the runner threads outputs
between steps + dispatches via runRegistryTool (registry mocked), loadPipeline,
startPipelineRun kicks the workflow, and the POST endpoint owner-gated + audited.
The Workflow class itself isn't unit-tested (no Workflow harness); executePipelineStep
+ startPipelineRun cover its logic directly. api tsc clean; api suite 791 green
(761 baseline + new, 0 regressions).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[pipelines] Pipeline definition format + durable runner (trigger → declarative pipeline)

2 participants