Skip to content

fix: read sender ids from OpenClaw runtime context#77

Open
Squirbie wants to merge 4 commits into
plastic-labs:feat/multi-peer-supportfrom
Squirbie:fix/runtime-context-sender-id
Open

fix: read sender ids from OpenClaw runtime context#77
Squirbie wants to merge 4 commits into
plastic-labs:feat/multi-peer-supportfrom
Squirbie:fix/runtime-context-sender-id

Conversation

@Squirbie
Copy link
Copy Markdown

Summary

  • read sender IDs from hidden openclaw.runtime-context rows when visible user messages no longer carry inline channel metadata
  • use the hidden sender only for Honcho peer attribution; runtime-context rows are not persisted as conversation messages
  • prefer hidden runtime-context over spoofable user-authored metadata, and fail closed when a runtime-context row exists without a sender id
  • use the same current-speaker resolution for both capture and before_prompt_build context injection

Why

OpenClaw can keep Discord/channel metadata out of model-visible user text by emitting it as a hidden runtime-context row after the user message. Without this fallback, multi-peer Honcho deployments may attribute clean Discord messages to the default/previous participant and mix memory between people.

This keeps the prompt/history clean while preserving per-speaker Honcho routing.

Tests

  • corepack pnpm exec vitest run helpers.test.ts
  • corepack pnpm exec vitest run
  • corepack pnpm build
  • git diff --check

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 27, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6a084e4d-9161-4a98-b948-257788e8b476

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Squirbie
Copy link
Copy Markdown
Author

@coderabbitai review

Maintainer note: this is a focused companion fix for the multi-peer branch. OpenClaw can now keep Discord/channel metadata out of visible user text and emit it as hidden openclaw.runtime-context rows instead.

This PR keeps Honcho multi-peer attribution working in that cleaner setup: capture and prompt-time context lookup read the hidden sender id, do not persist runtime-context rows as messages, and prefer hidden metadata over spoofable user-authored blocks. It also fails closed when a runtime-context row exists without a sender id.

Local validation passed: corepack pnpm exec vitest run helpers.test.ts, corepack pnpm exec vitest run, corepack pnpm build, and git diff --check.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 27, 2026

Only users with a collaborator, contributor, member, or owner role can interact with CodeRabbit.

@Squirbie
Copy link
Copy Markdown
Author

Updated this PR to resolve the merge conflict against the refreshed multi-peer base branch.

What changed:

  • Merged the latest origin/feat/multi-peer-support into fix/runtime-context-sender-id
  • Kept the newer base helper/test layout changes
  • Preserved the runtime-context sender id behavior from this PR
  • Pushed normally to the existing branch; no force-push or PR recreation

Validation passed locally:

  • corepack pnpm exec vitest run test/helpers.test.ts
  • corepack pnpm exec vitest run
  • corepack pnpm build
  • git diff --check

GitHub now reports the PR as mergeable/clean again. Maintainer review should be unblocked.

@Squirbie
Copy link
Copy Markdown
Author

Follow-up pushed to make the runtime-context path fail closed instead of falling back to the default/previous participant when attribution is present but incomplete.

What changed:

  • split strict sender resolution into string | null | undefined so null means trusted runtime-context existed but no sender_id was available
  • capture skips unattributed user messages instead of saving them to the default peer
  • context injection skips previous/default peer fallback when the current turn has runtime-context without sender_id
  • added focused helper/context tests for these cases

Validated locally:

  • corepack pnpm exec vitest run test/helpers.test.ts test/context.test.ts
  • corepack pnpm exec vitest run
  • corepack pnpm build
  • git diff --check

Copy link
Copy Markdown
Collaborator

@ajspig ajspig left a comment

Choose a reason for hiding this comment

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

Hey! Thanks for contributing. Runtime-context sender resolution is the right approach for clean multi-peer attribution, and the fail-closed behavior (skip rather than misattribute) is solid. A few things before merging:

API surface cleanup:

  • 8 new exported functions in helpers.ts, but only 3 are used outside tests. The strict/non-strict pairs (resolveSenderIdForMessage / resolveSenderIdForMessageStrict, same for CurrentTurn) add surface for a null vs undefined distinction — consider keeping only the strict variants and letting callers do ?? undefined if needed.

pickSenderId is very permissive:

  • It tries 7 fallback keys (sender_id, senderId, SenderId, user_id, userId, id, sender). Since runtime-context format is controlled by OpenClaw, can we lock this to the actual field name(s) OpenClaw emits? The wide net risks matching unrelated fields.

Minor:

  • maxDistance = 4 — worth a brief comment explaining why 4 (how many rows can sit between a user message and its runtime-context row).
  • extractMessages is at 6 params now, with the last being a 4-arg function. An options object would be cleaner, especially as the signature keeps growing.

@Squirbie
Copy link
Copy Markdown
Author

Squirbie commented May 2, 2026

Addressed the review feedback in 680a350:

  • Reduced the new helpers API surface by keeping runtime-context lookup helpers internal and removing the non-strict exported wrappers.
  • Narrowed sender-id extraction to OpenClaw's runtime field names: Conversation info.sender_id and Sender.id.
  • Added the maxDistance = 4 rationale comment.
  • Converted extractMessages to an options-object call shape.

Validation run locally:

  • corepack pnpm exec vitest run test/helpers.test.ts test/context.test.ts
  • corepack pnpm exec vitest run
  • corepack pnpm build
  • git diff --check

@Squirbie
Copy link
Copy Markdown
Author

Squirbie commented May 2, 2026

@ajspig I pushed 680a350 and want to call out the intended shape more explicitly, since the previous note was a little too checklist-like.

The core behavior is now: only OpenClaw-generated hidden openclaw.runtime-context rows are treated as trusted attribution. If such a row exists but does not carry a sender id, Honcho skips/fails closed instead of falling back to owner/default/previous participant. That is meant to preserve multi-peer separation rather than guessing.

Review items addressed:

  • API surface: removed the non-strict exported helper pairs and kept the runtime-context lookup helpers internal. The remaining strict helpers return string | null | undefined, where null specifically means “trusted runtime-context existed, but no sender id was present,” so callers can skip instead of falling back.
  • Sender-id fields: narrowed runtime-context sender extraction to the OpenClaw-controlled fields currently emitted by runtime context: Conversation info.sender_id and Sender.id. The broader userId/id/sender style fallbacks are gone for this path.
  • Search window: added the maxDistance = 4 rationale in code. It allows the user row, optional system/compaction markers, then the runtime-context row, while still avoiding crossing into unrelated later turns.
  • extractMessages: converted the growing positional argument list into an options object.

Validation after the change:

  • corepack pnpm exec vitest run test/helpers.test.ts test/context.test.ts
  • corepack pnpm exec vitest run
  • corepack pnpm build
  • git diff --check

Could you re-review this when you get a chance? The branch is clean/mergeable on GitHub from my latest check.

@Squirbie Squirbie requested a review from ajspig May 2, 2026 19:25
@Squirbie
Copy link
Copy Markdown
Author

Squirbie commented May 3, 2026

I believe the requested changes from the earlier review have been addressed in 680a350:

  • kept the helper surface internal to the plugin code path
  • narrowed trusted sender extraction to OpenClaw runtime context fields
  • documented the maxDistance behavior
  • kept the fallback fail-closed when no trusted sender can be recovered

Could you re-review when convenient?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants