Skip to content

fix(compaction): restore session invariants across compaction and reset#69270

Closed
de1tydev wants to merge 21 commits into
openclaw:mainfrom
de1tydev:fix/hook-message-provider-context
Closed

fix(compaction): restore session invariants across compaction and reset#69270
de1tydev wants to merge 21 commits into
openclaw:mainfrom
de1tydev:fix/hook-message-provider-context

Conversation

@de1tydev

@de1tydev de1tydev commented Apr 20, 2026

Copy link
Copy Markdown

Summary

Restore session invariants across compaction and reset instead of patching each symptom in isolation.

This coordinated fix now covers four connected paths:

  • subscribe-time before_compaction / after_compaction hook context
  • engine-owned compaction hook context in compact.queued.ts
  • command /new / /reset hook context in emitResetCommandHooks
  • gateway sessions.reset hook context in emitGatewayBeforeResetPluginHook

It also fixes compaction bookkeeping so zero-token outcomes reset cached usage instead of leaving the session in a repeated safeguard loop.

What changed

  • introduced a shared hook-message-provider resolver so compaction/reset hooks all use the same rules
  • normalized explicit providers before emitting hook context, so values like Telegram become telegram
  • inferred providers from session keys only for real deliverable channel-scoped keys
  • kept non-channel keys such as agent:main:direct:peer_123 unresolved instead of emitting fake providers
  • reset totalTokens / totalTokensFresh / estimatedCostUsd from compaction results even when tokensAfter === 0
  • extended regression coverage for mixed-case reset channels, normalized compaction hook providers, zero-token compactions, and gateway/manual compaction bookkeeping

Why

These reports all describe the same broader failure mode: compaction/reset code paths were not preserving the session invariants downstream systems rely on.

That surfaced as different user-visible bugs:

  • hook consumers could see missing or non-canonical messageProvider values and split one real conversation into multiple logical sessions
  • compaction could clear the transcript but leave stale token/cost accounting behind, causing repeated safeguard loops

Issues

Fixes #69269
Fixes #69286

Also addresses the duplicate token-accounting report in #69287.
Related cluster: #69202.

Tests

  • pnpm build
  • pnpm check
  • pnpm exec vitest run src/auto-reply/reply/commands-core.test.ts src/agents/pi-embedded-subscribe.handlers.compaction.test.ts src/auto-reply/reply/reply-state.test.ts src/gateway/server.sessions.gateway-server-sessions-a.test.ts

Real behavior proof

  • Behavior or issue addressed: reset/compaction hook provider context now resolves real channel-scoped Feishu session keys, does not invent a provider for non-channel direct keys, and normalizes explicit mixed-case providers.
  • Real environment tested: local OpenClaw source checkout at commit c59b756 on Debian 12, Node v25.9.0, using the patched production resolver module via node --import tsx.
  • Exact steps or command run after this patch:
node --import tsx <<'EOF'
import { resolveHookMessageProvider } from './src/utils/hook-message-provider.ts';
const cases = [
  { label: 'channel scoped Feishu reset/compaction session', sessionKey: 'agent:main:feishu:default:direct:ou_testuser' },
  { label: 'legacy non-channel direct session', sessionKey: 'agent:main:direct:peer_123' },
  { label: 'explicit mixed-case provider from hook caller', sessionKey: 'agent:main:main', provider: 'Telegram' },
];
for (const item of cases) {
  console.log(`${item.label}: ${JSON.stringify({ sessionKey: item.sessionKey, provider: item.provider, resolved: resolveHookMessageProvider(item) })}`);
}
EOF
  • Evidence after fix: terminal output from the patched checkout:
channel scoped Feishu reset/compaction session: {"sessionKey":"agent:main:feishu:default:direct:ou_testuser","resolved":"feishu"}
legacy non-channel direct session: {"sessionKey":"agent:main:direct:peer_123"}
explicit mixed-case provider from hook caller: {"sessionKey":"agent:main:main","provider":"Telegram","resolved":"telegram"}
  • Observed result after fix: live output shows channel-scoped reset/compaction keys carry messageProvider: "feishu", legacy non-channel direct keys leave the provider unset, and explicit Telegram is canonicalized to telegram before hook context emission.
  • What was not tested: no browser/mobile UI recording; targeted regression tests cover the gateway reset and compaction RPC paths.

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime agents Agent runtime and tooling size: S labels Apr 20, 2026
@greptile-apps

greptile-apps Bot commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR propagates messageProvider into before_compaction, after_compaction, and before_reset hook contexts across three code paths: the embedded-subscribe compaction handler, the command reset flow, and the gateway sessions.reset path. For the gateway path it adds inferMessageProviderFromSessionKey, which parses canonical session keys and extracts the channel segment.

The fix is correct for the targeted channel-scoped session keys (agent:{id}:feishu:…, agent:{id}:discord:…, etc.). One edge case: per-peer DM keys of the form agent:{id}:direct:{peerId} would yield \"direct\" (a chat-type label, not a channel name) from inferMessageProviderFromSessionKey because \"direct\" is not in the sentinel list — consider adding it alongside \"main\", \"cron\", \"subagent\", and \"acp\".

Confidence Score: 5/5

Safe to merge; the edge case with "direct" keys is P2 and unlikely to affect real deployments materially.

All findings are P2. The core fix is correct and well-tested. The inferMessageProviderFromSessionKey gap is a quality improvement rather than a blocking defect.

src/gateway/session-reset-service.ts — the inferMessageProviderFromSessionKey sentinel list.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/gateway/session-reset-service.ts
Line: 53-63

Comment:
**`inferMessageProviderFromSessionKey` misses non-channel `rest` prefixes**

Session keys built with `dmScope === "per-peer"` use the format `agent:{agentId}:direct:{peerId}`, so `rest.split(":")[0]` yields `"direct"` — a chat-type segment, not a channel name. Since `"direct"` is not in the sentinel list, `normalizeMessageChannel("direct")` is returned as `messageProvider`, giving downstream plugins an incorrect, non-channel value. Similarly, dashboard-scoped keys (`agent:ops:dashboard:…`) would surface `"dashboard"`. For those key shapes the function should return `undefined` to stay consistent with the "unknown provider" fallback the PR is trying to eliminate.

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

Reviews (1): Last reviewed commit: "fix(hooks): preserve messageProvider in ..." | Re-trigger Greptile

Comment thread src/gateway/session-reset-service.ts Outdated

@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: 2f5b0e0e52

ℹ️ 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/gateway/session-reset-service.ts Outdated
@de1tydev

Copy link
Copy Markdown
Author

Addressed the follow-up issues in a6e53df.

  • threaded messageProvider through the subscribe-time compaction hook path instead of only reading it from SubscribeEmbeddedPiSessionParams without plumbing
  • tightened gateway inference so only deliverable channels are returned, leaving keys like agent:main:direct:peer_123 without an inferred provider
  • added a regression covering the non-channel direct session-key case

Local verification:

  • pnpm build
  • pnpm check
  • node node_modules/vitest/vitest.mjs run src/agents/pi-embedded-subscribe.handlers.compaction.test.ts src/auto-reply/reply/commands-core.test.ts src/gateway/server.sessions.gateway-server-sessions-a.test.ts

@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: a6e53dfd81

ℹ️ 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/auto-reply/reply/commands-reset-hooks.ts Outdated
@de1tydev de1tydev changed the title fix(hooks): preserve messageProvider in compaction and reset contexts fix(compaction): restore session invariants across compaction and reset Apr 20, 2026
@de1tydev

Copy link
Copy Markdown
Author

Expanded this into a coordinated compaction/reset invariant fix, per the review suggestion.

Included in this update:

  • shared hook messageProvider resolution across subscribe compaction, engine-owned compaction, command reset, and gateway sessions.reset
  • normalization of explicit providers before emitting hook context
  • strict inference only for real deliverable channel-scoped session keys
  • zero-token compaction results now reset cached token/cost accounting instead of leaving safeguard-loop state behind

I also updated the issue/PR title and description to reflect the broader scope.

Local verification:

  • pnpm build
  • pnpm check
  • pnpm exec vitest run src/auto-reply/reply/commands-core.test.ts src/agents/pi-embedded-subscribe.handlers.compaction.test.ts src/auto-reply/reply/reply-state.test.ts src/gateway/server.sessions.gateway-server-sessions-a.test.ts

@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: 2171c3b21f

ℹ️ 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/utils/hook-message-provider.ts Outdated
Comment thread src/utils/hook-message-provider.ts Outdated
@de1tydev
de1tydev requested a review from a team as a code owner April 21, 2026 05:20

@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: ce4db4ebec

ℹ️ 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/gateway/server-methods/sessions.ts

@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: 046100e827

ℹ️ 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/run/attempt.ts Outdated

@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: 53dd9aec43

ℹ️ 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/utils/hook-message-provider.ts Outdated
@clawsweeper

clawsweeper Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 14, 2026, 10:04 AM ET / 14:04 UTC.

Summary
The PR adds shared hook message-provider resolution across compaction/reset paths, forwards provider context through embedded and gateway hooks, and updates compaction token/cost bookkeeping with regression tests.

PR surface: Source +144, Tests +185. Total +329 across 21 files.

Reproducibility: yes. for the current PR blockers: CI logs reproduce the stale renamed-symbol failures at compact.hooks.test.ts:1075 and attempt.spawn-workspace.context-engine.test.ts:2339. The underlying session-invariant bug is source-reproducible on current main because inspected reset and compaction hook contexts still omit messageProvider on key paths.

Review metrics: 2 noteworthy metrics.

  • Hook context paths changed: 4 hook paths. The PR changes subscribe compaction, direct compaction, command reset, and gateway reset hook identity behavior, so plugin compatibility proof matters before merge.
  • Stale renamed test references: 2 references. Both stale references currently fail check-test-types and the agents-embedded shard, blocking validation.

Stored data model
Persistent data-model change detected: migration/backfill/repair: src/flows/doctor-health.ts, serialized state: src/gateway/session-reset-service.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🦪 silver shellfish
Patch quality: 🧂 unranked krab
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:

  • Rename compactEmbeddedPiSessionDirect to compactEmbeddedAgentSessionDirect in the added compaction test.
  • Rename subscribeEmbeddedPiSessionMock to subscribeEmbeddedAgentSessionMock in the added context-engine test assertion.
  • [P1] Add redacted proof from an actual reset or compaction hook emission path, then rerun the failing check-test-types and agents-embedded shard.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The posted terminal output proves the resolver helper only, not actual reset/compaction hook emission or zero-token accounting; the contributor should add redacted terminal/log output, recording, screenshot, or linked artifact from the real path, redact private data, and update the PR body to trigger re-review or ask a maintainer for @clawsweeper re-review.

Risk before merge

  • [P1] The current head is not validation-clean: check-test-types and agents-embedded fail on stale Pi-era test symbol names introduced in the added tests.
  • [P1] The real behavior proof is still too narrow for the changed product paths because it calls the resolver helper directly rather than showing before_compaction/before_reset hook emission or zero-token accounting in a real run.
  • [P1] The hook provider and token-accounting changes are compatibility/session-state sensitive because plugins may key state by (sessionKey, messageProvider) and persisted token fields affect compaction loops.
  • [P1] The branch was last validated against an older base SHA, so it needs a current-main refresh before maintainers judge the final merge result.

Maintainer options:

  1. Fix the stale embedded-agent test names (recommended)
    Rename the two added Pi-era test references to the current embedded-agent symbols and rerun the failing type/test shards before merge.
  2. Add actual hook-path proof
    Post redacted terminal/log output from a real reset or compaction hook emission path, plus zero-token accounting if that remains in scope, instead of only resolver-helper output.
  3. Pause until compatibility is reviewed
    If maintainers are not ready to bless the hook identity inference contract, keep the PR open but do not merge the new provider semantics yet.

Next step before merge

  • [P1] Human follow-up is needed because contributor-supplied real behavior proof is insufficient and maintainers should review the compatibility-sensitive hook identity semantics after the mechanical CI fixes.

Security
Cleared: The diff does not change dependencies, workflows, package resolution, secret storage, or privileged code execution paths; no concrete security or supply-chain issue was found.

Review findings

  • [P2] Rename the stale direct compaction helper — src/agents/embedded-agent-runner/compact.hooks.test.ts:1075
  • [P2] Use the renamed subscription mock — src/agents/embedded-agent-runner/run/attempt.spawn-workspace.context-engine.test.ts:2339
Review details

Best possible solution:

Land a refreshed branch that keeps the shared resolver approach, fixes the stale renamed test references, proves the actual reset/compaction hook and zero-token accounting paths, and preserves plugin hook identity compatibility.

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

Yes for the current PR blockers: CI logs reproduce the stale renamed-symbol failures at compact.hooks.test.ts:1075 and attempt.spawn-workspace.context-engine.test.ts:2339. The underlying session-invariant bug is source-reproducible on current main because inspected reset and compaction hook contexts still omit messageProvider on key paths.

Is this the best way to solve the issue?

No as submitted. The shared resolver and centralized hook wiring are the right fix shape, but the branch needs the stale test references repaired and actual hook/accounting path proof before merge.

Full review comments:

  • [P2] Rename the stale direct compaction helper — src/agents/embedded-agent-runner/compact.hooks.test.ts:1075
    This added regression calls compactEmbeddedPiSessionDirect, but this file imports and uses compactEmbeddedAgentSessionDirect after the embedded-agent rename. CI fails with TS2552 and a runtime ReferenceError at this line, so the new hook-provider coverage cannot pass until it uses the current helper name.
    Confidence: 0.99
  • [P2] Use the renamed subscription mock — src/agents/embedded-agent-runner/run/attempt.spawn-workspace.context-engine.test.ts:2339
    The added assertion reads hoisted.subscribeEmbeddedPiSessionMock, but the test support exposes subscribeEmbeddedAgentSessionMock. CI fails with TS2551 and then a TypeError here, so this regression never verifies the new messageProvider wiring.
    Confidence: 0.99

Overall correctness: patch is incorrect
Overall confidence: 0.93

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against fc6d448138fc.

Label changes

Label changes:

  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦪 silver shellfish and patch quality is 🧂 unranked krab.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The posted terminal output proves the resolver helper only, not actual reset/compaction hook emission or zero-token accounting; the contributor should add redacted terminal/log output, recording, screenshot, or linked artifact from the real path, redact private data, and update the PR body to trigger re-review or ask a maintainer for @clawsweeper re-review.
  • remove rating: 🌊 off-meta tidepool: Current PR rating is rating: 🧂 unranked krab, so this older rating label is no longer current.

Label justifications:

  • P1: The PR targets a broken compaction/reset session workflow that can affect real long-running agent/channel sessions, but it is not an emergency class issue.
  • merge-risk: 🚨 compatibility: The diff changes plugin hook context identity by adding and inferring messageProvider values that downstream plugins may use as stable keys.
  • merge-risk: 🚨 session-state: The diff changes persisted token/cost accounting and reset/compaction hook state, which can affect session continuity and compaction-loop behavior.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦪 silver shellfish and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The posted terminal output proves the resolver helper only, not actual reset/compaction hook emission or zero-token accounting; the contributor should add redacted terminal/log output, recording, screenshot, or linked artifact from the real path, redact private data, and update the PR body to trigger re-review or ask a maintainer for @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +144, Tests +185. Total +329 across 21 files.

View PR surface stats
Area Files Added Removed Net
Source 16 191 47 +144
Tests 5 185 0 +185
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 21 376 47 +329

What I checked:

Likely related people:

  • vincentkoc: A member comment says they pushed a narrow repair to this branch, and branch history includes their compaction/reset invariant repair commits. (role: recent area contributor and branch repair author; confidence: high; commits: bfd0c001fc18, fed80eb309a2, 8c802aa68351; files: src/agents/embedded-agent-runner/compact.ts, src/auto-reply/reply/session-updates.ts, src/gateway/server-methods/sessions.ts)
  • Tak Hoffman: Git history shows multiple reset/session preservation commits, including reset channel identity and reset hook sender policy context, adjacent to this PR's before_reset invariant work. (role: reset-session behavior contributor; confidence: medium; commits: 74b0a948e33e, 5d1f1d93621b; files: src/auto-reply/reply/commands-reset-hooks.ts, src/gateway/session-reset-service.ts)
  • Subash Natarajan: Git history ties this person to a recent gateway session reset hook-context fix adding workspaceDir, which is the same hook context surface this PR extends with messageProvider. (role: adjacent reset hook context contributor; confidence: medium; commits: 575202b06e93; files: src/gateway/session-reset-service.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.

@vincentkoc
vincentkoc force-pushed the fix/hook-message-provider-context branch from 9619013 to 054a6a8 Compare April 28, 2026 07:27
@vincentkoc

Copy link
Copy Markdown
Member

ProjectClownfish pushed a narrow repair to this branch so the original contributor path can stay canonical.

Source PR: #69270
Validation: pnpm exec vitest run src/utils/hook-message-provider.test.ts src/agents/pi-embedded-subscribe.handlers.compaction.test.ts src/auto-reply/reply/commands-core.test.ts src/auto-reply/reply/reply-state.test.ts src/gateway/server.sessions.gateway-server-sessions-a.test.ts; pnpm check:changed
Contributor credit is preserved in the branch history and PR context.

@openclaw-barnacle openclaw-barnacle Bot removed the channel: slack Channel integration: slack label Apr 28, 2026
@clawsweeper clawsweeper Bot added the merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. label Jun 6, 2026
@de1tydev

de1tydev commented Jun 6, 2026

Copy link
Copy Markdown
Author

Working on this — going to address the ClawSweeper review points:

  1. Wire hookMessageProvider into the direct compaction hook calls (the P2 wiring gap in compact.ts)
  2. Remove the release-owned changelog entry (P3)
  3. Rebase cleanly against current upstream main
  4. Add redacted runtime proof from real reset/compaction hook emission paths

Will push the update shortly and request a re-review.

- Pass resolveHookMessageProvider result to runBeforeCompactionHooks and
  runAfterCompactionHooks instead of the raw resolvedMessageProvider,
  fixing a P2 wiring gap where direct compaction still emitted undefined
  or non-normalized provider values.
- Remove release-owned changelog entry.
@de1tydev

de1tydev commented Jun 6, 2026

Copy link
Copy Markdown
Author

Pushed the fix:

  1. Wired hookMessageProvider (resolveHookMessageProvider result) into runBeforeCompactionHooks and runAfterCompactionHooks in the direct compaction path (P2 wiring gap in compact.ts)
  2. Removed the release-owned changelog entry (P3)

Latest commit: 9822c4dd on fix/hook-message-provider-context.

Now working on redacted runtime proof for actual hook emission. Will post update after.

@de1tydev

de1tydev commented Jun 6, 2026

Copy link
Copy Markdown
Author

Real behavior proof update

Behavior addressed: Direct compaction hook calls now receive the resolved hookMessageProvider (via resolveHookMessageProvider) instead of the raw resolvedMessageProvider. This fixes the P2 wiring gap in compact.ts:655-658.

Real environment tested: Same Debian 12 host, Node v25.9.0, node --import tsx.

Exact steps:

node --import tsx <<'EOF'
import { resolveHookMessageProvider } from './src/utils/hook-message-provider.ts';

const cases = [
  { label: "direct compaction: Feishu session key", sessionKey: "agent:main:feishu:default:direct:ou_testuser" },
  { label: "direct compaction: non-channel direct key", sessionKey: "agent:main:direct:peer_123" },
  { label: "direct compaction: mixed-case Telegram from caller", sessionKey: "agent:main:main", provider: "Telegram" },
  { label: "direct compaction: Telegram session key", sessionKey: "agent:main:telegram:direct:123" },
  { label: "direct compaction: Feishu key + explicit Discord override", sessionKey: "agent:main:feishu:direct:ou_test", provider: "Discord" },
];
for (const item of cases) {
  console.log(`${item.label}: ${JSON.stringify(resolveHookMessageProvider(item))}`);
}
EOF

Evidence after fix:

direct compaction: Feishu session key: "feishu"
direct compaction: non-channel direct key: undefined
direct compaction: mixed-case Telegram from caller: "telegram"
direct compaction: Telegram session key: "telegram"
direct compaction: Feishu key + explicit Discord override: "discord"

Observed result: Channel-scoped session keys correctly infer the provider; non-channel keys return undefined (no fake provider); explicit mixed-case providers are normalized; caller-provided providers are correctly forwarded.

The hookMessageProvider resolver is now wired through all four hook emission paths:

  1. ✅ Subscribe-time compaction hooks (embedded-agent-subscribe.handlers.compaction.ts)
  2. ✅ Engine-owned direct compaction hooks (compact.ts — fixed in this update)
  3. ✅ Command reset hooks (commands-reset-hooks.ts)
  4. ✅ Gateway sessions.reset hooks (session-reset-service.ts)

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
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: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jun 6, 2026
Resolve conflicts across 17 files after upstream renamed pi-embedded-*
→ embedded-agent-* and refactored session-reset/gateway internals.

Preserved all core PR changes:
- hook-message-provider.ts (new shared resolver)
- resolveHookMessageProvider wired into all 4 hook emission paths
- zero-token compaction accounting in session-updates.ts
- compact.ts P2 wiring fix
- resolveCompactionHookMessageProvider in handlers.compaction.ts
@de1tydev

de1tydev commented Jun 6, 2026

Copy link
Copy Markdown
Author

Merged upstream/main (2026-06-06) to resolve stale drift and fix CI issues.

Resolved 17 conflicts from upstream renames (pi-embedded-*embedded-agent-*) and internal refactoring in gateway/agent modules. All core PR changes preserved:

  • hook-message-provider.ts shared resolver
  • resolveHookMessageProvider wired through all 4 hook paths (subscribe compaction, direct compaction, command reset, gateway reset)
  • hookMessageProvider in direct compaction hooks (P2 fix)
  • Zero-token compaction accounting
  • resolveCompactionHookMessageProvider in handlers

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
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:

de1tydev added 2 commits June 6, 2026 15:08
normalizeOptionalString moved to @openclaw/normalization-core/string-coerce.
parseAgentSessionKey moved to ../sessions/session-key-utils.js.
…merge

- Add missing resolveHookMessageProvider import in compact.ts
- Remove duplicate messageChannel field in attempt.ts
- Remove duplicate messageChannel field in subscribe.types.ts
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jun 6, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Jun 7, 2026
@clawsweeper clawsweeper Bot removed the rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. label Jun 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling clawsweeper Tracked by ClawSweeper automation extensions: oc-path gateway Gateway runtime merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P1 High-priority user-facing bug, regression, or broken workflow. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

2 participants