Skip to content

Feature/improve goto anything commands#24091

Merged
crazywoola merged 6 commits intolanggenius:mainfrom
ZeroZ-lab:feature/improve-goto-anything-commands
Aug 18, 2025
Merged

Feature/improve goto anything commands#24091
crazywoola merged 6 commits intolanggenius:mainfrom
ZeroZ-lab:feature/improve-goto-anything-commands

Conversation

@ZeroZ-lab
Copy link
Copy Markdown
Contributor

@ZeroZ-lab ZeroZ-lab commented Aug 18, 2025

Important

  1. Make sure you have read our contribution guidelines
  2. Ensure there is an associated issue and you have been assigned to it
  3. Use the correct syntax to link this PR: Fixes #<issue number>.

Summary

fix #24088

/**
 * Goto Anything - Action System
 *
 * This file defines the action registry for the goto-anything search system.
 * Actions handle different types of searches: apps, knowledge bases, plugins, workflow nodes, and commands.
 *
 * ## How to Add a New Slash Command
 *
 * 1. **Create Command Handler File** (in `./commands/` directory):
 *    ```typescript
 *    // commands/my-command.ts
 *    import type { SlashCommandHandler } from './types'
 *    import type { CommandSearchResult } from '../types'
 *    import { registerCommands, unregisterCommands } from './command-bus'
 *
 *    interface MyCommandDeps {
 *      myService?: (data: any) => Promise<void>
 *    }
 *
 *    export const myCommand: SlashCommandHandler<MyCommandDeps> = {
 *      name: 'mycommand',
 *      aliases: ['mc'], // Optional aliases
 *      description: 'My custom command description',
 *
 *      async search(args: string, locale: string = 'en') {
 *        // Return search results based on args
 *        return [{
 *          id: 'my-result',
 *          title: 'My Command Result',
 *          description: 'Description of the result',
 *          type: 'command' as const,
 *          data: { command: 'my.action', args: { value: args } }
 *        }]
 *      },
 *
 *      register(deps: MyCommandDeps) {
 *        registerCommands({
 *          'my.action': async (args) => {
 *            await deps.myService?.(args?.value)
 *          }
 *        })
 *      },
 *
 *      unregister() {
 *        unregisterCommands(['my.action'])
 *      }
 *    }
 *    ```
 *
 * **Example for Self-Contained Command (no external dependencies):**
 *    ```typescript
 *    // commands/calculator-command.ts
 *    export const calculatorCommand: SlashCommandHandler = {
 *      name: 'calc',
 *      aliases: ['calculator'],
 *      description: 'Simple calculator',
 *
 *      async search(args: string) {
 *        if (!args.trim()) return []
 *        try {
 *          // Safe math evaluation (implement proper parser in real use)
 *          const result = Function('"use strict"; return (' + args + ')')()
 *          return [{
 *            id: 'calc-result',
 *            title: `${args} = ${result}`,
 *            description: 'Calculator result',
 *            type: 'command' as const,
 *            data: { command: 'calc.copy', args: { result: result.toString() } }
 *          }]
 *        } catch {
 *          return [{
 *            id: 'calc-error',
 *            title: 'Invalid expression',
 *            description: 'Please enter a valid math expression',
 *            type: 'command' as const,
 *            data: { command: 'calc.noop', args: {} }
 *          }]
 *        }
 *      },
 *
 *      register() {
 *        registerCommands({
 *          'calc.copy': (args) => navigator.clipboard.writeText(args.result),
 *          'calc.noop': () => {} // No operation
 *        })
 *      },
 *
 *      unregister() {
 *        unregisterCommands(['calc.copy', 'calc.noop'])
 *      }
 *    }
 *    ```
 *
 * 2. **Register Command** (in `./commands/slash.tsx`):
 *    ```typescript
 *    import { myCommand } from './my-command'
 *    import { calculatorCommand } from './calculator-command' // For self-contained commands
 *
 *    export const registerSlashCommands = (deps: Record<string, any>) => {
 *      slashCommandRegistry.register(themeCommand, { setTheme: deps.setTheme })
 *      slashCommandRegistry.register(languageCommand, { setLocale: deps.setLocale })
 *      slashCommandRegistry.register(myCommand, { myService: deps.myService }) // With dependencies
 *      slashCommandRegistry.register(calculatorCommand) // Self-contained, no dependencies
 *    }
 *
 *    export const unregisterSlashCommands = () => {
 *      slashCommandRegistry.unregister('theme')
 *      slashCommandRegistry.unregister('language')
 *      slashCommandRegistry.unregister('mycommand')
 *      slashCommandRegistry.unregister('calc') // Add this line
 *    }
 *    ```
 *
 *
 * 3. **Update SlashCommandProvider** (in `./commands/slash.tsx`):
 *    ```typescript
 *    export const SlashCommandProvider = () => {
 *      const theme = useTheme()
 *      const myService = useMyService() // Add external dependency if needed
 *
 *      useEffect(() => {
 *        registerSlashCommands({
 *          setTheme: theme.setTheme,          // Required for theme command
 *          setLocale: setLocaleOnClient,      // Required for language command
 *          myService: myService,              // Required for your custom command
 *          // Note: calculatorCommand doesn't need dependencies, so not listed here
 *        })
 *        return () => unregisterSlashCommands()
 *      }, [theme.setTheme, myService]) // Update dependency array for all dynamic deps
 *
 *      return null
 *    }
 *    ```
 *
 *    **Note:** Self-contained commands (like calculator) don't require dependencies but are
 *    still registered through the same system for consistent lifecycle management.
 *
 * 4. **Usage**: Users can now type `/mycommand` or `/mc` to use your command
 *
 * ## Command System Architecture
 * - Commands are registered via `SlashCommandRegistry`
 * - Each command is self-contained with its own dependencies
 * - Commands support aliases for easier access
 * - Command execution is handled by the command bus system
 * - All commands should be registered through `SlashCommandProvider` for consistent lifecycle management
 *
 * ## Command Types
 * **Commands with External Dependencies:**
 * - Require external services, APIs, or React hooks
 * - Must provide dependencies in `SlashCommandProvider`
 * - Example: theme commands (needs useTheme), API commands (needs service)
 *
 * **Self-Contained Commands:**
 * - Pure logic operations, no external dependencies
 * - Still recommended to register through `SlashCommandProvider` for consistency
 * - Example: calculator, text manipulation commands
 *
 * ## Available Actions
 * - `@app` - Search applications
 * - `@knowledge` / `@kb` - Search knowledge bases
 * - `@plugin` - Search plugins
 * - `@node` - Search workflow nodes (workflow pages only)
 * - `/` - Execute slash commands (theme, language, etc.)
 */

Screenshots

Before After
... ...
2025-08-18-14-45-27.mp4

Checklist

  • This change requires a documentation update, included: Dify Document
  • I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.
  • I ran dev/reformat(backend) and cd web && npx lint-staged(frontend) to appease the lint gods

- Add comprehensive documentation for adding new slash commands
- Refactor command registration system for better maintainability
- Convert all Chinese comments to English
- Fix ESLint errors (unused variables, nested control flow)
- Simplify command architecture with clear separation of concerns
- Add support for commands in the goto-anything component
- Update the English and Simplified Chinese translation files to add command-related translation items
- Update the numbering in the command documentation to ensure consistency
- Adjust the numbering of "Update SlashCommandProvider" and "Usage" to the correct order
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. 💪 enhancement New feature or request labels Aug 18, 2025
@HyaCiovo
Copy link
Copy Markdown
Contributor

image What is this ?

- Update the return value logic to ensure that 'Command' is returned when the command is '/', otherwise return the corresponding command key
- Default to 'general' to handle unmatched cases
…g component

- Change 'Command' in the return value logic to '@command' to better support command format
- Update the search placeholder in English and Simplified Chinese translation files to add support for '/'
@ZeroZ-lab
Copy link
Copy Markdown
Contributor Author

ZeroZ-lab commented Aug 18, 2025

image What is this ?

This is the issue with the character '/' during multilingual parsing

Thank you very much for finding the problem, I have fixed it.

Copy link
Copy Markdown
Member

@crazywoola crazywoola left a comment

Choose a reason for hiding this comment

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

LGTM

@crazywoola crazywoola merged commit b0e58f9 into langgenius:main Aug 18, 2025
6 checks passed
@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Aug 18, 2025
bowenliang123 pushed a commit to bowenliang123/dify that referenced this pull request Aug 18, 2025
asukaminato0721 added a commit to asukaminato0721/dify that referenced this pull request Aug 20, 2025
* Restore useLabelStore mistakenly removed in commit 403e2d5 (langgenius#24052)

Co-authored-by: Yongtao Huang <[email protected]>
Co-authored-by: crazywoola <[email protected]>

* chore: synchronize translations (langgenius#24044)

* feat: add testcontainers based tests for metadata service (langgenius#24048)

* feat: add testcontainers based tests for model loadbalancing service (langgenius#24066)

* feat: add select input support to the conversation opener (langgenius#24043)

* feat: add CLAUDE.md for LLM-assisted development guidance (langgenius#23946)

* feat: add Redis SSL/TLS certificate authentication support (langgenius#23624)

* Fix sticky table header transparency with backdrop-filter blur in dark mode (langgenius#23999)

* fix: update first_id logic to use the oldest answer item in chat messages (langgenius#23992)

Co-authored-by: Copilot <[email protected]>
Co-authored-by: crazywoola <[email protected]>

* refactor: improve loading animation and debug panel styles (langgenius#24075)

* fix(oauth): redis compatibility (langgenius#23959)

* feat: enchance prompt and code (langgenius#23633)

Co-authored-by: stream <[email protected]>
Co-authored-by: Stream <[email protected]>
Co-authored-by: Stream <[email protected]>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* fix: return empty list instead of raising exception for qdrant search when score_threshold is 1 (langgenius#24032)

* chore: translate i18n files (langgenius#24081)

Co-authored-by: Stream29 <[email protected]>

* fix: no current code caused code generation show error (langgenius#24086)

* fix(ui): Optimize UI component styles and layouts (langgenius#24090) (langgenius#24092)

* feat: no longer enable auto upgrade when marketplace is disabled (langgenius#24… (langgenius#24101)

* Feature/improve goto anything commands (langgenius#24091)

* chore: translate i18n files (langgenius#24102)

Co-authored-by: crazywoola <[email protected]>

* fix  pg_vector extension requires SUPERUSER, but not available on Huawei Cloud RDS (langgenius#24093)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* Revert "fix  pg_vector extension requires SUPERUSER, but not availabl… (langgenius#24108)

* fix: validate checklist before publishing workflow (langgenius#24104)

* Chore: remove some dead code in experience-enhance-group (langgenius#24110)

Co-authored-by: Yongtao Huang <[email protected]>

* fix: treat default template of code as empty (langgenius#24106)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* Bump pyobvector to 0.2.15 (langgenius#24120)

* Use typing.Literal to replace str places (langgenius#24099)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* feat: add delete avatar functionality with confirmation modal (langgenius#24127)

Co-authored-by: crazywoola <[email protected]>

* chore: translate i18n files (langgenius#24131)

Co-authored-by: crazywoola <[email protected]>

* an example of suppress (langgenius#24136)

* feat: add testcontainers based tests for feature service (langgenius#24026)

* feat: Implements periodic deletion of workflow run logs that exceed t… (langgenius#23881)

Co-authored-by: shiyun.li973792 <[email protected]>
Co-authored-by: 1wangshu <[email protected]>
Co-authored-by: Blackoutta <[email protected]>
Co-authored-by: crazywoola <[email protected]>

* try ast-grep (langgenius#24149)

* fix: correct behaviour of code fix (langgenius#24152)

Co-authored-by: Joel <[email protected]>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* Fix number input in  tool configure form of agent node tool item (langgenius#24154)

* Remove the second `if self.runtime is None:` check (langgenius#24171)

Co-authored-by: Yongtao Huang <[email protected]>

* Fix: correctly match http/https URLs in image upload file (langgenius#24180)

* feat: add testcontainers based tests for model provider service (langgenius#24193)

* Fix: replace `get_builtin_provider` with `get_plugin_provider` (langgenius#24191)

* docs: format all md files (langgenius#24195)

Signed-off-by: yihong0618 <[email protected]>

* hotfix: fix multiple case match syntax (langgenius#24204)

---------

Signed-off-by: yihong0618 <[email protected]>
Co-authored-by: Yongtao Huang <[email protected]>
Co-authored-by: Yongtao Huang <[email protected]>
Co-authored-by: crazywoola <[email protected]>
Co-authored-by: lyzno1 <[email protected]>
Co-authored-by: NeatGuyCoding <[email protected]>
Co-authored-by: Zhehao Peng <[email protected]>
Co-authored-by: -LAN- <[email protected]>
Co-authored-by: Guangdong Liu <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Wu Tianwei <[email protected]>
Co-authored-by: Maries <[email protected]>
Co-authored-by: Joel <[email protected]>
Co-authored-by: stream <[email protected]>
Co-authored-by: Stream <[email protected]>
Co-authored-by: Stream <[email protected]>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Bo Wu <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Stream29 <[email protected]>
Co-authored-by: HyaCinth <[email protected]>
Co-authored-by: Junyan Qin (Chin) <[email protected]>
Co-authored-by: GuanMu <[email protected]>
Co-authored-by: Elvis_LEE <[email protected]>
Co-authored-by: He Wang <[email protected]>
Co-authored-by: crazywoola <[email protected]>
Co-authored-by: 9527MrLi <[email protected]>
Co-authored-by: shiyun.li973792 <[email protected]>
Co-authored-by: 1wangshu <[email protected]>
Co-authored-by: Blackoutta <[email protected]>
Co-authored-by: KVOJJJin <[email protected]>
Co-authored-by: yihong <[email protected]>
qiaofenlin pushed a commit to qiaofenlin/dify that referenced this pull request Aug 24, 2025
@ZeroZ-lab ZeroZ-lab deleted the feature/improve-goto-anything-commands branch August 25, 2025 02:03
qiqizjl pushed a commit to qiqizjl/dify that referenced this pull request Aug 27, 2025
HarryReidx pushed a commit to HarryReidx/dify that referenced this pull request Sep 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💪 enhancement New feature or request lgtm This PR has been approved by a maintainer size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Commands in the go to anything feature have migrated from @run to / slash

3 participants