Skip to content

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

Merged
thymikee merged 3 commits into
mainfrom
feat/phase4-response-level
Jun 30, 2026
Merged

feat: leveled response views + --level knob with snapshot digest — Phase 4#942
thymikee merged 3 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).

@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.1 kB
JS gzip 455.1 kB 455.5 kB +443 B
npm tarball 560.4 kB 561.0 kB +544 B
npm unpacked 2.0 MB 2.0 MB +1.7 kB

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 27.0 ms 25.9 ms -1.1 ms
CLI --help 48.2 ms 46.9 ms -1.3 ms

Top changed chunks:

Chunk Raw diff Gzip diff
dist/src/9722.js +599 B +230 B
dist/src/2948.js +309 B +138 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.

thymikee added a commit that referenced this pull request Jun 29, 2026
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.

thymikee added 2 commits June 30, 2026 07:27
… 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).
The kernel move (#940) deleted src/utils/device.ts; #941's
command-output-schemas.ts (merged after #940's codemod ran) still imported the
old path. Same one-line fix as #943; de-dups once that lands.
@thymikee thymikee force-pushed the feat/phase4-response-level branch 2 times, most recently from 744574e to 4d1263a Compare June 30, 2026 05:45
The --level/responseLevel flag is a diagnostics/output flag (not device-
observable), classified in the exclusion bucket alongside --cost. (Lost in an
earlier rebase; re-applying.)
@thymikee thymikee force-pushed the feat/phase4-response-level branch from 4d1263a to d7d2c77 Compare June 30, 2026 05:45
@thymikee

Copy link
Copy Markdown
Member Author

Rechecked current head d7d2c77 after the update. This appears to be a rebase/main-fix refresh; the digest-output blocker is still unresolved.

The PR diff still does not change the snapshot client/output path (client.capture.snapshot() / normalizeSnapshotResult / snapshotCliOutput), so a daemon digest with { nodeCount, refs } is still expected to be normalized into an empty default-shaped snapshot before CLI output. Please address the existing blocker with a response-level-aware snapshot client/output path or equivalent shipped-path preservation, plus a test that exercises real snapshot output for responseLevel: digest / --level digest.

@thymikee thymikee merged commit 43d0a63 into main Jun 30, 2026
21 checks passed
@thymikee thymikee deleted the feat/phase4-response-level branch June 30, 2026 05:53
@github-actions

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-06-30 05:53 UTC

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