Skip to content

Runner augmentation: register agents + engines via a3t/augment#45

Open
matt-wright86 wants to merge 1 commit into
mainfrom
feat/runner-augmentation
Open

Runner augmentation: register agents + engines via a3t/augment#45
matt-wright86 wants to merge 1 commit into
mainfrom
feat/runner-augmentation

Conversation

@matt-wright86

Copy link
Copy Markdown
Collaborator

Summary

A Runner augmentation so a bare new Runner() can register task agents and engines with a single import. import "@bifrost-ai/agent-3-task/augment" teaches the Runner class registerTaskAgent() / registerEngine() via declaration merging + Runner.prototype. Includes the deferred-config Runner, the agent-3-task augment, a runnable lvl3 example, and the fix that makes it work end-to-end.

Motivation

Registering a task agent meant hand-wiring a data registry, guards, an engine, and a free enrollTaskAgent call. This collapses it to:

import "@bifrost-ai/agent-3-task/augment";
import { Runner } from "@bifrost-ai/runner";

const runner = new Runner();
runner.registerEngine("fast", engine);
runner.registerTaskAgent({ name: "greeter" /* … */ });

The Runner core stays domain-neutral — each domain package opts in to its own methods through a side-effect /augment import, so the orchestrator never learns about "task agents".

  • Related issue/rune: #

Type of change

  • New feature (non-breaking) — the augment + deferred Runner
  • Bug fix (non-breaking) — bare-Runner registration threw Unknown data type
  • Breaking change
  • Documentation
  • Refactor / cleanup — /simplify pass; removed a debug log + a duplicate file
  • Test coverage — bare-Runner registration regression test
  • Chore / tooling

Checklist

  • Raw go/npx were not used
  • make lint / make test / make build — N/A: orchestrator-v2 uses its own vp/oxlint toolchain
  • vp run -r build clean · vp run -r test green (41/41)
  • Tests added for the new behavior
  • Commit messages are short, lowercase, imperative
  • No force-push to main
  • Self-reviewed the diff

What changed

  • agent-3-task/augmentregisterTaskAgent / registerEngine on Runner.prototype, plus the DataRegistries module augmentation for type-safe registries.
  • Deferred Runnernew Runner() with no args (identity/url resolved at start()); createTaskAgent replaces enrollTaskAgent.
  • ensure(type, guard) on the mutable data registry — the fix. A bare new Runner() starts with an empty data registry, so register* called get("agentDefinition"|"engine") and threw Unknown data type. ensure lazily creates the guarded registry on first use, so the isEngine / isAgentDefinition validation is preserved.
  • lvl3 example + a regression test that drives a bare-Runner registration (also closes the "example has no tests" CI gate).

Notes for reviewers

  • taskAgentDataGuards is now unused. The augment threads guards individually, so the bundle has no consumers — revive it via a registry seed(bundle) method, or drop it. Left as a design call.
  • Overlaps with refactor/orchestrator-v2-hardening ([Experiment] orchestrator-v2 hardening: telemetry, resilience, capability routing #43) in interfaces-task and runner/runner.ts — whichever lands first, the other rebases.
  • The upcoming task-source → "work item" rename will give ExecutionStats its neutral home (out of interfaces-task-source).

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@matt-wright86, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 11 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 05e080de-c312-4526-bc3c-e8fb17e41432

📥 Commits

Reviewing files that changed from the base of the PR and between e44e8df and 6b441ef.

⛔ Files ignored due to path filters (1)
  • orchestrator-v2/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • orchestrator-v2/packages/agent-3-task/package.json
  • orchestrator-v2/packages/agent-3-task/src/augment.spec.ts
  • orchestrator-v2/packages/agent-3-task/src/augment.ts
  • orchestrator-v2/packages/agent-3-task/vite.config.ts
  • orchestrator-v2/packages/interfaces-work/src/types.ts
  • orchestrator-v2/packages/runner/src/data-registry.ts
📝 Walkthrough

Walkthrough

This PR introduces a shared DataRegistries/DataRegistryGuards typing contract in interfaces-task, threads it through the runner's data registry (adding an ensure method) and Runner/RunnerOptions defaults, and replaces enrollTaskAgent with Runner.prototype augmentation methods (registerTaskAgent, registerEngine) in agent-3-task. Package exports, build configs, workspace globs, and tsconfig references are updated accordingly, and a new examples/lvl3 package is added demonstrating the new registration flow.

Changes

DataRegistries refactor and Runner augmentation

Layer / File(s) Summary
DataRegistries/DataRegistryGuards contract
orchestrator-v2/packages/interfaces-task/src/types.ts, orchestrator-v2/packages/interfaces-task/src/index.ts
Adds DataRegistries and DataRegistryGuards types, updates DataRegistry, MutableDataRegistry (with new ensure method), ScriptContext, and ScriptTaskDefinition to default to DataRegistries, and re-exports the new types.
Runner data-registry ensure() implementation
orchestrator-v2/packages/runner/src/data-registry.ts, orchestrator-v2/packages/runner/src/data-registry.spec.ts
Reworks createDataRegistry overloads, adds an ensureRegistry helper for lazy guarded registry creation, exposes ensure on returned registries, defaults asDataRegistry to DataRegistries, and updates tests to use explicit generics and MutableDataRegistry typing.
Runner and RunnerOptions default generics
orchestrator-v2/packages/runner/src/runner.ts, orchestrator-v2/packages/runner/src/types.ts
Changes Runner class and RunnerOptions type generic defaults from Record<string, unknown> to DataRegistries.
Runner prototype augmentation replacing enrollTaskAgent
orchestrator-v2/packages/agent-3-task/src/augment.ts, .../index.ts, .../create-task-agent.ts, .../run-task-agent.ts, .../run-task-agent.spec.ts
Removes enroll-task-agent.ts and its re-exports; adds augment.ts with module augmentation and Runner.prototype.registerTaskAgent/registerEngine implementations, wired via a side-effect import; updates createTaskAgent/runTaskAgent typing and tests to use DataRegistries instead of TaskAgentDataSchema.
Package exports, build config, and workspace/tsconfig wiring
orchestrator-v2/packages/agent-3-task/package.json, .../vite.config.ts, .../tsconfig.json, orchestrator-v2/packages/engine/package.json, orchestrator-v2/pnpm-workspace.yaml, orchestrator-v2/tsconfig.json
Adds ./augment export and @bifrost-ai/runner dependency to agent-3-task; adds augment build entry; updates engine's export shape; adds examples/* workspace glob and directory-level tsconfig references.
New lvl3 example package
orchestrator-v2/examples/lvl3/package.json, .../tsconfig.json, .../src/index.ts, .../src/index.spec.ts
Adds a new example package manifest, tsconfig, an entrypoint registering a task agent via Runner, and a spec verifying registration works on a bare Runner instance.

Sequence Diagram(s)

sequenceDiagram
    participant Example as examples/lvl3 index.ts
    participant Runner
    participant Augment as augment.ts
    participant Registry as DataRegistry

    Example->>Runner: new Runner()
    Example->>Runner: registerTaskAgent(agentDefinition)
    Runner->>Augment: invoke prototype method
    Augment->>Registry: ensure("agentDefinition")
    Augment->>Registry: register AgentDefinition
    Augment->>Runner: register task agent via createTaskAgent
Loading

Compact metadata

  • Related issues: None referenced in the provided summary.
  • Related PRs: None referenced in the provided summary.
  • Suggested labels: refactor, typescript, breaking-change
  • Suggested reviewers: None specified.

🐰 A registry once eager, now ensures on call,
Runner's prototype grows a method or two,
enrollTaskAgent bows out, augment takes it all,
lvl3 hops in, greeting fresh and new. 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: Runner augmentation for registering agents and engines via the augment module.
Description check ✅ Passed The description accurately matches the changeset and explains the augmentation, deferred Runner behavior, example, and bug fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
orchestrator-v2/packages/interfaces-task/src/types.ts (1)

3-9: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

keyof DataRegistries & string doesn't actually restrict keys — it collapses to plain string.

Because DataRegistries extends Record<string, unknown>, TypeScript's keyof operator folds every explicitly-augmented property name into the index signature's key type. Per the TS handbook/release notes, when a type has a string index signature, keyof produces string regardless of the concrete literal members that have been merged in.

Consequences:

  • DataRegistryGuards<T extends keyof DataRegistries & string> accepts any string for T, not just keys actually declared via module augmentation (e.g., taskAgent, engine). A typo like ensure("egnine", guard) (Line 35-38) type-checks fine.
  • When the key literal isn't independently pinned by inference at the call site, Pick<DataRegistries, T> silently resolves the value to unknown instead of erroring or preserving the guard's asserted type — this also affects the createDataRegistry<T extends keyof DataRegistries & string> overload in runner/src/data-registry.ts (Lines 16-18 there), which relies on this exact constraint to select Pick<DataRegistries, T>.

This defeats the compile-time safety the shared DataRegistries contract is meant to provide — precisely the guarantee registerTaskAgent/registerEngine rely on.

📚 TypeScript reference

Per TS 2.9 release notes: "If X contains a string index signature, keyof X is a union of string, number, and the literal types representing symbol-like properties, otherwise" it uses the literal property names.

Worth confirming intent — if this is an accepted trade-off for extensibility, no action needed; otherwise consider a design that preserves literal-key enforcement (e.g., not extending Record<string, unknown> directly, or a separate compile-time-checked key registry).

Also applies to: 35-38

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@orchestrator-v2/packages/interfaces-task/src/types.ts` around lines 3 - 9,
`DataRegistries`’s `Record<string, unknown>` base makes `keyof DataRegistries &
string` widen to plain `string`, so invalid registry keys slip through. Update
the shared typing in `types.ts` and the dependent `createDataRegistry`/guard
signatures so keys are constrained to the actual augmented registry names, not
any string; keep the existing `DataRegistries`, `DataRegistryGuards`, and
`Pick<DataRegistries, T>` call sites working with literal-key inference.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@orchestrator-v2/packages/interfaces-task/src/types.ts`:
- Around line 3-9: `DataRegistries`’s `Record<string, unknown>` base makes
`keyof DataRegistries & string` widen to plain `string`, so invalid registry
keys slip through. Update the shared typing in `types.ts` and the dependent
`createDataRegistry`/guard signatures so keys are constrained to the actual
augmented registry names, not any string; keep the existing `DataRegistries`,
`DataRegistryGuards`, and `Pick<DataRegistries, T>` call sites working with
literal-key inference.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ffdf1149-9ab5-45d3-89e1-afa2096e092a

📥 Commits

Reviewing files that changed from the base of the PR and between a411816 and e44e8df.

⛔ Files ignored due to path filters (1)
  • orchestrator-v2/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (22)
  • orchestrator-v2/examples/lvl3/package.json
  • orchestrator-v2/examples/lvl3/src/index.spec.ts
  • orchestrator-v2/examples/lvl3/src/index.ts
  • orchestrator-v2/examples/lvl3/tsconfig.json
  • orchestrator-v2/packages/agent-3-task/package.json
  • orchestrator-v2/packages/agent-3-task/src/augment.ts
  • orchestrator-v2/packages/agent-3-task/src/create-task-agent.ts
  • orchestrator-v2/packages/agent-3-task/src/enroll-task-agent.ts
  • orchestrator-v2/packages/agent-3-task/src/index.ts
  • orchestrator-v2/packages/agent-3-task/src/run-task-agent.spec.ts
  • orchestrator-v2/packages/agent-3-task/src/run-task-agent.ts
  • orchestrator-v2/packages/agent-3-task/tsconfig.json
  • orchestrator-v2/packages/agent-3-task/vite.config.ts
  • orchestrator-v2/packages/engine/package.json
  • orchestrator-v2/packages/interfaces-task/src/index.ts
  • orchestrator-v2/packages/interfaces-task/src/types.ts
  • orchestrator-v2/packages/runner/src/data-registry.spec.ts
  • orchestrator-v2/packages/runner/src/data-registry.ts
  • orchestrator-v2/packages/runner/src/runner.ts
  • orchestrator-v2/packages/runner/src/types.ts
  • orchestrator-v2/pnpm-workspace.yaml
  • orchestrator-v2/tsconfig.json
💤 Files with no reviewable changes (1)
  • orchestrator-v2/packages/agent-3-task/src/enroll-task-agent.ts

Rebuilds the agent-3-task Runner augmentation on top of the work-item
unification (#44). registerTaskAgent/registerEngine on Runner.prototype now
target registerWorkItemHandler, and a bare new Runner() lazily creates its
guarded data registry via a new ensure(type, guard) instead of throwing
"Unknown data type".

- ensure(type, guard) on MutableDataRegistry (+ shared ensureRegistry helper)
- ./augment export + a runner dependency on agent-3-task
- regression test for bare-Runner registration

Co-Authored-By: Eric Siebeneich <eric.siebeneich@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@matt-wright86 matt-wright86 force-pushed the feat/runner-augmentation branch from e44e8df to 6b441ef Compare July 4, 2026 21:04
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.

1 participant