voice: drop workflow dependency, drive turns via agent.Run + engine.Engine [skip-tag:voice]#58
Merged
Merged
Conversation
…ngine [skip-tag:voice]
NewPipeline now takes (engine.Engine, agent.Agent) instead of
(workflow.Runtime, workflow.Agent). The pipeline installs an internal
voiceHost that captures stream-delta envelopes for the active runID
and converts them to voice events; non-stream Host methods delegate
to an optional caller-supplied host (WithEngineHost).
History injection is no longer a pipeline concern. WithTurnHistory /
WithContextID are removed; callers wire history through an
agent.BoardSeeder via the new WithRunOptions(...) escape hatch.
Tests rewritten on top of engine.Engine fakes that publish stream
deltas via engine.EmitStream{Token,ToolCall,ToolResult}. The set of
test functions is unchanged — only the fakes were translated to the
new stack.
Session no longer copies sessionID into a pipeline contextID field
(that field is gone); callers that need agent.Request.ContextID can
attach it via WithRunOptions + agent.WithAttributes.
voice/go.mod bumped from sdk v0.2.2 to v0.2.7 to pull in the agent +
engine packages required by the new wiring.
Carries [skip-tag:voice] because this is a breaking change to voice's
public NewPipeline / option surface; auto-tag's patch-only logic
would label it incorrectly. Release coordinator should hand-tag
voice/v0.2.0.
Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
voice.Pipelineno longer importssdk/workflow. Turns are now driven byagent.Runagainst anyengine.Engine; the pipeline installs an internalvoiceHostto capture stream-delta envelopes for the active runID and translate them intovoice.Events.WithEngineHost(engine.Host)(fan-out for OTel / event bus / interrupts / checkpointer) andWithRunOptions(...agent.RunOption)(escape hatch foragent.BoardSeeder, observers, deciders, attributes — including history loading, which is no longer a pipeline concern).WithTurnHistory,WithContextID.Session.pipelineForTurnno longer copies sessionID into a pipeline-level context field.voice/go.mod:sdk v0.2.2→v0.2.7(needed foragent.Runandengine.StreamDeltaPayload).Why
[skip-tag:voice]This is a breaking change to voice's public
NewPipelinesignature and option surface. Auto-tag's patch-only bump would label it incorrectly. The release coordinator should hand-tagvoice/v0.2.0after merge.Migration
Old:
```go
voice.NewPipeline(s, t, workflowRuntime, workflowAgent,
voice.WithTurnHistory(msgs),
voice.WithContextID("sess-1"),
)
```
New:
```go
voice.NewPipeline(s, t, engineImpl, agent.Agent{ID: "voice"},
voice.WithRunOptions(
agent.WithBoardSeed(historySeeder(msgs)),
agent.WithAttributes(map[string]string{"context_id": "sess-1"}),
),
)
```
For graph-based agents, the engine is
runner.New(def, factory)fromsdk/graph/runner(it satisfiesengine.Enginedirectly).Verification
Bug found & fixed during refactor
`agent.Run` returns `(res, nil)` for engine-side failures (errors land on `res.Err` + non-completed `res.Status`), unlike the old `workflow.Runtime.Run` which returned the error directly. The naive port lost `EventError` emission for runner failures; `TestPipeline_RunnerError` caught it and `startFlow` now reads both `err` and `res.Err`, while filtering out cancelled/interrupted statuses to preserve Abort behaviour.
Out of scope (intentional)
Test plan
Made with Cursor