Skip to content

fix(slack-work-app): Add thread context in resume link messages - #3132

Merged
miles-kt-inkeep merged 6 commits into
mainfrom
fix/resume-link-in-thread
Apr 15, 2026
Merged

miles-kt-inkeep merged 6 commits into
mainfrom
fix/resume-link-in-thread

Conversation

@miles-kt-inkeep

Copy link
Copy Markdown
Contributor

No description provided.

@changeset-bot

changeset-bot Bot commented Apr 14, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 21ae2a0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 10 packages
Name Type
@inkeep/agents-work-apps Patch
@inkeep/agents-api Patch
@inkeep/agents-manage-ui Patch
@inkeep/agents-cli Patch
@inkeep/agents-core Patch
@inkeep/agents-email Patch
@inkeep/agents-mcp Patch
@inkeep/agents-sdk Patch
@inkeep/ai-sdk-provider Patch
@inkeep/create-agents Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Apr 14, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agents-api Ready Ready Preview, Comment Apr 15, 2026 1:23pm
agents-docs Ready Ready Preview, Comment Apr 15, 2026 1:23pm
agents-manage-ui Ready Ready Preview, Comment Apr 15, 2026 1:23pm

Request Review

@github-actions

github-actions Bot commented Apr 14, 2026 •

Copy link
Copy Markdown
Contributor

This public PR was merged directly in the public repo. The matching monorepo PR was left open for manual follow-up because agents-private remains the source of truth.

Matching internal PR: #97

@pullfrog

pullfrog Bot commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Summary

When a user sends a "resume link" message inside a Slack thread, the agent now receives the surrounding thread context — giving it the same conversational awareness that regular mention-based interactions already have.

Changes

Thread context for resume-link messages (resume-intent.ts)

Both resumeMention and resumeDirectMessage now:

  1. Detect whether the message is inside a thread (intent.threadTs !== intent.messageTs).
  2. Fetch thread context via getThreadContext in parallel with the existing Promise.all calls — no sequential overhead added.
  3. Pass threadContext into formatSlackQuery so the agent prompt includes prior thread messages.

Changeset

Patch bump for @inkeep/agents-work-apps.

Pullfrog  | View workflow run | Triggered by Pullfrog | Using Claude Opus | 𝕏

@pullfrog

pullfrog Bot commented Apr 14, 2026 •

Copy link
Copy Markdown
Contributor

Thread context for resume-link messages

When a user clicks a "resume" link inside a Slack thread, the agent now receives the surrounding thread context — the same context it already gets for regular mention-based interactions.

What changed

packages/agents-work-apps/src/slack/services/resume-intent.ts

Both resumeMention and resumeDirectMessage now:

  1. Detect whether the intent originated inside a thread (intent.threadTs !== intent.messageTs).
  2. If so, fetch the thread context via getThreadContext — in parallel with the other Slack API calls (Promise.all).
  3. Pass threadContext into formatSlackQuery, giving the agent visibility into the conversation the user is resuming from.

packages/agents-work-apps/src/__tests__/slack/resume-intent.test.ts

Adds a mock for getThreadContext and updates the existing resumeMention test to verify:

  • getThreadContext is called with the correct channel and thread timestamp.
  • formatSlackQuery receives the thread context.
  • The final question passed to handleSlackInteraction includes the thread context prepended.

Changeset

@inkeep/agents-work-apps — patch

Pullfrog  | View workflow run | Triggered by Pullfrog | Using Claude Opus | 𝕏

@pullfrog pullfrog 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.

Clean, focused change. The getThreadContext integration follows the same pattern used in app-mention.ts and direct-message.ts. isInThread logic, the Promise.all parallelization, and the threadContext || undefined coercion to avoid rendering empty <slack_thread_context> blocks are all correct. The DM path also gets a nice perf improvement by parallelizing the getSlackUserInfo call.

Pullfrog  | View workflow run | Using Claude Opus | 𝕏

@claude claude 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.

PR Review Summary

(0) Total Issues | Risk: Low

This PR adds thread context support to the resumeMention and resumeDirectMessage functions in the Slack work app. The changes are minimal, well-structured, and follow existing codebase patterns.

What Changed

  1. resumeMention (lines 159-179): Added thread context retrieval using the same isInThread pattern used elsewhere in the codebase (app-mention.ts, direct-message.ts, block-actions.ts). The getThreadContext call is correctly parallelized with existing async operations via Promise.all.

  2. resumeDirectMessage (lines 238-255): Same pattern applied consistently. Previously a single await for getSlackUserInfo, now correctly parallelized with getThreadContext.

  3. Changeset: Appropriate patch bump for @inkeep/agents-work-apps.

Review Notes

✅ Correctness: The isInThread check (Boolean(intent.threadTs && intent.threadTs !== intent.messageTs)) correctly matches the established pattern in peer files.

✅ Performance: Thread context is fetched in parallel with other async operations, maintaining the existing performance characteristics.

✅ Consistency: The threadContext || undefined conversion properly handles the empty-string-to-undefined transform for the optional threadContext field in FormatSlackQueryOptions.

✅ Edge cases: When not in a thread, Promise.resolve('') is returned, avoiding unnecessary API calls.


✅ APPROVE

Summary: Clean, well-structured bugfix that adds thread context to resume link messages in Slack. The implementation follows established patterns perfectly and parallelizes async operations appropriately. Ship it! 🚢

Reviewers (2)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
pr-review-standards 0 0 0 0 0 0 0
pr-review-consistency 0 0 0 0 0 0 0
Total 0 0 0 0 0 0 0

@github-actions github-actions Bot deleted a comment from claude Bot Apr 14, 2026
@github-actions

github-actions Bot commented Apr 14, 2026 •

Copy link
Copy Markdown
Contributor

Preview URLs

Use these stable preview aliases for testing this PR:

These point to the same Vercel preview deployment as the bot comment, but they stay stable and easier to find.

Raw Vercel deployment URLs

@claude claude 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.

PR Review Summary

(0) Total Issues | Risk: Low

This is a re-review scoped to the delta since the last automated review (commit b3d673358).

Delta Review

1 commit (fix test) — 1 file (resume-intent.test.ts, +11/-2)

The delta adds proper test coverage for the thread context functionality that was already approved in the previous review:

  1. Mock addition (line 57): Added getThreadContext mock returning sample thread messages
  2. Verification (lines 149-153): Test now verifies getThreadContext is called with correct channel and thread timestamp
  3. Output assertion (lines 142, 157): Test validates the formatted question includes thread context prefix and that formatSlackQuery receives the threadContext parameter

✅ Correctness: Test assertions correctly verify the thread context integration added in resume-intent.ts

✅ Test pattern: Uses existing mock patterns (vi.fn().mockResolvedValue) consistent with the rest of the test file

✅ Coverage: The test now properly verifies the full thread context flow for the mention entry point


✅ APPROVE

Summary: Clean test fix that completes the thread context feature. The delta correctly adds test coverage for the getThreadContext call and validates the formatted output includes thread messages. Ready to ship! 🚀

Reviewers (0)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
Total 0 0 0 0 0 0 0

Note: No reviewers dispatched — delta is test-only updates that align with already-approved implementation.

@github-actions github-actions Bot deleted a comment from claude Bot Apr 14, 2026

@claude claude 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.

PR Review Summary

(0) Total Issues | Risk: Low

This is a re-review scoped to the delta since the last automated review (commit 4b9987c98).

Delta Review

1 commit (fix raw query build error) — 1 file (agents-api/tsdown.config.ts, +9/-0)

The delta adds a resolveId hook to the rawQueryPlugin in the tsdown build configuration:

resolveId(source, importer) {
  if (!source.endsWith(rawQuery)) return;
  const basePath = source.slice(0, -rawQuery.length);
  const resolved = importer
    ? path.resolve(path.dirname(importer), basePath)
    : path.resolve(basePath);
  return resolved + rawQuery;
}

✅ Correctness: The implementation follows standard Rollup/tsdown plugin conventions. It properly:

  1. Strips the ?raw suffix to get the base path
  2. Resolves relative paths using path.dirname(importer) when an importer exists
  3. Falls back to path.resolve(basePath) for entry points without importers
  4. Re-appends the ?raw marker for the load hook to process

✅ Root cause fix: The prior load hook was receiving unresolved relative paths (e.g., ../../../../../../templates/v1/prompt/system-prompt.xml?raw) which fs.readFile cannot resolve. The new resolveId hook ensures absolute paths are passed to load.

✅ Consistency: Aligns with the existing load hook's path handling logic.


✅ APPROVE

Summary: Clean build tooling fix that resolves the ?raw import path resolution issue. The resolveId implementation is correct and follows standard plugin patterns. Combined with the previously-approved thread context feature, this PR is ready to ship! 🚀

Reviewers (2)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
pr-review-devops 0 0 0 0 0 0 0
pr-review-standards 0 0 0 0 0 0 0
Total 0 0 0 0 0 0 0

@github-actions github-actions Bot deleted a comment from claude Bot Apr 14, 2026
@vercel
vercel Bot temporarily deployed to Preview – agents-docs April 14, 2026 21:50 Inactive

@claude claude 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.

PR Review Summary

(0) Total Issues | Risk: Low

This is a re-review scoped to the delta since the last automated review (commit 114222355).

Delta Review

1 commit (revert tsdown changes) — 1 file (agents-api/tsdown.config.ts, -9 lines)

The delta reverts the resolveId hook that was added in the previous commit (fix raw query build error). This brings tsdown.config.ts back to its state on main, removing an unrelated build tooling change from the PR scope.

✅ Correctness: The revert is clean and complete — the file now matches main. The rawQueryPlugin remains functional with just the load hook, as it was before this PR.

✅ PR scope: The final PR diff now only contains the intended thread context feature:

  • resume-intent.ts — thread context retrieval for mention and DM resume flows
  • resume-intent.test.ts — test coverage for the new functionality
  • Changeset for @inkeep/agents-work-apps

✅ No regression: The build fix was unrelated to the thread context feature and its removal doesn't affect the core functionality being shipped.


✅ APPROVE

Summary: Clean housekeeping commit that removes an unrelated build tooling experiment from the PR. The thread context feature (previously approved) remains intact. Ready to ship! 🚀

Reviewers (0)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
Total 0 0 0 0 0 0 0

Note: No domain-specific reviewers dispatched — delta is a revert that cleans up PR scope. The core feature was already reviewed and approved in prior review runs.

@github-actions github-actions Bot deleted a comment from claude Bot Apr 14, 2026
@itoqa

itoqa Bot commented Apr 14, 2026

Copy link
Copy Markdown

Ito Test Report ✅

14 test cases ran. 14 passed.

All 14 test cases passed with zero failures, showing the Slack /link and /work-apps/slack/users/link/verify-token experience is stable on local endpoints across core, edge, resilience, and security coverage. Key findings were successful linking for mention-thread, DM-thread, and backward-compatible non-thread tokens; correct unauthenticated routing with preserved returnUrl and no verification call on bare /link; safe handling of expired/tampered/injection-like tokens; bounded behavior under refresh/replay race and mobile viewport checks; and strong authorization/anti-spoof controls that reject API-key or system identities and bind linking to the authenticated session user.

✅ Passed (14)
Category Summary Screenshot
Adversarial Tampered JWT was safely rejected in UI and API with controlled 400-class validation errors and no success response. ADV-1
Adversarial API-key and system bearer identities were rejected by verify-token with 403 session-auth-required responses. ADV-2
Adversarial A spoofed body userId did not hijack ownership; linking remained bound to the authenticated session user. ADV-3
Adversarial Same-token two-tab and replay checks remained deterministic without 5xx/crash behavior. ADV-4
Adversarial Injection-like payload in token intent did not execute script code (no alert/dialog), and flow remained in safe UI behavior. ADV-5
Edge Expired token produced explicit recovery guidance in UI and deterministic 400 API rejection with safe message; no success state observed. EDGE-1
Edge Direct unauthenticated /link showed /inkeep link guidance and did not trigger a verify-token API request. EDGE-2
Edge Throttled refresh during token linking stayed stable with bounded verify-token traffic and a successful terminal state. EDGE-3
Edge Mobile 390x844 flows kept sign-in/success/guidance states readable with no horizontal overflow. EDGE-4
Edge Back/forward during token login preserved returnUrl/token, and post-login /link completed once into a stable Account Linked state. EDGE-5
Logic Non-thread mention variants (equal message/thread timestamp and missing threadTs) both linked successfully. LOGIC-1
Happy-path Mention-thread token linking reached stable Account Linked state with successful verification. ROUTE-1
Happy-path DM-thread token linking completed successfully with a stable success UI and verify-token success. ROUTE-2
Happy-path Unauthenticated /link?token=... showed the sign-in gate and redirected to login with URL-encoded returnUrl preserving the original token. ROUTE-3

Commit: c2aa4a9

View Full Run


Tell us how we did: Give Ito Feedback

@claude claude 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.

PR Review Summary

(0) Total Issues | Risk: Low

This is a re-review scoped to the delta since the last automated review (commit c2aa4a9ecf83).

Delta Review

1 commit (Merge branch 'main' into fix/resume-link-in-thread) — brings in unrelated changes from main (Microsoft SSO feature #3134 + version packages #3131).

The PR's feature files (resume-intent.ts, resume-intent.test.ts, changeset) are unchanged since the prior review. No new code to evaluate.

Prior Review Summary

The core feature was thoroughly reviewed in 4 prior automated reviews, all with 0 findings:

✅ Pattern consistency: The isInThread check (Boolean(intent.threadTs && intent.threadTs !== intent.messageTs)) matches established patterns in app-mention.ts, direct-message.ts, block-actions.ts, and modal-submission.ts.

✅ Performance: getThreadContext is parallelized via Promise.all with existing async operations — no sequential overhead added.

✅ Correctness: The threadContext || undefined coercion properly handles empty-string-to-undefined conversion for the optional threadContext field.

✅ Test coverage: The test correctly verifies getThreadContext is called with the right arguments and that the formatted question includes thread context.

✅ Changeset: Appropriate patch bump for @inkeep/agents-work-apps.


✅ APPROVE

Summary: The delta is a clean merge from main with no changes to the PR's feature code. The thread context implementation (previously approved) follows established Slack event handler patterns perfectly. Ship it! 🚀

Reviewers (0)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
Total 0 0 0 0 0 0 0

Note: No domain-specific reviewers dispatched — delta is a merge commit with no changes to the PR's feature code. The core implementation was already reviewed and approved in 4 prior runs.

@github-actions github-actions Bot deleted a comment from claude Bot Apr 15, 2026
@miles-kt-inkeep
miles-kt-inkeep added this pull request to the merge queue Apr 15, 2026
Merged via the queue into main with commit 7438f76 Apr 15, 2026
27 checks passed
@miles-kt-inkeep
miles-kt-inkeep deleted the fix/resume-link-in-thread branch April 15, 2026 13:47
@itoqa

itoqa Bot commented Apr 15, 2026

Copy link
Copy Markdown

Ito Test Report ✅

14 test cases ran. 14 passed.

Across a unified local non-production run, all 14 test cases passed (0 failed), with core Slack /link journeys working end-to-end: mention and DM tokens both returned verify-token HTTP 200 and reached “Account Linked,” unauthenticated visits correctly redirected to /login with a single preserved returnUrl, /link without a token stayed instructional without firing verification, and mobile (390x844) remained usable without overflow. Critical resilience and security checks also held: expired/tampered/oversized or invalid tokens produced controlled errors, non-session callers were blocked with HTTP 403/session-required messaging, boundary and concurrency cases (threadTs==messageTs, duplicate submits, concurrent tabs) settled safely, and adversarial thread-context scenarios (prompt-injection and cross-channel mismatch) showed stable behavior with no leakage, matching code-review expectations and confirming no product defects in scope.

✅ Passed (14)
Category Summary Screenshot
Adversarial Not a real application bug. Code path correctly rejects tampered JWTs and re-execution confirmed controlled error UI ('signature verification failed') instead of success. ADV-1
Adversarial An oversized URL-encoded script-laced token (>8KB) produced a controlled validation error ('Invalid Compact JWS') while the /link UI stayed responsive, with no popup/script execution or token echo. ADV-2
Adversarial Not a real application bug. Route correctly enforces session-user requirement and rejects non-session identity with HTTP 403 + 'Session authentication required for account linking'. ADV-3
Adversarial Injection-token link flow reached stable "Account Linked" state without crash/hang. ADV-4
Adversarial Cross-channel mismatch token flow stayed stable with controlled verify behavior and no visible leakage artifacts. ADV-5
Edge Expired token flow redirected through sign-in and returned deterministic /inkeep link guidance without spinner lock. N/A
Edge Boundary token (threadTs == messageTs) linked successfully and code path treats it as non-thread context. N/A
Edge Duplicate in-mount verify submissions are guarded by linkingRef + waiting-state gate; no defect confirmed. N/A
Edge Concurrent tabs using a fresh token both reached controlled settled states (Account Linked) without hanging. N/A
Edge On 390x844 mobile viewport, CTA remained reachable, redirect preserved returnUrl, and invalid-token state stayed readable without horizontal overflow. EDGE-5
Happy-path Mention token link flow reached Account Linked with verify-token HTTP 200. ROUTE-1
Happy-path DM token link flow reached Account Linked with verify-token HTTP 200. ROUTE-2
Screen Logged-out token flow showed Connect + Sign in CTA, redirect to /login preserved encoded returnUrl with token exactly once, and mobile checks remained usable. SCREEN-1
Screen Authenticated /link without token stayed in instructional state and did not trigger verify-token requests. SCREEN-2

Commit: 21ae2a0

View Full Run


Tell us how we did: Give Ito Feedback

This branch was successfully deployed

3 active deployments
Preview – agents-api — 21ae2a07 Deployed Apr 15, 2026 by vercel[bot]
Preview – agents-docs — 21ae2a07 Deployed Apr 15, 2026 by vercel[bot]
Preview – agents-manage-ui — 21ae2a07 Deployed Apr 15, 2026 by vercel[bot]
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.

1 participant