Skip to content

feat(agents): add prompt cache break diagnostics#60707

Merged
vincentkoc merged 8 commits into
mainfrom
pr-kv-observability
Apr 4, 2026
Merged

feat(agents): add prompt cache break diagnostics#60707
vincentkoc merged 8 commits into
mainfrom
pr-kv-observability

Conversation

@vincentkoc

@vincentkoc vincentkoc commented Apr 4, 2026

Copy link
Copy Markdown
Member

Summary

  • Problem: the cache-boundary correctness fixes removed the obvious prompt leaks, but we still had weak observability when cache reuse dropped on embedded-runner turns.
  • Why it matters: without a cache-state diff, live KV regressions look like provider flakiness and are hard to localize to system prompt, tools, transport, or cache-retention changes.
  • What changed: add embedded-runner prompt-cache diagnostics that fingerprint cache-relevant state, compare it turn-to-turn, emit structured cache-trace/result data, wire the live cache suite to assert those trace stages for runner-path scenarios, and expose per-session cache reuse in status --verbose.
  • What did NOT change (scope boundary): no provider payload semantics, no new cache policy, no default TUI/chat noise, and no live cache behavior changes outside test diagnostics/assertions.

Change Type (select all)

  • Feature
  • Bug fix
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Auth / tokens
  • Skills / tool execution
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause (if applicable)

  • Root cause: N/A
  • Missing detection / guardrail: we had transport correctness tests, but no runner-level diffing of cache-relevant inputs against subsequent cache-read behavior, and the live cache suite did not verify diagnostic output.
  • Contributing context (if known): the recent cache-boundary rollout increased the importance of knowing when reuse drops because the remaining gaps are now mostly path divergence or prompt/tool churn, not obvious marker leaks.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file:
    • src/agents/pi-embedded-runner/prompt-cache-observability.test.ts
    • src/agents/cache-trace.test.ts
    • src/agents/pi-embedded-runner.cache.live.test.ts
    • src/commands/status.format.test.ts
    • src/commands/status.test.ts
  • Scenario the test should lock in: stable turns establish a baseline, cache-relevant diffs are captured, a later large cache-read drop produces a structured cache-break result with human-readable causes, live embedded-runner cache probes emit cache:state plus cache:result trace entries, and status --verbose renders an explicit cache-reuse summary for recent sessions.
  • Why this is the smallest reliable guardrail: the diffing logic is pure state tracking, so isolated tests are fastest for correctness; the live suite is the right place to prove the trace wiring on real runner paths; the status formatter test keeps the operator-facing cache math stable without depending on the heavier status command stack.
  • Existing test that already covers this (if any): none
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • status --verbose now shows a per-session cache line in the Sessions table, for example 40% hit · read 2.0k · write 1.0k.
  • Default status output, TUI, and chat surfaces stay unchanged.
  • Root-cause cache-break diagnostics still require cache tracing or debug logging.

Diagram (if applicable)

Before:
[embedded turn] -> [provider call] -> [cache read drops] -> [little local signal]

After:
[embedded turn] -> [snapshot cache-relevant state]
               -> [provider call]
               -> [compare cache read vs prior turn]
               -> [trace/log exact changed inputs]
               -> [live suite asserts trace stages]
               -> [status --verbose shows cache reuse]

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) No
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22 / pnpm / Vitest
  • Model/provider: N/A
  • Integration/channel (if any): embedded runner
  • Relevant config (redacted): optional existing OPENCLAW_CACHE_TRACE / debug logging only; live suite now self-configures cache trace env vars into a temp file

Steps

  1. Run two embedded turns with the same session and enable cache tracing or debug logs.
  2. Change a cache-relevant input such as system prompt, tool set, transport, or cache retention.
  3. Observe the trace/log output after the next turn.
  4. Run openclaw status --verbose to inspect session-level cache reuse.
  5. Run the live cache suite later with OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 to verify runner-path cache behavior and emitted trace stages together.

Expected

  • A structured cache-state snapshot is recorded before the turn.
  • Every traced runner turn records a cache:result stage.
  • A later material cache-read drop reports the tracked changes that likely caused it.
  • status --verbose renders explicit cache reuse for recent sessions.

Actual

  • Pending review.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios:
    • pnpm exec vitest run --config vitest.config.ts --maxWorkers=1 src/agents/pi-embedded-runner/prompt-cache-observability.test.ts
    • pnpm exec vitest run --config vitest.config.ts --maxWorkers=1 src/agents/cache-trace.test.ts
    • pnpm exec vitest run --config vitest.config.ts --maxWorkers=1 src/commands/status.format.test.ts
    • git diff --check
  • Edge cases checked:
    • first turn establishes baseline without false positive
    • small cache-read drops do not emit a break result
    • tool-name collection ignores blank/missing names
    • traced stable turns still record a cache:result event
    • verbose status cache math stays aligned with the existing compact token suffix math
  • What you did not verify:
    • live KV tests
    • full pnpm build green state, because latest origin/main currently fails in unrelated src/agents/openai-ws-stream.ts
    • full attempt.test.ts, which remains non-reporting in this environment
    • src/commands/status.test.ts, which remains blocked here by the existing telegram command config contract surface is unavailable failure in the branch test stack
    • live-suite execution itself; only the wiring was updated

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes/No) Yes
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) No
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: cache-break warnings could be noisy if the thresholds are too sensitive for some providers.
    • Mitigation: diagnostics only run when cache tracing or debug logging is enabled, and the detector requires both a relative and absolute cache-read drop.
  • Risk: embedded-runner cache snapshots could miss a provider-specific cache input not modeled here.
    • Mitigation: the snapshot fields are explicit and testable, and the trace output makes gaps obvious for the next refinement.
  • Risk: live-suite trace assertions could become flaky if trace stage names churn.
    • Mitigation: the assertions only check the two stable stages needed for this feature: cache:state and cache:result.
  • Risk: explicit cache reuse in status --verbose could drift from the token suffix math over time.
    • Mitigation: both now share the same cache math helper, and src/commands/status.format.test.ts locks that in.

AI-assisted: yes.
Testing degree: lightly tested plus targeted unit coverage; live wiring added but not executed.

@vincentkoc vincentkoc self-assigned this Apr 4, 2026
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: L maintainer Maintainer-authored PR commands Command implementations labels Apr 4, 2026
@vincentkoc
vincentkoc marked this pull request as ready for review April 4, 2026 06:33

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1521eb2ac7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/pi-embedded-runner/prompt-cache-observability.ts Outdated
@greptile-apps

greptile-apps Bot commented Apr 4, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds embedded-runner prompt-cache diagnostics: a beginPromptCacheObservation/completePromptCacheObservation pair that fingerprints cache-relevant inputs (model, transport, system prompt, tool set) each turn, diffs them against the prior turn, and emits structured warnings and optional JSONL trace events when a material cache-read drop is detected. A new Cache column in status --verbose surfaces per-session cache reuse, sharing the same resolvePromptCacheStats helper now used by both the compact token suffix and the verbose column. Coverage is solid: isolated unit tests for the diffing and formatting logic, and live-suite wiring for the runner-path trace stages.

All findings are P2 (quality/robustness): the module-level trackers map grows unboundedly over the lifetime of a long-running gateway process; stableStringify uses a visited-set rather than a path-set for cycle detection, so diamond-shared objects produce a \"[Circular]\" digest rather than their actual value; and toolDigest is order-sensitive in a way that could trigger spurious change events if tool registration order varies.

Confidence Score: 5/5

Safe to merge — all findings are P2 style/robustness suggestions with no present runtime defects.

No P0 or P1 issues found. The three P2 comments (unbounded tracker map, diamond-ref digest, order-sensitive tool digest) are quality improvements rather than present bugs; the feature is opt-in (disabled unless OPENCLAW_CACHE_TRACE or debug logging is active), so the impact of the identified issues is further contained.

src/agents/pi-embedded-runner/prompt-cache-observability.ts (tracker map growth + tool digest ordering) and src/agents/cache-trace.ts (stableStringify cycle detection).

Comments Outside Diff (1)

  1. src/agents/cache-trace.ts, line 109-158 (link)

    P2 seen WeakSet is a visited set, not a path set — diamond refs become "[Circular]"

    The seen WeakSet accumulates every object visited during the entire traversal. If the same object appears at two different paths (a "diamond" reference — common with shared tool or model config objects), the second occurrence is serialised as "[Circular]" even though there is no actual cycle. This makes the resulting digest stable but not representative of the actual value, so two structurally identical inputs that differ only in whether a shared sub-object was seen earlier will produce the same fingerprint whether or not they should.

    For the cache-break detection use case this means a false match (no detected change) rather than a false alarm, so it's unlikely to cause user-visible noise; but it does silently degrade fingerprint fidelity for payloads with shared objects. A standard path-tracking approach (pass seen down, remove on return) would catch true cycles only.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: src/agents/cache-trace.ts
    Line: 109-158
    
    Comment:
    **`seen` WeakSet is a visited set, not a path set — diamond refs become `"[Circular]"`**
    
    The `seen` WeakSet accumulates every object visited during the entire traversal. If the same object appears at two different paths (a "diamond" reference — common with shared tool or model config objects), the second occurrence is serialised as `"[Circular]"` even though there is no actual cycle. This makes the resulting digest stable but not representative of the actual value, so two structurally identical inputs that differ only in whether a shared sub-object was seen earlier will produce the same fingerprint whether or not they should.
    
    For the cache-break detection use case this means a false match (no detected change) rather than a false alarm, so it's unlikely to cause user-visible noise; but it does silently degrade fingerprint fidelity for payloads with shared objects. A standard path-tracking approach (pass `seen` down, remove on return) would catch true cycles only.
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/prompt-cache-observability.ts
Line: 48

Comment:
**Unbounded module-level tracker map**

`trackers` is never pruned. In long-running gateway processes that serve many distinct sessions, an entry is added (and never removed) for every unique `sessionKey`/`sessionId` string the runner sees. The CLAUDE.md prompt-cache guidelines call out correctness/perf-critical treatment for state that can grow without bound.

Consider a `WeakMap` keyed by a shared session object, or a bounded LRU eviction (e.g., remove the oldest entry when the map exceeds a soft cap), or at minimum a comment explaining why growth is expected to remain bounded for this deployment model.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/agents/cache-trace.ts
Line: 109-158

Comment:
**`seen` WeakSet is a visited set, not a path set — diamond refs become `"[Circular]"`**

The `seen` WeakSet accumulates every object visited during the entire traversal. If the same object appears at two different paths (a "diamond" reference — common with shared tool or model config objects), the second occurrence is serialised as `"[Circular]"` even though there is no actual cycle. This makes the resulting digest stable but not representative of the actual value, so two structurally identical inputs that differ only in whether a shared sub-object was seen earlier will produce the same fingerprint whether or not they should.

For the cache-break detection use case this means a false match (no detected change) rather than a false alarm, so it's unlikely to cause user-visible noise; but it does silently degrade fingerprint fidelity for payloads with shared objects. A standard path-tracking approach (pass `seen` down, remove on return) would catch true cycles only.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/prompt-cache-observability.ts
Line: 140

Comment:
**`toolDigest` is sensitive to tool registration order**

`digestText(JSON.stringify(params.toolNames))` is order-dependent. `promptCacheToolNames` is built from `[...builtInTools, ...allCustomTools]`, so if either list's iteration order varies between turns (e.g., after a plugin reload or if custom tools arrive from a non-deterministic source), the digest will change and trigger a false "tools changed" cache-break entry, even when the actual tool set is identical.

Sorting the names before hashing would make the digest set-stable:
```suggestion
    toolDigest: digestText(JSON.stringify([...params.toolNames].sort())),
```
Only do this if tool order is genuinely not cache-relevant for any supported provider; if providers like Anthropic or OpenAI cache the tool list positionally, keep the current order-sensitive behaviour and add a comment explaining it.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "feat(status): show cache reuse in verbos..." | Re-trigger Greptile

pendingChanges: PromptCacheChange[] | null;
};

const trackers = new Map<string, PromptCacheTracker>();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Unbounded module-level tracker map

trackers is never pruned. In long-running gateway processes that serve many distinct sessions, an entry is added (and never removed) for every unique sessionKey/sessionId string the runner sees. The CLAUDE.md prompt-cache guidelines call out correctness/perf-critical treatment for state that can grow without bound.

Consider a WeakMap keyed by a shared session object, or a bounded LRU eviction (e.g., remove the oldest entry when the map exceeds a soft cap), or at minimum a comment explaining why growth is expected to remain bounded for this deployment model.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/prompt-cache-observability.ts
Line: 48

Comment:
**Unbounded module-level tracker map**

`trackers` is never pruned. In long-running gateway processes that serve many distinct sessions, an entry is added (and never removed) for every unique `sessionKey`/`sessionId` string the runner sees. The CLAUDE.md prompt-cache guidelines call out correctness/perf-critical treatment for state that can grow without bound.

Consider a `WeakMap` keyed by a shared session object, or a bounded LRU eviction (e.g., remove the oldest entry when the map exceeds a soft cap), or at minimum a comment explaining why growth is expected to remain bounded for this deployment model.

How can I resolve this? If you propose a fix, please make it concise.

streamStrategy: params.streamStrategy,
transport: params.transport,
systemPromptDigest: digestText(params.systemPrompt),
toolDigest: digestText(JSON.stringify(params.toolNames)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 toolDigest is sensitive to tool registration order

digestText(JSON.stringify(params.toolNames)) is order-dependent. promptCacheToolNames is built from [...builtInTools, ...allCustomTools], so if either list's iteration order varies between turns (e.g., after a plugin reload or if custom tools arrive from a non-deterministic source), the digest will change and trigger a false "tools changed" cache-break entry, even when the actual tool set is identical.

Sorting the names before hashing would make the digest set-stable:

Suggested change
toolDigest: digestText(JSON.stringify(params.toolNames)),
toolDigest: digestText(JSON.stringify([...params.toolNames].sort())),

Only do this if tool order is genuinely not cache-relevant for any supported provider; if providers like Anthropic or OpenAI cache the tool list positionally, keep the current order-sensitive behaviour and add a comment explaining it.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/prompt-cache-observability.ts
Line: 140

Comment:
**`toolDigest` is sensitive to tool registration order**

`digestText(JSON.stringify(params.toolNames))` is order-dependent. `promptCacheToolNames` is built from `[...builtInTools, ...allCustomTools]`, so if either list's iteration order varies between turns (e.g., after a plugin reload or if custom tools arrive from a non-deterministic source), the digest will change and trigger a false "tools changed" cache-break entry, even when the actual tool set is identical.

Sorting the names before hashing would make the digest set-stable:
```suggestion
    toolDigest: digestText(JSON.stringify([...params.toolNames].sort())),
```
Only do this if tool order is genuinely not cache-relevant for any supported provider; if providers like Anthropic or OpenAI cache the tool list positionally, keep the current order-sensitive behaviour and add a comment explaining it.

How can I resolve this? If you propose a fix, please make it concise.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 054e072f44

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 114 to +116
function resolveProviderBaseUrl(model: LiveResolvedModel["model"]): string | undefined {
const candidate = (model as { baseUrl?: unknown }).baseUrl;
return typeof candidate === "string" && candidate.trim().length > 0 ? candidate : undefined;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Close resolveProviderBaseUrl before cache-trace helpers

This change drops the original return ... and closing brace in resolveProviderBaseUrl(model), so subsequent helper declarations are parsed inside that function and the file terminates with a '}' expected parse error. In this state src/agents/pi-embedded-runner.cache.live.test.ts cannot be parsed/executed, which breaks the live cache test path before any of the new assertions can run.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 25f6c89a14

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +141 to +142
function resolveProviderBaseUrl(fixture: LiveResolvedModel): string | undefined {
return resolveProviderBaseUrl(fixture.model);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid shadowing resolveProviderBaseUrl with self-calling overload

The second resolveProviderBaseUrl declaration shadows the earlier implementation and then calls resolveProviderBaseUrl(fixture.model), so calls that pass a model (for example in buildEmbeddedRunnerConfig) no longer hit the model-based resolver and instead recurse into the shadowed function until it dereferences fixture.model on undefined and throws. This breaks live cache probe config assembly as soon as this helper is invoked.

Useful? React with 👍 / 👎.

@vincentkoc
vincentkoc merged commit c76646a into main Apr 4, 2026
9 checks passed
@vincentkoc
vincentkoc deleted the pr-kv-observability branch April 4, 2026 07:29

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 42791bee7d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (!liveCacheTraceFile) {
throw new Error("live cache trace file not initialized");
}
const raw = await fs.readFile(liveCacheTraceFile, "utf8").catch(() => "");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Wait for queued trace writes before asserting cache stages

readCacheTraceEvents reads the trace file once immediately, but cache-trace events are appended through the queued writer asynchronously, so the last cache:state/cache:result lines may still be in flight right after a run completes. In live CI (slow disk or busy workers), this creates nondeterministic failures where the stage assertion races the writer; add a short retry/poll (or flush hook) before asserting stage presence.

Useful? React with 👍 / 👎.

cacheTrace.recordStage("cache:result", {
note: "state changed without a cache-read break",
options: {
cacheRead: attemptUsage?.cacheRead ?? 0,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve missing usage in cache-result diagnostics

When a turn ends without usage metadata (getUsageTotals() can be undefined on abort/error), this code records cacheRead as 0, which makes trace output look like a hard cache miss rather than “no measurement.” That can mislead cache-break investigations, especially because this feature is intended for root-cause diagnostics; omit cacheRead when usage is absent or emit an explicit no-usage marker instead of coercing to zero.

Useful? React with 👍 / 👎.

KimGLee pushed a commit to KimGLee/openclaw that referenced this pull request Apr 4, 2026
* feat(agents): add prompt cache break diagnostics

* test(agents): wire cache trace into live cache suite

* fix(agents): always record cache trace result stage

* feat(status): show cache reuse in verbose output

* fix(agents): ignore missing prompt cache usage

* chore(changelog): note prompt cache diagnostics

* fix(agents): harden prompt cache diagnostics
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
* feat(agents): add prompt cache break diagnostics

* test(agents): wire cache trace into live cache suite

* fix(agents): always record cache trace result stage

* feat(status): show cache reuse in verbose output

* fix(agents): ignore missing prompt cache usage

* chore(changelog): note prompt cache diagnostics

* fix(agents): harden prompt cache diagnostics
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
* feat(agents): add prompt cache break diagnostics

* test(agents): wire cache trace into live cache suite

* fix(agents): always record cache trace result stage

* feat(status): show cache reuse in verbose output

* fix(agents): ignore missing prompt cache usage

* chore(changelog): note prompt cache diagnostics

* fix(agents): harden prompt cache diagnostics
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
* feat(agents): add prompt cache break diagnostics

* test(agents): wire cache trace into live cache suite

* fix(agents): always record cache trace result stage

* feat(status): show cache reuse in verbose output

* fix(agents): ignore missing prompt cache usage

* chore(changelog): note prompt cache diagnostics

* fix(agents): harden prompt cache diagnostics
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
* feat(agents): add prompt cache break diagnostics

* test(agents): wire cache trace into live cache suite

* fix(agents): always record cache trace result stage

* feat(status): show cache reuse in verbose output

* fix(agents): ignore missing prompt cache usage

* chore(changelog): note prompt cache diagnostics

* fix(agents): harden prompt cache diagnostics
Nachx639 pushed a commit to Nachx639/clawdbot that referenced this pull request Jun 17, 2026
* feat(agents): add prompt cache break diagnostics

* test(agents): wire cache trace into live cache suite

* fix(agents): always record cache trace result stage

* feat(status): show cache reuse in verbose output

* fix(agents): ignore missing prompt cache usage

* chore(changelog): note prompt cache diagnostics

* fix(agents): harden prompt cache diagnostics
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling commands Command implementations maintainer Maintainer-authored PR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant