Skip to content

Let arranging operators return a caller-chosen agent - #916

Draft
antiguru wants to merge 1 commit into
TimelyDataflow:master-nextfrom
antiguru:generic-agent
Draft

antiguru wants to merge 1 commit into
TimelyDataflow:master-nextfrom
antiguru:generic-agent

Conversation

@antiguru

Copy link
Copy Markdown
Member

arrange_core, reduce_with_tactic, and arrange_from_upsert build their trace and hard-wire the reader they return to TraceAgent, which hides the trace inside its TraceBox. A trace that shares state with something outside the operator, such as a handle through which other threads observe its batches, can only hand that state back through TraceAgent::trace_box_unstable.

This adds an Agent trait for the reader an operator returns. Agent::new takes the trace by value and returns the reader and a TraceWriter, and TraceAgent implements it by delegating to TraceAgent::new. arrange_core_with_agent, reduce_with_tactic_and_agent, and arrange_from_upsert_with_agent return Arranged<A> for a caller's agent, which can take the trace's shared state before wrapping a TraceAgent. The existing functions delegate with TraceAgent, so no caller changes. The writer stays concrete, since TraceWriter::new and TraceBox::new are already public.

This is the alternative to #915, which injects a trace factory instead. Here the handle becomes part of the returned type rather than leaving through a closure. Open points for discussion:

  • Fixing TraceWriter<Self::Trace> in the trait rules out agents that intercept writes. Adding a writer associated type later would break implementers.
  • Reduce and upsert read and compact through their own clone of the agent, so an agent must honour the TraceReader contract of the trace it wraps.
  • Only the lowest-level entry points get variants. reduce_abelian, reduce_core, and reduce_trace still return TraceAgent.

Posted by Claude Code.

🤖 Generated with Claude Code

https://claude.ai/code/session_015tLhSbZdXrTSK2KwSocT59

`arrange_core`, `reduce_with_tactic`, and `arrange_from_upsert` build their
trace and hard-wire the reader they return to `TraceAgent`, which hides the
trace inside its `TraceBox`. A trace that shares state with something outside
the operator, for example a handle through which other threads observe its
batches, then has no stable way to hand that state to its caller:
`TraceAgent::trace_box_unstable` is the only path.

The `Agent` trait abstracts the reader an operator returns: `Agent::new`
takes the trace by value and returns the reader and a `TraceWriter`.
`TraceAgent` implements it by delegating to `TraceAgent::new`. The new
`arrange_core_with_agent`, `reduce_with_tactic_and_agent`, and
`arrange_from_upsert_with_agent` return `Arranged<A>` for a caller's agent
`A`, which can keep the trace's shared state before wrapping a
`TraceAgent`. The existing functions delegate with `TraceAgent`, so their
callers are unchanged.

The writer stays concrete. `TraceWriter::new` and `TraceBox::new` are public,
so any agent can build one.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015tLhSbZdXrTSK2KwSocT59

This branch has not been deployed

No deployments
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