feat(slack): include thread metadata in agent context#6534
feat(slack): include thread metadata in agent context#6534bennewton999 wants to merge 41 commits intoopenclaw:mainfrom
Conversation
…gent context - Add thread_ts and parent_user_id to message metadata passed to agents - Enables agents to detect threaded replies and provide context-aware responses - Thread starters include thread_ts but not parent_user (they ARE the parent) - Includes comprehensive test coverage for both cases Fixes: Agents could not determine if Slack messages were thread replies
| // For thread starters, include thread_ts but not parent_user (the starter IS the parent) | ||
| const starterThreadInfo = starter.ts ? ` thread_ts: ${starter.ts}` : ""; | ||
| const starterWithId = `${starter.text}\n[slack message id: ${starter.ts ?? threadTs} channel: ${message.channel}${starterThreadInfo}]`; |
There was a problem hiding this comment.
[P1] Thread starter metadata uses the wrong timestamp
In the thread-starter envelope you’re building starterThreadInfo from starter.ts, but thread_ts should be the thread root timestamp (threadTs), not the root message’s ts (though they’re often equal). If starter.ts is missing, this currently omits thread_ts entirely even though threadTs is known, and if starter.ts differs it will mislabel the thread. This affects only thread replies where resolveSlackThreadStarter returns a starter with text.
Also, the comment says “include thread_ts” but the code only includes it when starter.ts is present.
Suggested fix: use threadTs (or starter.ts ?? threadTs) for thread_ts in the starter envelope.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/slack/monitor/message-handler/prepare.ts
Line: 470:472
Comment:
[P1] Thread starter metadata uses the wrong timestamp
In the thread-starter envelope you’re building `starterThreadInfo` from `starter.ts`, but `thread_ts` should be the thread root timestamp (`threadTs`), not the root message’s `ts` (though they’re often equal). If `starter.ts` is missing, this currently omits `thread_ts` entirely even though `threadTs` is known, and if `starter.ts` differs it will mislabel the thread. This affects only thread replies where `resolveSlackThreadStarter` returns a starter with `text`.
Also, the comment says “include thread_ts” but the code only includes it when `starter.ts` is present.
Suggested fix: use `threadTs` (or `starter.ts ?? threadTs`) for `thread_ts` in the starter envelope.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
✅ Fixed in 9ac4602 - now using threadTs instead of starter.ts for thread_ts metadata
| it("includes thread_ts and parent_user_id metadata in thread replies", async () => { | ||
| const slackCtx = createSlackMonitorContext({ | ||
| cfg: { | ||
| channels: { slack: { enabled: true } }, | ||
| } as OpenClawConfig, |
There was a problem hiding this comment.
[P3] Test name doesn’t match scope
These tests assert that ctxPayload.Body contains the metadata, but they don’t verify it’s specifically in the [slack message id: ...] footer or that top-level messages don’t get thread_ts. Consider tightening assertions (e.g., match the footer line) or renaming the tests to reflect that they validate Body output rather than “thread replies” behavior beyond that.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/slack/monitor/message-handler/prepare.inbound-contract.test.ts
Line: 148:152
Comment:
[P3] Test name doesn’t match scope
These tests assert that `ctxPayload.Body` contains the metadata, but they don’t verify it’s specifically in the `[slack message id: ...]` footer or that top-level messages don’t get `thread_ts`. Consider tightening assertions (e.g., match the footer line) or renaming the tests to reflect that they validate `Body` output rather than “thread replies” behavior beyond that.
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
✅ Fixed in 9ac4602 - improved assertions to use regex matching exact footer format and added test for top-level messages
…ions - Use threadTs (thread root) instead of starter.ts for thread_ts in starter metadata - Ensures thread_ts is always present when threadTs is known - Improve test assertions to verify exact message footer format - Add test to verify top-level messages exclude thread_ts Addresses code review feedback from greptile-apps
|
Thanks for the review @greptile-apps! I've addressed both issues: P1 - Thread starter timestamp: Fixed to use P3 - Test assertions: Improved test specificity:
Commit: 9ac4602 |
|
Perfect! I can see both fixes have been implemented correctly: ✅ P1 Fix - Thread starter timestamp: ✅ P3 Fix - Test assertions:
The commit stats (+81/-5 lines) reflect the substantial test improvements while keeping the core logic change minimal (just 2 lines changed in Both issues are now properly addressed. The thread metadata feature should work reliably across all Slack thread scenarios, and the tests provide robust verification of the expected message footer formats. |
* docs(discord): clarify exec approvals UI * Add link for slash command in Discord exec approvals Updated documentation to include a link for the slash command used in Discord exec approvals. * docs(discord): move exec approvals note * docs(discord): document exec approvals config * docs(discord): reorder exec approvals config --------- Co-authored-by: Luke K (pr-0f3t) <[email protected]>
Co-authored-by: hansbbans <[email protected]>
- Fix @1 -> $1 in landpr.md - Fix $@ -> $1 in reviewpr.md - Remove stray /reviewpr line from reviewpr.md - Delete old pr.md (replaced by reviewpr.md and landpr.md)
* improve exe.dev setup instructions 1. Fix device approval command 2. Clarify where Gateway token can be found * Update device approval instructions in exe-dev.md Clarify instructions for approving devices in OpenClaw.
…penclaw#6398) * security(message-tool): validate filePath/path against sandbox root * style: translate Polish comments to English for consistency
…penclaw#4610) * security(web): sanitize WhatsApp accountId to prevent path traversal Apply normalizeAccountId() from routing/session-key to resolveDefaultAuthDir() so that malicious config values like "../../../etc" cannot escape the intended auth directory. Fixes openclaw#2692 * fix(web): check sanitized segment instead of full path in Windows test * style(web): fix oxfmt formatting in accounts test
This reverts commit e4d5721.
…5926) Add timeout protection to prevent indefinite hangs when Urbit server becomes unresponsive or network partition occurs. Changes: - Add AbortSignal.timeout(30_000) to 7 one-shot fetch calls - Add AbortController with 60s connection timeout to SSE stream fetch (clears timeout after headers received to avoid aborting active stream) Affected methods: sendSubscription, connect, openStream, poke, scry, close Fixes openclaw#5266 Co-authored-by: Claude Opus 4.5 <[email protected]>
|
✅ Merged latest main and resolved conflicts.
|
|
Closing in favor of #14625 — clean rebase on latest main with the same feature, minus the accumulated merge noise from this branch. |
Summary
Adds thread metadata (
thread_tsandparent_user_id) to the message context passed to agents, enabling them to detect and respond to Slack threaded replies with context awareness.Problem
Agents currently cannot determine if a Slack message is a threaded reply because OpenClaw receives but doesn't expose thread metadata from the Slack API.
Before:
After:
Changes
src/slack/monitor/message-handler/prepare.tsto include thread metadata in message contextthread_tsandparent_user_id(when available)thread_tsonly (they ARE the parent, not a reply)prepare.inbound-contract.test.tsTesting
parent_user_idpresentparent_user_idUse Cases Enabled
Breaking Changes
None - this is additive metadata only.
Closes #6531
Greptile Overview
Greptile Summary
This PR augments the Slack inbound message formatting to append thread metadata (
thread_tsand optionalparent_user_id) into the message footer that’s embedded in the agent-visible context, and adds contract tests to assert the metadata appears for thread replies.The change is localized to the Slack monitor message preparation pipeline (
src/slack/monitor/message-handler/prepare.ts), which is responsible for shaping the finalizedMsgContextpayload passed into agent execution and session/history logic. The new tests (prepare.inbound-contract.test.ts) cover presence/absence ofparent_user_idin the emittedBodystring.Confidence Score: 4/5
thread_tsis computed for the thread starter envelope.starter.tsinstead of the known thread root timestamp and can omitthread_tswhenstarter.tsis missing, which undermines the feature’s stated contract for some thread-reply scenarios.(2/5) Greptile learns from your feedback when you react with thumbs up/down!