Skip to content

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Jan 5, 2026

Summary

This PR refactors the chat context system to store references (IDs) instead of content, resolving content only at send time. This addresses issues with stale context, hidden context visibility, and lack of manual control over what context is attached to chat.

Key changes:

  • Context Refs State: New ContextRef type and state management in useChatMode (refs, addRef, removeRef, clearRefs)
  • ContextBar UI: New component displaying attached context as removable chips above the input
  • Auto-sync from Tabs: Open session tabs automatically add/remove context refs
  • Lazy Resolution: useTransport now accepts refs and resolves content from store/indexes at send time
  • Slash Command: Selecting a session via / now adds it as a context ref instead of inserting a mention (new onSelect callback in tiptap)

Review & Testing Checklist for Human

  • Test chat with session context: Open a session tab, open chat, send a message - verify the LLM receives the session's transcript/notes as context
  • Test ContextBar display: Verify chips appear showing attached sessions, and the X button removes them
  • Test slash command: Type / and select a session - verify it adds to ContextBar (not inserted as text). This uses a new onSelect callback in the tiptap mention extension.
  • Test tab switching: Switch between session tabs and verify auto-sync adds/removes refs correctly (watch for any infinite loop behavior)
  • Test multiple sessions: Add multiple sessions via slash command - note that currently only the first session's content is used for context (intentional limitation)

Notes

The resolution logic in useTransport was changed from using React hooks (useSession, main.UI.useSliceRowIds) to direct store/indexes access (store.getRow, indexes.getSliceRowIds). This is intentional to enable lazy resolution but changes the reactivity model.

Updates since last revision:

  • Fixed TypeScript errors: now correctly uses main.UI.useIndexes() to get the indexes instance for calling getSliceRowIds, rather than incorrectly calling it on the store object.

Link to Devin run: https://app.devin.ai/sessions/e583e4169beb43088b5d3b58fcb95ec2
Requested by: @yujonglee ([email protected])

- Add context refs state to useChatMode (refs, addRef, removeRef, clearRefs)
- Create ContextBar component to display context refs as chips
- Implement auto-sync from open tabs to refs
- Move resolution logic to useTransport (lazy loading at send time)
- Update slash command to add refs instead of inserting text for sessions
- Remove old attachedSessionId flow from ChatMessageInput

Co-Authored-By: yujonglee <[email protected]>
@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@netlify
Copy link

netlify bot commented Jan 5, 2026

Deploy Preview for howto-fix-macos-audio-selection canceled.

Name Link
🔨 Latest commit 32b76cc
🔍 Latest deploy log https://app.netlify.com/projects/howto-fix-macos-audio-selection/deploys/695b5def66b110000836cb48

@netlify
Copy link

netlify bot commented Jan 5, 2026

Deploy Preview for hyprnote-storybook canceled.

Name Link
🔨 Latest commit 32b76cc
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote-storybook/deploys/695b5def46c1ad0008f94074

@netlify
Copy link

netlify bot commented Jan 5, 2026

Deploy Preview for hyprnote ready!

Name Link
🔨 Latest commit 32b76cc
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote/deploys/695b5def415e560008c95ade
😎 Deploy Preview https://deploy-preview-2820--hyprnote.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

- Use main.UI.useIndexes to get the indexes instance
- Call getSliceRowIds on indexes instead of store
- Remove unused useMemo import from view.tsx

Co-Authored-By: yujonglee <[email protected]>
Comment on lines +58 to +69
const addRef = useCallback((ref: ContextRef) => {
setRefs((prev) => {
if (prev.some((r) => r.type === ref.type && r.id === ref.id)) {
return prev;
}
return [...prev, ref];
});
}, []);

const removeRef = useCallback((id: string) => {
setRefs((prev) => prev.filter((r) => r.id !== id));
}, []);
Copy link
Contributor

Choose a reason for hiding this comment

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

Duplicate detection vs removal logic mismatch

addRef prevents duplicates by checking both type and id (line 60), but removeRef only filters by id (line 68). This creates an inconsistency:

  • If two refs exist with the same id but different type (e.g., {type: "session", id: "123"} and {type: "human", id: "123"}), they can coexist
  • But calling removeRef("123") will remove BOTH refs, not just the intended one
  • In context-bar.tsx line 22, clicking remove on one chip will unexpectedly remove other chips with the same ID
// Fix: Match the removal logic to the duplicate check
const removeRef = useCallback((type: ContextRefType, id: string) => {
  setRefs((prev) => prev.filter((r) => !(r.type === type && r.id === id)));
}, []);
Suggested change
const addRef = useCallback((ref: ContextRef) => {
setRefs((prev) => {
if (prev.some((r) => r.type === ref.type && r.id === ref.id)) {
return prev;
}
return [...prev, ref];
});
}, []);
const removeRef = useCallback((id: string) => {
setRefs((prev) => prev.filter((r) => r.id !== id));
}, []);
const addRef = useCallback((ref: ContextRef) => {
setRefs((prev) => {
if (prev.some((r) => r.type === ref.type && r.id === ref.id)) {
return prev;
}
return [...prev, ref];
});
}, []);
const removeRef = useCallback((type: ContextRefType, id: string) => {
setRefs((prev) => prev.filter((r) => !(r.type === type && r.id === id)));
}, []);

Spotted by Graphite Agent

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

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