Skip to content

Upgrade Switchyard plugin to production-ready native and library integration #401

Description

@bbednarski9

Summary

Upgrade the experimental nemo-relay-switchyard integration to production-ready status.

The current plugin is source-only, CLI feature-gated, and uses the Switchyard Decision API over HTTP. That is sufficient for the current sidecar-based integration, but it does not yet support native Relay harness integrations such as Hermes or LC Deep Agents, nor a published consumer-facing crate. As Switchyard evolves toward a library-first architecture, Relay should also be able to use Switchyard's decision and accumulation components in-process instead of requiring a separately managed Switchyard service.

Goals

1. Native harness integration

Make the Switchyard plugin available through Relay's native/runtime integration paths, not only the CLI wrapper:

  • Register and activate the plugin through native and worker/plugin-host lifecycles.
  • Support Hermes, LC Deep Agents, and future native harnesses without requiring nemo-relay-cli as the integration boundary.
  • Preserve the existing request/stream intercept behavior, target binding, retries, fallbacks, optimization accounting, and observability semantics.
  • Define the host/plugin contract for configuration, lifecycle, capabilities, and error reporting.

2. Publishable crate

Move nemo-relay-switchyard from source-only experimental packaging to a supported distribution model:

  • Define the public API and ownership boundary for the plugin.
  • Resolve the dependency/versioning strategy for Switchyard's public library crates.
  • Publish the crate (or a clearly defined supported crate split) with stable documentation, feature flags, compatibility policy, and release CI.
  • Keep the integration optional so Relay users do not pay for Switchyard dependencies unless they enable the plugin.
  • Provide supported examples that do not depend on internal services or untracked development worktrees.

3. In-process Switchyard library integration

Migrate from a required Switchyard sidecar to a library-backed DecisionProvider as the Switchyard library architecture becomes available:

  • Consume public Switchyard decision/routing APIs in-process.
  • Use Switchyard-owned ATOF accumulation/snapshot and decision logic where appropriate.
  • Keep provider-protocol translation in the Switchyard library rather than duplicating translation logic in Relay.
  • Preserve a service/HTTP adapter during migration for deployments that still need a separate Switchyard process.
  • Define snapshot freshness, lifecycle, concurrency, and failure semantics for embedded accumulators and decision providers.
  • Keep the versioned request/decision contract compatible across service and library modes.

Current limitations

  • The current plugin is publish = false and must be built from the Relay source checkout.
  • The CLI feature is the supported activation path; native harness integrations are not yet covered.
  • Decision API routing and ATOF-backed profiles require a reachable Switchyard service.
  • The current dependency on switchyard-translation is library-based, but decision logic and ATOF accumulation remain service-bound.
  • The current examples are experimental compatibility/E2E workflows rather than a production deployment contract.

Python packaging limitation

The current Python wheel cannot configure this plugin. The Python native extension does not depend on or register nemo-relay-switchyard, so a Python ComponentSpec(kind="switchyard", ...) is currently an unknown component.

Publishing the Rust crate alone would not solve this: Python support also requires wiring the crate into the Python native extension, registering the component kind, exposing/testing the configuration path, and documenting the sidecar or in-process runtime requirement. The crate can technically be built as a workspace/path dependency while publish = false; publication is needed for a stable external Rust dependency and release boundary, not as a substitute for Python integration.

Proposed work breakdown

  1. Document and implement the native host/plugin lifecycle contract.
  2. Add native-harness registration and integration tests.
  3. Define and stabilize the publishable crate boundary and feature/dependency policy.
  4. Add an in-process Switchyard DecisionProvider behind a Relay-owned abstraction.
  5. Add service and in-process conformance tests against the same request/decision fixtures.
  6. Add snapshot freshness, embedded accumulator lifecycle, and failure-mode tests.
  7. Update user-facing docs and examples once the supported deployment model is established.

Acceptance criteria

  • Hermes and LC Deep Agents can activate and use Switchyard routing through native integration paths without the CLI wrapper.
  • The published Python package can discover, configure, and execute the Switchyard component through its native/plugin API.
  • A supported published Rust crate/package can be consumed without a Relay source checkout.
  • Relay can run against an in-process Switchyard DecisionProvider with no mandatory Switchyard sidecar.
  • The HTTP Decision API remains available as a compatibility/deployment mode during the migration.
  • Service and library modes produce equivalent routing, translation, retry/fallback, optimization, and observability results for the same fixtures.
  • ATOF-backed routing has documented snapshot freshness and lifecycle behavior.
  • No internal-only services, credentials, or development worktrees are required by the supported examples.
  • Production readiness is documented with versioning, compatibility, performance, security, and operational guidance.

Related work

This issue is intentionally an umbrella tracker; implementation should be split into independently reviewable PRs.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions