Skip to content

feat(runtime): surface cost, usage breakdown, and available commands on status events and getStatus#345

Open
DaniAkash wants to merge 3 commits into
openclaw:mainfrom
DaniAkash:feature/runtime-usage-and-commands-on-status
Open

feat(runtime): surface cost, usage breakdown, and available commands on status events and getStatus#345
DaniAkash wants to merge 3 commits into
openclaw:mainfrom
DaniAkash:feature/runtime-usage-and-commands-on-status

Conversation

@DaniAkash
Copy link
Copy Markdown
Contributor

@DaniAkash DaniAkash commented May 25, 2026

Surfaces fields the wire protocol already carries but the runtime currently throws away. Pure addition — every new field is optional and existing event shapes are preserved.

Motivation

Downstream consumers building chat UIs on top of acpx can't render a live context-window bar or detect agent-advertised slash commands today, because the runtime drops the relevant data on the floor between the wire payload and the public event/status surfaces.

  • usage_update: ACP carries cost, plus a per-turn token breakdown under _meta.usage (Claude Code populates this; Codex partially does). The runtime currently keeps only used and size.
  • available_commands_update: ACP carries AvailableCommand[] with name/description/input. The runtime currently emits a one-line summary string and discards the list.
  • getStatus(): the session reducer already persists cumulative_token_usage, request_token_usage, and acpx.available_commands onto the record, but the public AcpRuntimeStatus shape doesn't expose any of them.

This PR plumbs all three through.

What changed

src/runtime/public/contract.ts

New types:

  • AcpRuntimeUsageCost = { amount?, currency? }
  • AcpRuntimeUsageBreakdown = { inputTokens?, outputTokens?, cachedReadTokens?, cachedWriteTokens?, thoughtTokens?, totalTokens? }
  • AcpRuntimeAvailableCommand = { name, description?, hasInput }
  • AcpRuntimeSessionUsage = { cumulative?, perRequest? }

Extends the status variant of AcpRuntimeEvent with optional cost, breakdown, availableCommands. Extends AcpRuntimeStatus with optional usage, availableCommands.

src/runtime/public/events.ts

  • usageUpdateEvent now reads payload.cost and payload._meta.usage defensively, normalizes both, and forwards them on the event. Both fields are optional and absent for adapters (e.g. gemini-cli today) that don't report them.
  • New availableCommandsUpdateEvent replaces the previous one-line-summary mapping. Normalizes each entry into { name, description?, hasInput }, dropping entries that lack a usable name. The wire input payload (an AvailableCommandInput schema) is intentionally collapsed into the hasInput boolean — picker UIs only need the binary "does it want an argument?" signal, and we don't want to lock in the input schema here.

src/runtime/engine/manager.ts

  • getStatus() now includes usage and availableCommands when the persisted record carries the underlying data. The session reducer already stashes both, so no reducer changes are needed.
  • New helpers tokenUsageToBreakdown, buildUsageField, buildAvailableCommandsField next to the existing buildModelsField.

The persisted record format (SessionTokenUsage uses snake_case + Claude-style key names; the reducer at conversation-model.ts:421 only retains 4 of the 6 SDK token fields) is preserved as-is. tokenUsageToBreakdown maps:

persisted (snake_case) runtime (camelCase)
input_tokens inputTokens
output_tokens outputTokens
cache_read_input_tokens cachedReadTokens
cache_creation_input_tokens cachedWriteTokens

thoughtTokens and totalTokens aren't persisted today (only seen on live events from _meta.usage). Live events from the new event path carry the full 6-field shape; status reads from the persisted record carry the 4-field subset. The asymmetry is documented in the type doc-comments.

buildAvailableCommandsField reads names from record.acpx.available_commands (which the reducer persists as string[]) and surfaces them as { name, hasInput: false }. Live events from the new event path carry the richer { name, description, hasInput } shape. Same asymmetry, same reason — kept the reducer's persisted shape untouched to avoid a session-record migration.

Tests

  • test/runtime-events.test.ts — new tests for usage_update with cost + _meta.usage round-trip, partial-cost handling, _meta without a usage record being ignored, and availableCommands enrichment (description, hasInput flag, dropped invalid entries). Existing tests updated to feed the realistic object form (the old test fed bare strings — non-spec).
  • test/runtime-manager.test.ts — new tests covering getStatus() populating both fields when the record carries them, and omitting both when the record is empty.

CHANGELOG.md

Three bullets under "Unreleased / Changes". No breaking entries.

Test plan

  • pnpm typecheck clean.
  • pnpm lint clean.
  • pnpm format:check clean (against tracked files; the coverage/ and reports/ artifacts that pnpm check produces are pre-existing repo behavior, not from this PR).
  • pnpm test — 734 / 734 pass, 0 fail.
  • pnpm check (format → typecheck → lint → build → viewer:typecheck → viewer:build → test:coverage → mutate) runs end-to-end with mutation score 91.07 ≥ 80 threshold.

Compatibility

  • All-additive. Every new field on the public contract is optional. Existing consumers that read only used / size from usage_update, or read only the existing fields on AcpRuntimeStatus, continue to work unchanged.
  • The text payload on the available_commands_update event changes from "available commands updated (N)" (or "available commands updated" for empty/missing list) to always include a count — "available commands updated (N)" with N >= 0. The two test cases that pinned the old text have been updated.
  • Persisted record schema unchanged.

Out of scope (deliberate)

  • The AvailableCommandInput schema isn't plumbed through — we only surface hasInput: boolean. If/when picker UIs need typed input args, that's a separate addition.
  • Compaction itself is intentionally not added to the runtime. Compaction stays client-initiated as a regular slash-command prompt — the agent (Claude Code / Codex) interprets it on its side; the runtime stays out of the way. Downstream consumers can build a compact() convenience on top of the new event channel by sending the agent's reported /compact name as a startTurn text.
  • The session reducer continues to persist only command names (not descriptions or hasInput). That's why getStatus().availableCommands carries description = undefined, hasInput = false for entries sourced from the persisted record, while live events from the wire carry the full data. Migrating the persisted shape is a follow-up if downstream consumers need historical detail.
Real-agent verification (click to expand)

What was tested

A minimal harness that exercises every new surface this PR adds and
dumps the result as JSON. The full script is reproducible from a clean
checkout of this branch with pnpm install && pnpm build, then node proof.mjs with the file below.

// proof.mjs — verifies the new fields end-to-end against any
// ACP-compatible agent the runtime's built-in registry knows about.
// Change the `agent` value below to point at a different adapter.
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import {
  createAcpRuntime,
  createAgentRegistry,
  createFileSessionStore,
} from "./dist/runtime.js";

const stateDir = mkdtempSync(join(tmpdir(), "acpx-proof-"));
const cwd = mkdtempSync(join(tmpdir(), "acpx-proof-cwd-"));

const runtime = createAcpRuntime({
  cwd,
  sessionStore: createFileSessionStore({ stateDir }),
  agentRegistry: createAgentRegistry(),
  permissionMode: "approve-reads",
  nonInteractivePermissions: "deny",
  timeoutMs: 120_000,
});

const events = [];
try {
  const handle = await runtime.ensureSession({
    sessionKey: "proof",
    agent: "codex", // change to "claude" or "gemini" to exercise other adapters
    mode: "persistent",
    cwd,
  });
  const turn = runtime.startTurn({
    handle,
    text: "Respond with exactly the word 'pong' and nothing else.",
    mode: "prompt",
    requestId: "proof-req-1",
    timeoutMs: 120_000,
  });
  for await (const ev of turn.events) events.push(ev);
  const result = await turn.result;
  const status = await runtime.getStatus({ handle });

  const usage = events.filter((e) => e.type === "status" && e.tag === "usage_update");
  const cmds = events.filter((e) => e.type === "status" && e.tag === "available_commands_update");

  console.log(JSON.stringify({
    turnResult: result,
    usageUpdateEventCount: usage.length,
    usageUpdateEventFirst: usage[0],
    availableCommandsUpdateEventCount: cmds.length,
    availableCommandsUpdateEvents: cmds,
    getStatusResponse: status,
  }, null, 2));

  try { await runtime.close({ handle, reason: "proof done" }); } catch {}
} finally {
  rmSync(stateDir, { recursive: true, force: true });
  rmSync(cwd, { recursive: true, force: true });
}

Captured output (codex, redacted)

Ran against npx -y @agentclientprotocol/codex-acp@^0.0.44
(resolved by the runtime's built-in registry under agent: "codex"),
local codex CLI authenticated via ChatGPT. Session UUIDs, pids,
tmpdir paths, and locally-installed skill names have been redacted;
the four codex built-in commands (mcp, skills, status, logout)
are kept verbatim as they are part of codex's public command surface.

{
  "turnResult": { "status": "completed", "stopReason": "end_turn" },
  "usageUpdateEventCount": 1,
  "usageUpdateEventFirst": {
    "type": "status",
    "text": "usage updated: 19985/258400",
    "tag": "usage_update",
    "used": 19985,
    "size": 258400
  },
  "availableCommandsUpdateEventCount": 1,
  "availableCommandsUpdateEvents": [
    {
      "type": "status",
      "text": "available commands updated (38)",
      "tag": "available_commands_update",
      "availableCommands": [
        { "name": "mcp",    "description": "List configured Model Context Protocol (MCP) tools.", "hasInput": false },
        { "name": "skills", "description": "List available skills.",                              "hasInput": false },
        { "name": "status", "description": "Display session configuration and token usage.",      "hasInput": false },
        { "name": "logout", "description": "Sign out of Codex...",                                "hasInput": false },
        { "name": "$<redacted-local-skill>", "description": "<truncated>", "hasInput": false },
        { "name": "$<redacted-local-skill>", "description": "<truncated>", "hasInput": false },
        { "_redacted": "32 additional locally-installed skills omitted" }
      ]
    }
  ],
  "getStatusResponse": {
    "summary": "session=proof backendSessionId=<redacted> pid=<redacted> open",
    "models": {
      "currentModelId": "gpt-5.5[medium]",
      "availableModelIds": [
        "gpt-5.5[low]", "gpt-5.5[medium]", "gpt-5.5[high]", "gpt-5.5[xhigh]",
        "gpt-5.4[low]", "gpt-5.4[medium]", "gpt-5.4[high]", "gpt-5.4[xhigh]",
        "gpt-5.4-mini[low]", "...", "gpt-5.2[xhigh]"
      ]
    },
    "availableCommands": [
      { "name": "mcp",    "hasInput": false },
      { "name": "skills", "hasInput": false },
      { "name": "status", "hasInput": false },
      { "name": "logout", "hasInput": false },
      { "_redacted": "34 locally-installed skills omitted" }
    ],
    "details": { "cwd": "<redacted-tmpdir>", "lastUsedAt": "...", "closed": false }
  }
}

What this validates

New surface Codex result Verdict
available_commands_update.availableCommands rich list (the previously-dropped field) 38 entries, full { name, description, hasInput } ✅ end-to-end wire-to-runtime plumbing works
AcpRuntimeStatus.availableCommands on getStatus() 38 entries from persisted record, degraded to { name, hasInput: false } as the reducer only persists names ✅ matches the documented behavior
usage_update.used / usage_update.size (preserved) 19985 / 258400 ✅ no regression on the existing fields
Legacy available_commands_update fallback text when list is empty n/a in this capture (codex sends a non-empty list); covered by unit test parsePromptEventLine covers status and tool summary fallbacks
usage_update.cost absent from this codex run — adapter doesn't emit it ✅ normalizer defensively omits the field; used/size-only consumers see no change
usage_update.breakdown absent from this codex run — codex doesn't populate _meta.usage ✅ same defensive-omit; unit test parsePromptEventLine surfaces cost and _meta.usage breakdown on usage_update covers the populated case
AcpRuntimeStatus.usage absent because the reducer had no _meta.usage to persist ✅ field omitted cleanly when empty

The two new payload surfaces this PR adds (rich availableCommands on
the event and on getStatus()) both round-trip correctly against a
real codex turn. The two surfaces codex doesn't emit (cost,
breakdown) demonstrate the normalizer's defensive-omit behavior —
the runtime never fabricates empty objects, so consumers that read
only used/size see byte-identical events to main.

How this generalises to other agents

The harness is agent-neutral — only the agent: "codex" string
changes when pointing at a different adapter. Same script, same
assertions, just a different built-in spawn command resolved by the
agent registry.

  • Claude (@agentclientprotocol/claude-agent-acp) — Claude Code
    populates _meta.usage per-turn, so the same proof against
    agent: "claude" will surface usage_update.breakdown populated
    with inputTokens / outputTokens / cachedReadTokens / cachedWriteTokens / thoughtTokens / totalTokens. The cost field is also expected if
    the adapter emits it. The availableCommands list is shorter
    (Claude Code's command set) but the shape is identical.
  • Gemini (gemini --acp) — gemini-cli today doesn't implement
    available_commands_update or usage_update with rich payloads.
    The runtime correctly emits zero events on those surfaces and
    getStatus().availableCommands / getStatus().usage are both
    omitted. No crash, no synthetic empty payloads.
  • Any future adapter that follows the ACP wire spec for
    UsageUpdate and AvailableCommandsUpdate automatically benefits
    from the same plumbing — the changes are wire-level normalizers,
    not adapter-specific code paths.

Reviewers wanting to verify against a different adapter can drop in
their own agent: string (any name the built-in registry resolves) or
register a custom command via createAgentRegistry({ overrides: { ... } }).

…on status events and getStatus

The ACP wire protocol carries richer context-window and command data
than the runtime currently exposes. Three additive surface changes:

- usage_update events now carry the agent-reported cost and a typed
  per-turn breakdown (input/output/cachedRead/cachedWrite/thought/total
  tokens) normalized from the wire payload's _meta.usage. Previously
  only the top-level used and size numbers survived into AcpRuntimeEvent.
- available_commands_update events now carry the full availableCommands
  list (name, description, hasInput flag) instead of dropping it to a
  one-line summary, so clients can detect /compact, /clear, and similar
  agent-advertised commands.
- AcpRuntimeStatus.usage and AcpRuntimeStatus.availableCommands now
  expose the cumulative + per-request token breakdowns and command list
  that the session reducer already persists onto the record.

Pure addition: every new field on the AcpRuntimeEvent status variant
and on AcpRuntimeStatus is optional. The text payloads on the existing
events are unchanged for the empty / unknown cases, and the persisted
record schema is untouched.

New types: AcpRuntimeUsageCost, AcpRuntimeUsageBreakdown,
AcpRuntimeAvailableCommand, AcpRuntimeSessionUsage.
@DaniAkash DaniAkash requested a review from a team as a code owner May 25, 2026 19:05
@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 25, 2026

Codex review: needs real behavior proof before merge. Reviewed May 26, 2026, 3:13 AM ET / 07:13 UTC.

Summary
The PR adds optional public runtime event/status fields for usage cost, token breakdowns, and available commands, re-exports the new types, and covers the event/status plumbing with tests.

Reproducibility: not applicable. this is an additive feature PR rather than a bug report. Source inspection confirms current main lacks the requested public runtime fields, while the PR body provides partial live-output proof for availableCommands.

Review metrics: 2 noteworthy metrics.

  • Runtime surface added: 4 exported types, 5 optional fields. AGENTS.md treats data models and output shapes as product surface, so the new normalized field names deserve maintainer review before merge.
  • Diff scope: 6 files changed, +444/-4. The branch is focused on runtime contract/event/status plumbing plus tests, with no dependency, workflow, or publishing churn.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦐 gold shrimp
Patch quality: 🐚 platinum hermit
Result: blocked until stronger real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Add redacted terminal or log output from an adapter that emits _meta.usage or cost, showing populated cost/breakdown and getStatus().usage after the change.

Proof guidance:
Needs stronger real behavior proof before merge: The PR body includes redacted live Codex output proving availableCommands on live events and getStatus, but it does not show populated cost, breakdown, or status.usage from a real adapter; terminal output or redacted logs are acceptable, and private paths, tokens, endpoints, and other sensitive details should be redacted before updating the PR body for re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • The real-agent proof demonstrates available command plumbing, but it does not show populated cost, breakdown, or AcpRuntimeStatus.usage from a real ACP adapter.
  • The new cost/breakdown/availableCommands names and hasInput abstraction become exported runtime API surface once merged, so maintainer acceptance of the field shape matters more than CI alone.

Maintainer options:

  1. Decide the mitigation before merge
    Merge the focused runtime plumbing only after maintainers accept the public field shape and either obtain populated real-agent usage proof or explicitly accept unit coverage for adapters the contributor cannot run.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge
Human review should decide the public runtime API shape and whether the remaining usage/cost proof gap needs contributor evidence or an explicit maintainer waiver.

Security
Cleared: The diff touches runtime TypeScript and tests only; it does not change dependencies, workflows, scripts, secrets, install behavior, or publishing metadata.

Review details

Best possible solution:

Merge the focused runtime plumbing only after maintainers accept the public field shape and either obtain populated real-agent usage proof or explicitly accept unit coverage for adapters the contributor cannot run.

Do we have a high-confidence way to reproduce the issue?

Not applicable: this is an additive feature PR rather than a bug report. Source inspection confirms current main lacks the requested public runtime fields, while the PR body provides partial live-output proof for availableCommands.

Is this the best way to solve the issue?

Unclear: the patch is a narrow way to preserve structured ACP data for downstream consumers, but the normalized public field names and hasInput abstraction need maintainer acceptance before they become stable API.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against fea7ee6e1456.

Label changes

Label justifications:

  • P2: This is a normal-priority runtime API improvement with limited blast radius but real downstream value for ACP UI consumers.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body includes redacted live Codex output proving availableCommands on live events and getStatus, but it does not show populated cost, breakdown, or status.usage from a real adapter; terminal output or redacted logs are acceptable, and private paths, tokens, endpoints, and other sensitive details should be redacted before updating the PR body for re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

What I checked:

  • Repository policy read: AGENTS.md was read fully; its product-direction guidance treats data models and output shapes as long-term product surface, which is relevant because this PR adds public runtime fields and exported types. (AGENTS.md:29, fea7ee6e1456)
  • Current main lacks the new status fields: On current main, AcpRuntimeStatus exposes summary/session/model/details fields only, and the status event variant exposes used/size but no cost, breakdown, usage, or availableCommands surface. (src/runtime/public/contract.ts:91, fea7ee6e1456)
  • Current main drops cost and breakdown on live usage events: usageUpdateEvent on current main reads only used and size and returns only those two structured values, so the PR is not redundant with main. (src/runtime/public/events.ts:447, fea7ee6e1456)
  • Current reducer persists data that getStatus could expose: The reducer already maps usage metadata into cumulative/request token usage and stores available command names, matching the PR's getStatus source data. (src/session/conversation-model.ts:421, fea7ee6e1456)
  • PR diff adds focused runtime contract and plumbing: The head diff adds four exported runtime types, optional usage/availableCommands/cost/breakdown fields, event normalizers, getStatus builders, and runtime tests without dependency or workflow changes. (src/runtime/public/contract.ts:88, 04207620f2b7)
  • Real behavior proof is partial: The PR body's redacted Codex output shows live availableCommands on events and getStatus, but the captured usage_update lacks cost/breakdown and getStatus lacks usage because that adapter did not emit _meta.usage or cost. (04207620f2b7)

Likely related people:

  • DaniAkash: Prior merged runtime public-surface work added getStatus model exposure and permission callback types in the same contract/manager area this PR extends, beyond authorship of this PR. (role: recent area contributor; confidence: high; commits: b76a80bf9fe9, 6a609164fc37; files: src/runtime/public/contract.ts, src/runtime/engine/manager.ts, test/runtime-manager.test.ts)
  • osolmaz: Runtime embedding and prompt-turn stabilization history introduced the central public contract, event parser, manager, and tests touched here. (role: introduced runtime API surface; confidence: high; commits: be510ba918d4, a983e63abfa9; files: src/runtime/public/contract.ts, src/runtime/public/events.ts, src/runtime/engine/manager.ts)
  • enki: Turn-handle work is adjacent to the live runtime event stream and public runtime contract this PR extends. (role: adjacent runtime contributor; confidence: medium; commits: 475a767169cb; files: src/runtime/public/contract.ts, src/runtime/engine/manager.ts)
  • Peter Steinberger: Local blame on the shallow checkout points the current runtime files at the v0.9.0 release commit, and prior runtime work shows co-authored/release involvement in the same public surface area. (role: recent release and adjacent area contributor; confidence: medium; commits: 00e4c9452290, 6a609164fc37; files: src/runtime/public/contract.ts, src/runtime/public/events.ts, src/runtime/engine/manager.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels May 25, 2026
@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 25, 2026

ClawSweeper PR egg

🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat.

Where did the egg go?
  • The egg game starts only after the PR passes the real-behavior proof check.
  • Before that, no creature or rarity is rolled. The treat waits for real proof.
  • This is still just collectible flavor: proof affects review readiness, not creature quality.

… and drop CHANGELOG edit

Two follow-ups from ClawSweeper's review:

- Restore the legacy 'available commands updated' (no count) text when the
  wire list is missing or empty. The structured availableCommands: [] field
  is still attached either way, so text-matching consumers see no change
  while structured consumers still get the new field.
- Revert the direct CHANGELOG.md edit. Feature PRs in this repo leave
  release-note authoring to the release commit by convention.
@clawsweeper clawsweeper Bot added the P2 Normal priority bug or improvement with limited blast radius. label May 26, 2026
@DaniAkash
Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Added a folded "Real-agent verification" section to the PR description with the harness script, redacted codex output, and a field-by-field validation matrix covering each new surface and how it generalises to other adapters.

@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 26, 2026

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels May 26, 2026
Add AcpRuntimeAvailableCommand, AcpRuntimeUsageBreakdown,
AcpRuntimeUsageCost, and AcpRuntimeSessionUsage to the export type {}
block in src/runtime.ts so downstream consumers can reach them via
'acpx/runtime' alongside the existing types. Without this they were
declared in contract.ts but only reachable via the deeper
'acpx/runtime/public/contract' import path.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Normal priority bug or improvement with limited blast radius. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant