Skip to content

[AI-stack E8] @netscript/ai: orchestration primitives (fan-out + bounded-cycle) #247

Description

@rickylabs

Add @netscript/ai/orchestrate: two AbortSignal-threaded, explicitly bounded primitives (fan-out, bounded-cycle) for composing agent loops — no named strategies.

Context

Part of epic #238 · cluster ENGINE · wave defer · depends-on E1, E3.

This sits after the core contract (E1) and the base agent-loop primitive (E3) are stable; orchestration composes those loops rather than owning agent state, so it cannot land before either exists. Wave defer reflects that eis-chat and the first-wave provider adapters do not need multi-agent composition to ship.

Problem / motivation

@netscript/ai core has no vocabulary for running more than one agent loop at a time. Anything that needs fan-out (e.g. multiple provider calls in parallel) or a bounded iterate-until-condition loop today would be hand-rolled per call site, the same way eis-chat hand-rolls its own loop control — no shared cancellation, no shared bound-enforcement, no reusable seam other adapters or plugins/ai could depend on. Per the ratified orchestration decision, this gap is intentionally narrow: NetScript ships primitives only, not named multi-agent strategies (no "supervisor", "router", "debate" presets in v1), so the fix is two small composable functions, not a framework.

Scope

Ships

  • packages/ai-core/src/orchestrate/mod.ts exported as subpath @netscript/ai/orchestrate.
  • fanOut(tasks: AgentTask[], opts: { signal: AbortSignal }) — runs N agent-loop invocations concurrently, threads one AbortSignal to all children, rejects/aborts remaining tasks on first fatal error unless configured otherwise, returns settled results per task.
  • boundedCycle(step: AgentStep, opts: { signal: AbortSignal; maxIterations: number }) — iterates a single agent-loop step until its stop condition or maxIterations is hit, throwing a typed bound-exceeded error if the cap is reached without a stop; no unbounded/implicit-retry path.
  • Explicit AbortSignal propagation contract: both primitives must observe an already-aborted signal before doing any work and must stop scheduling new work once the signal fires mid-run.
  • Unit tests covering: normal completion, abort mid-flight, maxIterations exhaustion, and signal-already-aborted-at-call-time.

Out of scope

  • Named orchestration strategies/presets (router, supervisor, debate, etc.) — explicitly deferred, no slice owns this in v1 per the ratified decision.
  • Agent-loop implementation itself (loop state, tool-call turns) — owned by E3.
  • Provider adapters invoked inside the tasks/steps — owned by the provider adapter slices (e.g. E4/E5, per the epic: NetScript AI Stack — first-class AI runtime, chat & plugin seams (anchor #219) #238 DAG).
  • Gateway-mode dispatch of orchestrated calls — owned by the gateway opt-in slice.
  • Telemetry/span emission around orchestration boundaries — owned by E9 (./otel), which is the only slice allowed to import @netscript/telemetry via TelemetryPort.

Public surface

  • New subpath export: @netscript/ai/orchestrate (file: packages/ai-core/src/orchestrate/mod.ts).
  • Exports: fanOut, boundedCycle, AgentTask, AgentStep, OrchestrateBoundExceededError (typed error for maxIterations exhaustion).
  • No new manifest items, no new plugin surface — this is core-only.

Acceptance & fitness gates

  • F-3: orchestrate/ respects layering (domain -> ports -> application -> adapters); deno task arch:check passes.
  • F-5: mod.ts has @module JSDoc, full public-surface JSDoc, and stays at or under 20 exports.
  • F-6: publishes via deno task publish:dry-run WITHOUT --allow-slow-types.
  • F-13: both primitives have documented runtime stop behavior (AbortSignal observed pre- and mid-run; boundedCycle has an explicit, typed stop on bound exceeded — no silent truncation).
  • Core stays free of @netscript/* runtime deps (orchestrate imports nothing from @netscript/telemetry or any other framework package).
  • Unit tests pass for: normal completion, mid-flight abort, maxIterations exhaustion, and pre-aborted signal at call time.
  • deno check --unstable-kv clean on packages/ai-core.

Dependencies

Depends on E1, E3 (GitHub numbers tracked in the #238 DAG checklist).

Size

S

Part of #238

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions