Class DecisionTrace

java.lang.Object
ai.redouble.demo.decide.DecisionTrace
All Implemented Interfaces:
JobObserver<JobEvent>

public final class DecisionTrace extends Object implements JobObserver<JobEvent>
One decision agent run, streamed as it happens: an observer on the runtime's message bus, scoped to the run's workflow, writing every event of the thinker and of every job under it as one line of newline-delimited JSON. Every line names its job (id, parent, type, display name, tool name, the turn it belongs to), so a page rebuilds the tree and draws each turn as the decision that opened it and the tool that ran on it. A decision's completion carries the whole exchange: the state the model was shown (the objective, one line per artifact, the moves so far), the questions asked, and every answer with its distribution, since a decision model leaves no reasoning to show and the distributions are what it thought. A tool's completion carries the artifact it produced. The last line is the answer (the statements selected), the run's turns as the thinker recorded them, and the totals, or the failure; it is written when the run's own terminal event comes through the bus, after every line before it. The lines go to any sink; a host wraps the sink in its own streaming response and is told when the stream ends. A sink that refuses a line (the reader left) stops the lines and nothing else: the run goes on to its end on the runtime.
Since:
0.1 (2026-09-24)
Author:
Andrey Santrosyan
  • Constructor Details

    • DecisionTrace

      public DecisionTrace(String workflowId, String thinkerJobId, Consumer<String> sink, Runnable onEnd)
      Parameters:
      workflowId - the run's workflow, the scope of the events read
      thinkerJobId - the thinker's own job id, the root of the tree
      sink - where each line goes, newline included; a sink that throws UncheckedIOException or IllegalStateException has lost its reader
      onEnd - told once, when the last line has been written
  • Method Details

    • getPredicate

      public Predicate<JobEvent> getPredicate()
      Description copied from interface: JobObserver
      Returns a predicate for filtering events at the MessageBus level. Called once during subscription.
      Specified by:
      getPredicate in interface JobObserver<JobEvent>
      Returns:
      predicate to filter events, or null to accept all events of type T
    • observe

      public void observe(JobEvent event)
      Description copied from interface: JobObserver
      Process a job event. Runs in a separate virtual thread. Must handle its own resources and exceptions.
      Specified by:
      observe in interface JobObserver<JobEvent>
      Parameters:
      event - the job event to process
    • fail

      public void fail(Throwable failure)
      The last line when the run itself failed, then the stream closes. The run's own failed event brings it here; a holder of the handle calls it only when no terminal event reached the stream (awaitEnd(Duration)), so a stream never hangs open on a run that ended without one.
    • awaitEnd

      public boolean awaitEnd(Duration wait) throws InterruptedException
      Whether the stream ended within the wait: the run's own terminal event came through and wrote the last line.
      Throws:
      InterruptedException