Skip to content

feat(decopilot): background slow generate_image as a durable job#3979

Open
pedrofrxncx wants to merge 4 commits into
mainfrom
bg-tool
Open

feat(decopilot): background slow generate_image as a durable job#3979
pedrofrxncx wants to merge 4 commits into
mainfrom
bg-tool

Conversation

@pedrofrxncx

@pedrofrxncx pedrofrxncx commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Backgrounds slow generate_image calls so they no longer freeze the user's turn or the per-thread gate. On the cluster the tool enqueues a durable DBOS workflow (generate → append result → re-enter the thread gate to react) and returns a "started" handle immediately; desktop daemons POST the work back to a fence-authed cluster route.

How it works

  • makeBackgroundable(name, tool, dispatcher) wraps a slow built-in. With no dispatcher (desktop without link, tests) it returns the inner tool unchanged — backgrounding is a cluster capability, not a behavior change everywhere.
  • Cluster: createBackgroundToolDispatcher enqueues backgroundToolWorkflow on a per-org partitioned DBOS queue. Steps: runHeavyTool (memoized — replays don't regenerate a different image) → appendResult (assistant message rendered via the normal generate_image card) → react (re-enter the per-thread gate so the agent acknowledges/continues).
  • Desktop daemon: createHttpBackgroundDispatcher POSTs to /api/:org/threads/:threadId/background-tool, authed with the run's temp bearer + run fence token, which runs the same cluster workflow.
  • No bespoke job table — DBOS owns durability, idempotency, status, and cancellation; the jobId is the workflow id.

Review fixes included

  • Background card no longer spins forever. The originating call returns a handle; the card is now terminal ("Image queued — generating in the background") and the finished image arrives as its own message below.
  • Reaction nudge hidden from the transcript. The reaction turn's role:"user" nudge ("…do NOT call generate_image again") would otherwise render as a user bubble. Added an internal flag to message Metadata; useMessagePairs filters it, so the model still sees it but the user doesn't. Round-trips on both v1 (saveMessages) and v2 (PartEmitter finish anchor).
  • Validated the route's tool input against the generate_image schema instead of forwarding an unvalidated z.unknown() cast.
  • Deterministic reaction-message id so a workflow replay doesn't mint a new one.

Testing

  • bun run check — clean
  • oxlint on changed files — clean
  • bun test on backgroundable, decopilot-events, run-registry, thread-gate-workflow — pass

Notes

  • The "X agents working on N tasks" home badge (running-threads summary) was bundled onto this branch and has been removed here — it's an independent feature for its own PR.
  • apps/mesh/src/tools/connection/create.ts (an unrelated ON_MCP_CONFIGURATION firstRun change) is left out of this PR.
  • This branch's merge-base is behind main; the running-threads removal restores files to their pre-feature state, so a main merge/rebase is still pending separately.

- generate_image background card is terminal (idle), not a permanent spinner
- hide the reaction nudge from the transcript via an internal message-metadata
  flag (model still sees it; useMessagePairs filters it)
- throttle per-step running-summary touch to once/min per run to cut KV CAS
  write amplification + cross-run contention on the shared per-org key
- validate the background-tool route input against the generate_image schema
  instead of forwarding an unvalidated cast
- deterministic reaction-message id (workflow replay must not mint a new one)
- backfill runningStore in the reactor/registry test fixtures
The "X agents working on N tasks" home badge is an independent feature that
got bundled onto this branch. Remove it so the PR is scoped to the
background-tool work: deletes the running-threads store + use-running-summary
hook, and restores run-reactor, thread/ports storage, constants, the SSE pool,
the home page, and the mesh-sdk running-summary types/events to their
pre-feature state.
Updated the backgroundToolWorkflow declaration from an export to a const assignment for improved clarity and consistency in the workflow registration process.
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