Skip to content

feat: leveled response views + --level knob with snapshot digest — Phase 4#942

Open
thymikee wants to merge 2 commits into
mainfrom
feat/phase4-response-level
Open

feat: leveled response views + --level knob with snapshot digest — Phase 4#942
thymikee wants to merge 2 commits into
mainfrom
feat/phase4-response-level

Conversation

@thymikee

Copy link
Copy Markdown
Member

What

The core of Phase 4's token win: a leveled response system. A responseLevel knob — digest | default | full — behind a global --level flag (mirroring --cost), with a per-command ResponseView registry applied in the router on the success path.

The headline view: snapshot digest collapses the full node tree (the dominant token sink for agents) to { nodeCount, refs: first 12 hittable/non-occluded refs with labels } plus the cheap top-level signals.

agent-device snapshot --level digest   # token-cheap; just counts + actionable refs
agent-device snapshot                  # default — byte-identical to today

Invariant (Maestro-safe)

With responseLevel default (or unset) AND no registered view AND no --cost, the router returns the original response object untouched — byte-identical to today, so the Maestro .ad recompare path is unaffected. Views and cost are purely additive and compose (cost computed from the original node tree, so cost.nodeCount stays accurate even after a digest).

Changes

  • src/contracts.ts: RESPONSE_LEVELS/ResponseLevel, meta.responseLevel, boundary-schema whitelist. Plumbing mirrors --cost end to end (cli-flags FlagDefinition + GLOBAL_FLAG_KEYS, AgentDeviceClientConfig + overrides, buildClientConfig, buildMeta). ResponseLevel exported from the public root.
  • src/daemon/response-views.ts (new): the ResponseView registry, seeding the snapshot digest. full returns today's shape (nothing richer is computed yet).
  • src/daemon/request-router.ts: applyResponseLevelView + applyAgentCostGrafts on the success path — composes cleanly with the existing cost block.

Tests

  • response-views.test.ts: the snapshot view — digest filters to hittable === true && interactionBlocked !== 'covered', drops the tree, keeps truncated/visibility/snapshotQuality; default/full are reference-identical passthroughs.
  • request-router-response-level.test.ts: the router graft via an injected test view — (a) default identity is JSON.stringify-identical to no-meta, (b) digest applies, (c) full passthrough, (d) digest + --cost composition, (e) unregistered command + digest is byte-identical, (f) responseLevel survives boundary parse.

Verification

  • tsc --noEmit 0; oxfmt + oxlint --deny-warnings clean; fallow audit --base origin/main clean; rslib build 0; Layering Guard empty
  • vitest daemon/contracts/client → 111 files / 1106 tests pass (incl. the existing cost/typed-error grafts after the router restructure)

Scope / follow-ups (Phase 4 workstreams)

  • This is WS1 (the core + snapshot digest). Sibling PR feat: per-command MCP outputSchema — Phase 4 #941 adds per-command MCP outputSchema (independent).
  • Deferred: more digest views (screenshot overlayRefs, the single-node find/get family); the typed batch-step digest (WS4, rides on this); MCP responseLevel exposure (held back to avoid colliding with feat: per-command MCP outputSchema — Phase 4 #941's command-tools.ts edits); and the zero-load fast-path generalization (sensitive routing — better as a focused follow-up).

… Phase 4

Add the agent-cost leveled-response system: a responseLevel knob
(digest | default | full) plumbed end to end behind a global --level flag
(mirroring --cost), and a per-command ResponseView registry applied in the
router on the success path.

- contracts: RESPONSE_LEVELS/ResponseLevel + meta.responseLevel + boundary
  schema whitelist. Plumbing mirrors --cost: cli-flags FlagDefinition +
  GLOBAL_FLAG_KEYS, AgentDeviceClientConfig + overrides, buildClientConfig,
  buildMeta. ResponseLevel exported from the public root.
- src/daemon/response-views.ts: the ResponseView registry. Seeds the snapshot
  digest — the full node tree (the dominant token sink) collapses to
  { nodeCount, refs: first 12 hittable/non-occluded refs with labels } plus the
  cheap top-level signals (truncated/visibility/snapshotQuality). full returns
  today's shape (nothing richer is computed yet).
- router graft (applyResponseLevelView + applyAgentCostGrafts): composes with
  the existing cost block. With responseLevel default (or unset) AND no
  registered view AND no --cost, the original response is returned UNCHANGED —
  byte-identical to today (Maestro .ad recompare safe). cost.nodeCount reads the
  original node tree so it stays accurate even after a digest.

Tests: snapshot view unit test (digest filters hittable/occluded, drops the
tree, keeps cheap signals; default/full passthrough); router graft test via an
injected view (default identity byte-identical, digest applies, full passthrough,
digest+cost composition, unregistered-command passthrough, boundary parse).

Verified: tsc, oxfmt + oxlint --deny-warnings, fallow audit clean, rslib build,
Layering Guard empty, 1106 daemon/contracts/client tests pass (incl. the
existing cost/typed-error grafts after the restructure).
@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown

Size Report

Metric Base Current Diff
JS raw 1.4 MB 1.4 MB -1.9 kB
JS gzip 453.3 kB 452.8 kB -515 B
npm tarball 558.5 kB 557.2 kB -1.3 kB
npm unpacked 2.0 MB 2.0 MB -5.0 kB

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 25.7 ms 25.1 ms -0.7 ms
CLI --help 44.5 ms 43.3 ms -1.2 ms

Top changed chunks:

Chunk Raw diff Gzip diff
dist/src/9722.js +599 B +230 B
dist/src/2948.js +77 B +75 B
dist/src/cli.js +30 B +10 B

@thymikee

Copy link
Copy Markdown
Member Author

Current head 08b715d is blocked by CI. Integration Tests fail in pnpm test:integration:progress:check because the new public CLI flag responseLevel is unclassified by scripts/integration-progress.ts:

provider-backed integration progress check failed: unclassified public CLI flags: responseLevel

Please add responseLevel to the appropriate progress-script coverage bucket, likely the config/output/diagnostics/transport bucket if it is an output-shaping flag, or another explicit owner if the PR intends different coverage. The rest of the completed checks are green.

The new --level/responseLevel flag (#942) is a diagnostics/output flag (not
device-observable), so it belongs in the exclusion bucket alongside --cost.
Unblocks the Provider-backed integration progress check.
@thymikee

Copy link
Copy Markdown
Member Author

Reviewed current head 1389c40 against Phase 4 and the shipped command path. The previous CI blocker is fixed and all 21 checks are green, but I found one blocker before this can be ready.

--level digest is applied in the daemon, but the snapshot client path appears to normalize the digest back into an empty default-shaped snapshot before CLI output. src/daemon/response-views.ts returns the intended digest shape { nodeCount, refs, ... } with no nodes array. Then client.capture.snapshot() still routes the daemon result through normalizeSnapshotResult, which reads data.nodes via readSnapshotNodes; without nodes, that becomes [], and the later snapshot serializer emits { nodes: [], truncated: ... } rather than the digest refs/count.

That means the advertised token-cheap agent-device snapshot --level digest shape is not what CLI users get through the production command surface. The tests cover the raw daemon view and a mocked router view, but not the real snapshot client/CLI path, so this regression can pass green CI. Please either preserve digest-shaped snapshot responses through the client/output layer or add a response-level-aware output path, plus a test that exercises real snapshot command output for responseLevel: digest / --level digest.

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