Skip to content

Bind the originating query to the canvas: persisted tool-call recipes for deterministic replay #11

Description

@Weegy

Summary

Extension of #5. Deterministic refresh only works if the canvas knows how its data was produced. Today that knowledge evaporates after the turn: the LLM interprets the user's request, makes tool calls, gets responses, and composes the tree — and none of that pipeline is persisted with the canvas. Only the resulting tree (with its dataRefs) survives.

This issue proposes binding the query to the canvas: persist the resolved data-production recipe — the concrete tool calls with their final parameters, the response→primitive data mapping, and the composition decisions — as a first-class part of the canvas, so the canvas can be re-materialized deterministically, with no LLM in the loop.

Motivation

Proposed behavior

  1. Canvas recipe. When a turn produces or patches a canvas, Tier 2 persists alongside the tree: the ordered set of tool calls (tool id, resolved/concrete parameters — no free-text placeholders), the mapping from each response to the primitive data it populated (by stable primitive id), and any deterministic post-processing applied (sort, limit, aggregation expressed as data ops, not prose).
  2. Refresh = replay. canvas_refresh (Deterministic refresh for data-driven canvases (no LLM turn) #5) executes the recipe: re-run the recorded tool calls with the recorded parameters, re-apply the recorded mappings, diff against the current revision, emit patch ops. The LLM is not invoked.
  3. Parameterization, not re-interpretation. Recipe parameters that are time-relative ("last 30 days") are stored as resolved expressions (now − 30d), not as the frozen values, so replay moves the window deterministically. The set of allowed expressions is small and closed — anything that would need interpretation stays frozen and is marked non-refreshable.
  4. Drift handling. If a recorded tool call fails on replay (tool removed, schema changed, permission revoked), the affected primitives get a defined stale/error state and the client offers the escalation path from Deterministic refresh for data-driven canvases (no LLM turn) #5: one explicit LLM turn to rebuild the recipe. The new recipe replaces the old one.
  5. Determinism contract. Recipes record the ops-catalog version and tool versions they were built against; replay refuses (with the drift path above) rather than silently producing different semantics on a version mismatch.

Open questions

Affected areas

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions