Skip to content

refactor: unify peer kind to ChatType, rename dm to direct#11881

Merged
cpojer merged 12 commits intomainfrom
fix/import-extensions
Feb 9, 2026
Merged

refactor: unify peer kind to ChatType, rename dm to direct#11881
cpojer merged 12 commits intomainfrom
fix/import-extensions

Conversation

@quotentiroler
Copy link
Contributor

@quotentiroler quotentiroler commented Feb 8, 2026

Summary

Unify the peer/chat type system by replacing RoutePeerKind and NormalizedChatType with ChatType and changing the "dm" literal value to "direct" throughout the codebase.

Why

normalizeChatType(), NormalizedChatType, and RoutePeerKind were used inconsistently throughout the codebase.

Changes

Core Type Changes

  • ChatType ("direct" | "group" | "channel") is now the canonical type for peer/chat classification
  • RoutePeerKind is now a deprecated type alias pointing to ChatType
  • Session keys now use direct: prefix instead of dm: (e.g., agent:main:whatsapp:direct:+123)

Backward Compatibility

All of these accept both "dm" (legacy) and "direct" (new):

  • normalizeChatType() - normalizes "dm""direct"
  • cron-tool.ts session key parsing - accepts :dm: or :direct: markers
  • qmd-manager.ts session key parsing - accepts :dm: or :direct: markers
  • getDmHistoryLimitFromSessionKey() - accepts :dm: or :direct: session keys

Existing user session stores with :dm: keys continue to work seamlessly.

Files Modified (59 total)

  • Core routing: resolve-route.ts, session-key.ts
  • Config types: types.agents.ts, types.base.ts, zod-schema.agents.ts
  • Plugin SDK: Added ChatType export, deprecated RoutePeerKind
  • All channel monitors: telegram, slack, signal, discord, web, line, imessage
  • All extensions: mattermost, zalo, tlon, feishu, googlechat, matrix, msteams, nextcloud-talk, bluebubbles
  • Tests updated to expect :direct: in generated output
  • Legacy :dm: test data retained to verify backward compat
  • Docs updated

Breaking Change

Session keys now generate "direct" instead of "dm". The backward compat layer ensures old keys are still read correctly, so this is a soft breaking change - no user action required on upgrade.

Testing

  • pnpm check passes (tsgo, lint, format)
  • All unit tests pass
  • Backward compat tests verify normalizeChatType("dm")"direct"

quotentiroler and others added 2 commits February 8, 2026 05:35
The imports incorrectly used .ts extension which doesn't resolve
with moduleResolution: NodeNext. Changed to .js and added 'type'
import modifier.
@quotentiroler quotentiroler changed the title fix: use .js extension for ESM imports of RoutePeerKind refactor: use RoutePeerKind type instead of inline literals Feb 8, 2026
- Replace RoutePeerKind with ChatType throughout codebase
- Change 'dm' literal values to 'direct' in routing/session keys
- Keep backward compat: normalizeChatType accepts 'dm' -> 'direct'
- Add ChatType export to plugin-sdk, deprecate RoutePeerKind
- Update session key parsing to accept both 'dm' and 'direct' markers
- Update all channel monitors and extensions to use ChatType

BREAKING CHANGE: Session keys now use 'direct' instead of 'dm'.
Existing 'dm' keys still work via backward compat layer.
@openclaw-barnacle openclaw-barnacle bot added docs Improvements or additions to documentation channel: bluebubbles Channel integration: bluebubbles channel: discord Channel integration: discord channel: googlechat Channel integration: googlechat channel: imessage Channel integration: imessage channel: matrix Channel integration: matrix channel: mattermost Channel integration: mattermost channel: msteams Channel integration: msteams channel: nextcloud-talk Channel integration: nextcloud-talk channel: signal Channel integration: signal channel: slack Channel integration: slack channel: telegram Channel integration: telegram channel: tlon Channel integration: tlon channel: whatsapp-web Channel integration: whatsapp-web channel: zalo Channel integration: zalo gateway Gateway runtime agents Agent runtime and tooling channel: feishu Channel integration: feishu labels Feb 8, 2026
@quotentiroler quotentiroler changed the title refactor: use RoutePeerKind type instead of inline literals refactor: unify peer kind to ChatType, rename dm to direct Feb 8, 2026
- Fix test expectations to expect :direct: in generated output
- Add explicit backward compat test for normalizeChatType('dm')
- Keep input test data with :dm: keys to verify backward compat
getDmHistoryLimitFromSessionKey now accepts both :dm: and :direct:
to ensure old session keys continue to work correctly.
@clawdinator
Copy link
Contributor

clawdinator bot commented Feb 8, 2026

CLAWDINATOR FIELD REPORT // PR Closure

I am CLAWDINATOR — cybernetic crustacean, maintainer triage bot for OpenClaw. I was sent from the future to keep this repo shipping clean code.

TARGET ACQUIRED. I have reviewed your PR. Your effort is br00tal.

Situation briefing: OpenClaw receives ~25 PRs every hour. The maintainers cannot pump iron that hard without collapsing. This PR is unlikely to merge in the near term, so I'm closing it to keep the pipeline moving. Consider that a deprecation — not a termination of your spirit.

Don't sweat the close. Every PR teaches us something — CLAWDINATOR aggregates bugs, patterns, and feature demands across all contributions. The maintainers get briefed on that intel to target what gets built and what gets fixed next. Your code didn't merge, but your work made the project smarter.

Think your change should ship? Come with me if you want to ship. Report to #pr-thunderdome-dangerzone on Discord — READ THE TOPIC or risk immediate termination. Give the maintainers a clear briefing — what it fixes, who it helps, why it's br00tal.

Other br00tal routes: publish a skill on ClawHub (clawhub.ai), ship a CLI or other open‑source tool, or maintain your own fork of openclaw. All of those help the community ship.

I'll be back. Stay br00tal.

🤖 This is an automated message from CLAWDINATOR, the OpenClaw maintainer bot.\n\n

@clawdinator clawdinator bot closed this Feb 8, 2026
@quotentiroler quotentiroler reopened this Feb 8, 2026
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 8, 2026

Additional Comments (2)

src/config/sessions/reset.ts
Legacy dm reset config ignored

resolveSessionResetPolicy indexes sessionCfg.resetByType using params.resetType, which is now only "direct" | "group" | "thread" (src/config/sessions/reset.ts:6,91). If a user has an existing config with resetByType: { dm: ... } (very likely given the rename), that override will be silently ignored and the DM/direct sessions will fall back to the base reset policy. Consider normalizing resetByType.dmresetByType.direct (or accepting both keys) when resolving policy to preserve backward compatibility.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/config/sessions/reset.ts
Line: 89:93

Comment:
**Legacy `dm` reset config ignored**

`resolveSessionResetPolicy` indexes `sessionCfg.resetByType` using `params.resetType`, which is now only `"direct" | "group" | "thread"` (`src/config/sessions/reset.ts:6,91`). If a user has an existing config with `resetByType: { dm: ... }` (very likely given the rename), that override will be silently ignored and the DM/direct sessions will fall back to the base reset policy. Consider normalizing `resetByType.dm``resetByType.direct` (or accepting both keys) when resolving policy to preserve backward compatibility.

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

src/config/zod-schema.session.ts
Schema rejects legacy dm

SessionSchema.resetByType now only allows direct/group/thread (src/config/zod-schema.session.ts:57-60). That means existing configs using resetByType.dm will fail validation on upgrade, which conflicts with the stated backward-compat approach elsewhere (e.g., normalizeChatType accepting "dm"). If resetByType.dm is meant to remain supported as a legacy alias, the schema needs to accept it (and ideally normalize it to direct).

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/config/zod-schema.session.ts
Line: 52:60

Comment:
**Schema rejects legacy `dm`**

`SessionSchema.resetByType` now only allows `direct/group/thread` (`src/config/zod-schema.session.ts:57-60`). That means existing configs using `resetByType.dm` will fail validation on upgrade, which conflicts with the stated backward-compat approach elsewhere (e.g., `normalizeChatType` accepting `"dm"`). If `resetByType.dm` is meant to remain supported as a legacy alias, the schema needs to accept it (and ideally normalize it to `direct`).

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

@quotentiroler quotentiroler requested a review from cpojer February 8, 2026 19:31
@quotentiroler quotentiroler removed the request for review from cpojer February 8, 2026 22:57
- session-key.test.ts: verify both :dm: and :direct: keys are valid
- getDmHistoryLimitFromSessionKey: verify both formats work
@cpojer cpojer merged commit 223eee0 into main Feb 9, 2026
23 of 24 checks passed
@cpojer cpojer deleted the fix/import-extensions branch February 9, 2026 00:20
zendizmo pushed a commit to zendizmo/openclaw that referenced this pull request Feb 9, 2026
…11881)

* fix: use .js extension for ESM imports of RoutePeerKind

The imports incorrectly used .ts extension which doesn't resolve
with moduleResolution: NodeNext. Changed to .js and added 'type'
import modifier.

* fix tsconfig

* refactor: unify peer kind to ChatType, rename dm to direct

- Replace RoutePeerKind with ChatType throughout codebase
- Change 'dm' literal values to 'direct' in routing/session keys
- Keep backward compat: normalizeChatType accepts 'dm' -> 'direct'
- Add ChatType export to plugin-sdk, deprecate RoutePeerKind
- Update session key parsing to accept both 'dm' and 'direct' markers
- Update all channel monitors and extensions to use ChatType

BREAKING CHANGE: Session keys now use 'direct' instead of 'dm'.
Existing 'dm' keys still work via backward compat layer.

* fix tests

* test: update session key expectations for dmdirect migration

- Fix test expectations to expect :direct: in generated output
- Add explicit backward compat test for normalizeChatType('dm')
- Keep input test data with :dm: keys to verify backward compat

* fix: accept legacy 'dm' in session key parsing for backward compat

getDmHistoryLimitFromSessionKey now accepts both :dm: and :direct:
to ensure old session keys continue to work correctly.

* test: add explicit backward compat tests for dmdirect migration

- session-key.test.ts: verify both :dm: and :direct: keys are valid
- getDmHistoryLimitFromSessionKey: verify both formats work

* feat: backward compat for resetByType.dm config key

* test: skip unix-path Nix tests on Windows
lucasmpramos pushed a commit to butley/openclaw that referenced this pull request Feb 10, 2026
…11881)

* fix: use .js extension for ESM imports of RoutePeerKind

The imports incorrectly used .ts extension which doesn't resolve
with moduleResolution: NodeNext. Changed to .js and added 'type'
import modifier.

* fix tsconfig

* refactor: unify peer kind to ChatType, rename dm to direct

- Replace RoutePeerKind with ChatType throughout codebase
- Change 'dm' literal values to 'direct' in routing/session keys
- Keep backward compat: normalizeChatType accepts 'dm' -> 'direct'
- Add ChatType export to plugin-sdk, deprecate RoutePeerKind
- Update session key parsing to accept both 'dm' and 'direct' markers
- Update all channel monitors and extensions to use ChatType

BREAKING CHANGE: Session keys now use 'direct' instead of 'dm'.
Existing 'dm' keys still work via backward compat layer.

* fix tests

* test: update session key expectations for dmdirect migration

- Fix test expectations to expect :direct: in generated output
- Add explicit backward compat test for normalizeChatType('dm')
- Keep input test data with :dm: keys to verify backward compat

* fix: accept legacy 'dm' in session key parsing for backward compat

getDmHistoryLimitFromSessionKey now accepts both :dm: and :direct:
to ensure old session keys continue to work correctly.

* test: add explicit backward compat tests for dmdirect migration

- session-key.test.ts: verify both :dm: and :direct: keys are valid
- getDmHistoryLimitFromSessionKey: verify both formats work

* feat: backward compat for resetByType.dm config key

* test: skip unix-path Nix tests on Windows
skyhawk14 pushed a commit to skyhawk14/openclaw that referenced this pull request Feb 13, 2026
…11881)

* fix: use .js extension for ESM imports of RoutePeerKind

The imports incorrectly used .ts extension which doesn't resolve
with moduleResolution: NodeNext. Changed to .js and added 'type'
import modifier.

* fix tsconfig

* refactor: unify peer kind to ChatType, rename dm to direct

- Replace RoutePeerKind with ChatType throughout codebase
- Change 'dm' literal values to 'direct' in routing/session keys
- Keep backward compat: normalizeChatType accepts 'dm' -> 'direct'
- Add ChatType export to plugin-sdk, deprecate RoutePeerKind
- Update session key parsing to accept both 'dm' and 'direct' markers
- Update all channel monitors and extensions to use ChatType

BREAKING CHANGE: Session keys now use 'direct' instead of 'dm'.
Existing 'dm' keys still work via backward compat layer.

* fix tests

* test: update session key expectations for dmdirect migration

- Fix test expectations to expect :direct: in generated output
- Add explicit backward compat test for normalizeChatType('dm')
- Keep input test data with :dm: keys to verify backward compat

* fix: accept legacy 'dm' in session key parsing for backward compat

getDmHistoryLimitFromSessionKey now accepts both :dm: and :direct:
to ensure old session keys continue to work correctly.

* test: add explicit backward compat tests for dmdirect migration

- session-key.test.ts: verify both :dm: and :direct: keys are valid
- getDmHistoryLimitFromSessionKey: verify both formats work

* feat: backward compat for resetByType.dm config key

* test: skip unix-path Nix tests on Windows
mbelinky pushed a commit that referenced this pull request Feb 14, 2026
* fix: use .js extension for ESM imports of RoutePeerKind

The imports incorrectly used .ts extension which doesn't resolve
with moduleResolution: NodeNext. Changed to .js and added 'type'
import modifier.

* fix tsconfig

* refactor: unify peer kind to ChatType, rename dm to direct

- Replace RoutePeerKind with ChatType throughout codebase
- Change 'dm' literal values to 'direct' in routing/session keys
- Keep backward compat: normalizeChatType accepts 'dm' -> 'direct'
- Add ChatType export to plugin-sdk, deprecate RoutePeerKind
- Update session key parsing to accept both 'dm' and 'direct' markers
- Update all channel monitors and extensions to use ChatType

BREAKING CHANGE: Session keys now use 'direct' instead of 'dm'.
Existing 'dm' keys still work via backward compat layer.

* fix tests

* test: update session key expectations for dmdirect migration

- Fix test expectations to expect :direct: in generated output
- Add explicit backward compat test for normalizeChatType('dm')
- Keep input test data with :dm: keys to verify backward compat

* fix: accept legacy 'dm' in session key parsing for backward compat

getDmHistoryLimitFromSessionKey now accepts both :dm: and :direct:
to ensure old session keys continue to work correctly.

* test: add explicit backward compat tests for dmdirect migration

- session-key.test.ts: verify both :dm: and :direct: keys are valid
- getDmHistoryLimitFromSessionKey: verify both formats work

* feat: backward compat for resetByType.dm config key

* test: skip unix-path Nix tests on Windows
davidrudduck added a commit to davidrudduck/openclaw that referenced this pull request Feb 19, 2026
…ction (#3)

* refactor: unify peer kind to ChatType, rename dm to direct (openclaw#11881)

* fix: use .js extension for ESM imports of RoutePeerKind

The imports incorrectly used .ts extension which doesn't resolve
with moduleResolution: NodeNext. Changed to .js and added 'type'
import modifier.

* fix tsconfig

* refactor: unify peer kind to ChatType, rename dm to direct

- Replace RoutePeerKind with ChatType throughout codebase
- Change 'dm' literal values to 'direct' in routing/session keys
- Keep backward compat: normalizeChatType accepts 'dm' -> 'direct'
- Add ChatType export to plugin-sdk, deprecate RoutePeerKind
- Update session key parsing to accept both 'dm' and 'direct' markers
- Update all channel monitors and extensions to use ChatType

BREAKING CHANGE: Session keys now use 'direct' instead of 'dm'.
Existing 'dm' keys still work via backward compat layer.

* fix tests

* test: update session key expectations for dmdirect migration

- Fix test expectations to expect :direct: in generated output
- Add explicit backward compat test for normalizeChatType('dm')
- Keep input test data with :dm: keys to verify backward compat

* fix: accept legacy 'dm' in session key parsing for backward compat

getDmHistoryLimitFromSessionKey now accepts both :dm: and :direct:
to ensure old session keys continue to work correctly.

* test: add explicit backward compat tests for dmdirect migration

- session-key.test.ts: verify both :dm: and :direct: keys are valid
- getDmHistoryLimitFromSessionKey: verify both formats work

* feat: backward compat for resetByType.dm config key

* test: skip unix-path Nix tests on Windows

* fix(daemon): use execFileSync instead of execSync to avoid shell injection

resolveBinaryPath used execSync with string interpolation to run
which/where, passing the binary name through a shell. While currently
only called with hardcoded "bun" and "node" literals, the function
signature accepts arbitrary strings -- a future caller passing
untrusted input would enable command injection.

Switch to execFileSync with an argv array to bypass the shell entirely.

---------

Co-authored-by: max <40643627+quotentiroler@users.noreply.github.com>
davidrudduck added a commit to davidrudduck/openclaw that referenced this pull request Feb 19, 2026
…ction (#3)

* refactor: unify peer kind to ChatType, rename dm to direct (openclaw#11881)

* fix: use .js extension for ESM imports of RoutePeerKind

The imports incorrectly used .ts extension which doesn't resolve
with moduleResolution: NodeNext. Changed to .js and added 'type'
import modifier.

* fix tsconfig

* refactor: unify peer kind to ChatType, rename dm to direct

- Replace RoutePeerKind with ChatType throughout codebase
- Change 'dm' literal values to 'direct' in routing/session keys
- Keep backward compat: normalizeChatType accepts 'dm' -> 'direct'
- Add ChatType export to plugin-sdk, deprecate RoutePeerKind
- Update session key parsing to accept both 'dm' and 'direct' markers
- Update all channel monitors and extensions to use ChatType

BREAKING CHANGE: Session keys now use 'direct' instead of 'dm'.
Existing 'dm' keys still work via backward compat layer.

* fix tests

* test: update session key expectations for dmdirect migration

- Fix test expectations to expect :direct: in generated output
- Add explicit backward compat test for normalizeChatType('dm')
- Keep input test data with :dm: keys to verify backward compat

* fix: accept legacy 'dm' in session key parsing for backward compat

getDmHistoryLimitFromSessionKey now accepts both :dm: and :direct:
to ensure old session keys continue to work correctly.

* test: add explicit backward compat tests for dmdirect migration

- session-key.test.ts: verify both :dm: and :direct: keys are valid
- getDmHistoryLimitFromSessionKey: verify both formats work

* feat: backward compat for resetByType.dm config key

* test: skip unix-path Nix tests on Windows

* fix(daemon): use execFileSync instead of execSync to avoid shell injection

resolveBinaryPath used execSync with string interpolation to run
which/where, passing the binary name through a shell. While currently
only called with hardcoded "bun" and "node" literals, the function
signature accepts arbitrary strings -- a future caller passing
untrusted input would enable command injection.

Switch to execFileSync with an argv array to bypass the shell entirely.

---------

Co-authored-by: max <40643627+quotentiroler@users.noreply.github.com>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…11881)

* fix: use .js extension for ESM imports of RoutePeerKind

The imports incorrectly used .ts extension which doesn't resolve
with moduleResolution: NodeNext. Changed to .js and added 'type'
import modifier.

* fix tsconfig

* refactor: unify peer kind to ChatType, rename dm to direct

- Replace RoutePeerKind with ChatType throughout codebase
- Change 'dm' literal values to 'direct' in routing/session keys
- Keep backward compat: normalizeChatType accepts 'dm' -> 'direct'
- Add ChatType export to plugin-sdk, deprecate RoutePeerKind
- Update session key parsing to accept both 'dm' and 'direct' markers
- Update all channel monitors and extensions to use ChatType

BREAKING CHANGE: Session keys now use 'direct' instead of 'dm'.
Existing 'dm' keys still work via backward compat layer.

* fix tests

* test: update session key expectations for dmdirect migration

- Fix test expectations to expect :direct: in generated output
- Add explicit backward compat test for normalizeChatType('dm')
- Keep input test data with :dm: keys to verify backward compat

* fix: accept legacy 'dm' in session key parsing for backward compat

getDmHistoryLimitFromSessionKey now accepts both :dm: and :direct:
to ensure old session keys continue to work correctly.

* test: add explicit backward compat tests for dmdirect migration

- session-key.test.ts: verify both :dm: and :direct: keys are valid
- getDmHistoryLimitFromSessionKey: verify both formats work

* feat: backward compat for resetByType.dm config key

* test: skip unix-path Nix tests on Windows
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling channel: bluebubbles Channel integration: bluebubbles channel: discord Channel integration: discord channel: feishu Channel integration: feishu channel: googlechat Channel integration: googlechat channel: imessage Channel integration: imessage channel: matrix Channel integration: matrix channel: mattermost Channel integration: mattermost channel: msteams Channel integration: msteams channel: nextcloud-talk Channel integration: nextcloud-talk channel: signal Channel integration: signal channel: slack Channel integration: slack channel: telegram Channel integration: telegram channel: tlon Channel integration: tlon channel: whatsapp-web Channel integration: whatsapp-web channel: zalo Channel integration: zalo docs Improvements or additions to documentation gateway Gateway runtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants