Ask
The minimal libsy Python bindings expose only the managed Algorithm.run, which resolves to an aggregate response. For interactive hosts (chat UIs, agent runtimes) that embed libsy on the live completion path, a streaming form — run_stream yielding response chunks while the algorithm still owns target selection, judging, and fallback — would make the embedding straightforward.
Our current workaround
We run Switchyard algorithms per agent step with real clients: the Python client executes our native streaming pipeline, forwards deltas to the user out-of-band, and returns the aggregate to libsy. This works well (escalation mode and the stage router are live for us this way), but it means the response the user watches and the response libsy returns are reconciled by the host rather than by the library, and hosts without an existing streaming pipeline can't take that shortcut.
Shape that would work
algorithm.run_stream(request, headers=None) returning an async iterator of neutral response chunks plus a final decisions/summary object, with client call implementations allowed to return either an aggregate or an async iterator of chunks.
- Escalation mode's semantics under streaming are the interesting design question (the judged efficient answer may already have streamed when the verdict says escalate); we'd be happy to share what we learned shipping exactly that UX if useful.
Context: we embed Switchyard inside Gumloop's agent platform (fork: gumloop/gumloop-switchyard), with the custom N-target classifier binding proposed in #365.
Ask
The minimal libsy Python bindings expose only the managed
Algorithm.run, which resolves to an aggregate response. For interactive hosts (chat UIs, agent runtimes) that embed libsy on the live completion path, a streaming form —run_streamyielding response chunks while the algorithm still owns target selection, judging, and fallback — would make the embedding straightforward.Our current workaround
We run Switchyard algorithms per agent step with real clients: the Python client executes our native streaming pipeline, forwards deltas to the user out-of-band, and returns the aggregate to libsy. This works well (escalation mode and the stage router are live for us this way), but it means the response the user watches and the response libsy returns are reconciled by the host rather than by the library, and hosts without an existing streaming pipeline can't take that shortcut.
Shape that would work
algorithm.run_stream(request, headers=None)returning an async iterator of neutral response chunks plus a final decisions/summary object, with clientcallimplementations allowed to return either an aggregate or an async iterator of chunks.Context: we embed Switchyard inside Gumloop's agent platform (fork: gumloop/gumloop-switchyard), with the custom N-target classifier binding proposed in #365.