-
Notifications
You must be signed in to change notification settings - Fork 553
feat: implement @agent-mention UI with fuzzy finding in WUI #745
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: implement @agent-mention UI with fuzzy finding in WUI #745
Conversation
Adds support for @agent mentions in the Claude Code WUI prompt input, enabling users to reference sub-agents defined in .claude/agents/ directories. Backend changes: - Add /api/v1/agents/discover endpoint to scan and parse agent YAML files - Wire up AgentHandlers in server implementation - Add YAML parsing dependency for agent frontmatter Frontend changes: - Extend FuzzyFileMentionList to fetch and display agents alongside files - Show agents with HatGlasses icon in dropdown (fixed from HardHatIcon) - Update FileMentionNode to detect and render agent mentions with correct icon - Fix double @ symbol issue by stripping @ from both id and label fields - Add fuzzy matching for agent names using fuzzy npm package Fixes: - Replace HardHatIcon with correct HatGlasses icon for agents - Remove double @ symbol in mention badges (strip from both id and label) - Show correct icon in mention badges based on type (agent/file/directory) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Important
Looks good to me! 👍
Reviewed everything up to 41509ce in 1 minute and 39 seconds. Click for details.
- Reviewed
1863lines of code in21files - Skipped
0files when reviewing. - Skipped posting
3draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. humanlayer-wui/src/components/internal/SessionDetail/components/FuzzyFileMentionList.tsx:134
- Draft comment:
Verify that the fuzzy library returns the matched character positions in the property used. Using 'result.index || []' assumes the property is named 'index'; some implementations may return 'indexes' instead. Ensure this aligns with the library’s output. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%The comment is asking the PR author to verify the behavior of a library, which violates the rule against asking for confirmation or verification. It does not provide a specific suggestion or point out a clear issue with the code. Therefore, it should be removed.
2. humanlayer-wui/src/components/internal/SessionDetail/components/FuzzyFileMentionList.tsx:189
- Draft comment:
The ArrowUp key handler uses a modulo expression with '|| 0'. Since modulo always yields a valid index when results.length > 0, the '|| 0' may be redundant and could be simplified for clarity. - Reason this comment was not posted:
Comment was not on a location in the diff, so it can't be submitted as a review comment.
3. humanlayer-wui/src/components/internal/SessionDetail/components/FuzzyFileMentionList.tsx:102
- Draft comment:
Consider using Promise.allSettled instead of Promise.all when fetching files and agents. This would enable handling partial results if one API call fails, rather than causing the entire search to fail. - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 30% vs. threshold = 50% The suggestion has merit - Promise.allSettled would allow showing partial results if one API fails. However, the current error handling is intentionally conservative - if either request fails, it shows an error and clears results. This is a reasonable UX choice since partial results could be confusing. The current approach is simpler and clearer. The comment identifies a real technical possibility for improvement. Partial results could be better than no results in some cases. While technically possible, the current all-or-nothing approach is a valid design choice that keeps the UX simpler and more predictable. The comment suggests a change without clear evidence it would improve the user experience. The comment should be removed. While technically valid, it suggests a change to intentional error handling behavior without strong evidence it would improve the user experience.
Workflow ID: wflow_yN8jLdAMbDwlrA36
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
…andlers - Update test files to use new constant names (api.SlashCommandSourceLocal/Global) - Add AgentHandlers parameter to NewServerImpl calls in test files - Replace deprecated ioutil.ReadFile with os.ReadFile 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Important
Looks good to me! 👍
Reviewed 983aaf5 in 1 minute and 5 seconds. Click for details.
- Reviewed
144lines of code in4files - Skipped
0files when reviewing. - Skipped posting
5draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. hld/api/handlers/agents.go:41
- Draft comment:
The regex '^[a-z-]+$' is very strict. Confirm that this pattern meets all agent naming requirements. If agents might need to include digits or underscores in the future, consider updating the regex. - Reason this comment was not posted:
Comment was not on a location in the diff, so it can't be submitted as a review comment.
2. hld/api/handlers/agents.go:85
- Draft comment:
Replacing ioutil.ReadFile with os.ReadFile is appropriate and follows modern Go best practices since ioutil is deprecated. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
3. hld/api/handlers/files_test.go:274
- Draft comment:
The call to NewServerImpl has been updated to include a nil for AgentHandlers. This ensures the test suite remains compatible with the new server signature. Verify that passing nil here is acceptable for tests not involving agent functionality. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
4. hld/api/handlers/sessions_slash_commands_test.go:327
- Draft comment:
The tests now consistently use the updated constants (api.SlashCommandSourceLocal and api.SlashCommandSourceGlobal) instead of the old api.Local/api.Global. This improves clarity in command source assignments—ensure that all scenarios reflect this change correctly. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
5. hld/api/handlers/testutil_test.go:27
- Draft comment:
Passing nil for AgentHandlers in the NewServerImpl call aligns with the updated constructor signature and ensures tests that don't involve agent functionality remain unaffected. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
Workflow ID: wflow_pgM8PB6ACrx7mfXW
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
- Keep full @agent-<name> in id field (don't strip @) so it gets inserted into text - Only strip @ from label field for visual display in badge - Update agent detection to check for '@agent-' prefix since id now includes @ This ensures the actual text inserted and sent to Claude is @agent-<name> 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Important
Looks good to me! 👍
Reviewed ef67dd8 in 1 minute and 17 seconds. Click for details.
- Reviewed
41lines of code in2files - Skipped
0files when reviewing. - Skipped posting
2draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. humanlayer-wui/src/components/internal/SessionDetail/components/FileMentionNode.tsx:17
- Draft comment:
Updated agent-check to use '@agent-' prefix. Ensure that the backend consistently provides IDs with an '@' so that the condition (id.startsWith('@agent-')) works as expected. - Reason this comment was not posted:
Comment looked like it was already resolved.
2. humanlayer-wui/src/components/internal/SessionDetail/components/FuzzyFileMentionList.tsx:215
- Draft comment:
For agent selections, the id now keeps the full '@agent-' while the label strips the '@'. Confirm that this behavior is consistent across the mention system to avoid double '@' in rendering. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%The comment is asking the PR author to confirm that a specific behavior is consistent across the system. This falls under the rule of not asking the author to confirm their intention or ensure behavior is intended. Therefore, this comment should be removed.
Workflow ID: wflow_Cw4SbaUh8TyYxDXY
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
The constants api.Global and api.Local were renamed in PR #745 to be values of the SlashCommandSource type. This updates the integration tests to use the new constant format. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Important
Looks good to me! 👍
Reviewed b36df9e in 1 minute and 25 seconds. Click for details.
- Reviewed
35lines of code in1files - Skipped
0files when reviewing. - Skipped posting
3draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. hld/daemon/daemon_slash_commands_integration_test.go:226
- Draft comment:
Using api.SlashCommandSource("global") instead of a raw constant improves type consistency. If possible, use a well-named constant (e.g., api.SlashCommandSourceGlobal) to avoid typos in the literal string. - Reason this comment was not posted:
Comment looked like it was already resolved.
2. hld/daemon/daemon_slash_commands_integration_test.go:250
- Draft comment:
Similarly, update the duplicate command test to use api.SlashCommandSource("global"). Consider using a shared constant for the expected source value for clarity. - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 30% vs. threshold = 50% The suggestion to use a shared constant is a reasonable code quality improvement. Having the string "global" repeated multiple times could lead to maintenance issues if it needs to change. However, this is a test file, and the string literal makes the test more readable and self-contained. The suggestion is not critical enough to warrant keeping the comment. The comment suggests a valid improvement, but am I being too dismissive of test code quality? Test code is still code that needs to be maintained. While test code quality matters, the current approach using string literals makes the tests more readable and self-documenting. The risk of the "global" string needing to change is low, and the benefit of explicit values in tests often outweighs the DRY principle. Delete the comment. While using a constant is a valid suggestion, the current approach with string literals is acceptable for test code and may even be preferable for readability.
3. hld/daemon/daemon_slash_commands_integration_test.go:308
- Draft comment:
The comparisons for both global and local sources now use api.SlashCommandSource("global") and api.SlashCommandSource("local"). For improved maintainability, consider defining and using constants for these source values if available. - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 20% vs. threshold = 50% This is a test file, and the change being made is just switching from api.Global to api.SlashCommandSource("global"). The suggestion to use constants could be valid, but without seeing the api package we don't know if these constants already exist. Additionally, since this is a test file, the explicitness of using string literals might actually be preferable for readability. I don't have visibility into the api package to know if constants already exist. The comment might be suggesting something that's already available. Even without seeing the api package, suggesting constants in a test file is less compelling since test code often benefits from being explicit rather than abstract. Delete the comment. While using constants could be valid, we don't have enough context about the api package to know if it's a useful suggestion, and test files often benefit from explicit values.
Workflow ID: wflow_3Au5M0A9OZMrqery
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
b36df9e to
ef67dd8
Compare
The integration tests were still using the old api.Global and api.Local constants which were renamed to api.SlashCommandSourceGlobal and api.SlashCommandSourceLocal in the API generation update. This was causing CI failures while tests passed locally due to cached or outdated generated files. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Important
Looks good to me! 👍
Reviewed e3f52dd in 57 seconds. Click for details.
- Reviewed
35lines of code in1files - Skipped
0files when reviewing. - Skipped posting
3draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. hld/daemon/daemon_slash_commands_integration_test.go:226
- Draft comment:
Good use of the new api.SlashCommandSourceGlobal constant here instead of the deprecated api.Global. This update improves consistency with the API spec. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
2. hld/daemon/daemon_slash_commands_integration_test.go:250
- Draft comment:
The duplicate command test now correctly asserts the global source using api.SlashCommandSourceGlobal. Ensure all duplicate checks follow this updated convention. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
3. hld/daemon/daemon_slash_commands_integration_test.go:308
- Draft comment:
Updated conditional checks to use api.SlashCommandSourceGlobal and api.SlashCommandSourceLocal instead of the old constants. This enhances consistency across the tests. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
Workflow ID: wflow_pKOh29u5rSokCJ8b
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
What problem(s) was I solving?
Users couldn't easily reference Claude Code sub-agents in the WUI prompt input. While Claude supports sub-agents through the Task tool, there was no UI affordance to discover and mention them using the familiar
@pattern that works for files. Users had to remember exact agent names and type them manually.What user-facing changes did I ship?
@to see available sub-agents alongside files in the mention dropdown.claude/agents/(local) and~/.claude/agents/(global) directories@code) to filter agents using fuzzy matching@agent-<name>mentions that Claude recognizes and can invokeHow I implemented it
Backend (Go daemon)
/api/v1/agents/discoverendpoint that scans.claude/agents/directories for markdown files with YAML frontmatter---markers@agent-<name>format ready for mentionsFrontend (React/TypeScript)
FuzzyFileMentionListcomponent to fetch agents alongside files when@is typedfuzzynpm packageFileMentionNodeto detect agent mentions and render with appropriate HatGlasses iconHardHatIconwithHatGlassesicon@symbol issue by stripping@from both id and label fieldsAPI Changes
/agents/discoverendpoint andAgentschemaHow to verify it
Manual Testing
@in the prompt input@codeand verify it matches@agent-codebase-locator@weband verify it matches@agent-web-search-researcher@agent-<name>(single@, not double).claude/agents/test.mdwith valid YAML frontmatterAutomated Verification
make -C humanlayer-wui checkmake -C hld check(fails due to unrelated test constant renaming)curl -X POST http://localhost:2136/api/v1/agents/discover -H "Content-Type: application/json" -d '{"workingDir": "."}'Description for the changelog
feat: Add @agent-mention support in WUI prompt input with fuzzy search and visual distinction using HatGlasses icon
https://www.loom.com/share/8ab2053b1e8b4c59861c567fadf652da
Important
Adds
@agentmention support in WUI with fuzzy search and visual distinction using HatGlasses icon, including backend agent discovery and frontend integration.@agentmentions in WUI, allowing users to type@to see available sub-agents and files..claude/agents/(local) and~/.claude/agents/(global) directories.fuzzynpm package./api/v1/agents/discoverendpoint inagents.goto discover agents from directories.FuzzyFileMentionListinFuzzyFileMentionList.tsxto include agents in search results.FileMentionNodeinFileMentionNode.tsxto render agent mentions with HatGlasses icon./agents/discoverendpoint andAgentschema.fuzzypackage topackage.jsonfor fuzzy search functionality.This description was created by
for e3f52dd. You can customize this summary. It will automatically update as commits are pushed.