mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[agent-workbench]: EP-driven extension tab auto-selection in prompt palette (IJPL-233558)
IJ-MR-197006 Move auto-selection decision to the EP side: add shouldAutoSelect() to AgentPromptPaletteExtension so each extension can declare whether it should be auto-selected given the context. Alt+Cmd+\ queries matching extensions to autoselect tab. GitOrigin-RevId: 550b96b2cba505e1b20c665ce47f34e77d90132b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
2e8eb9d191
commit
cf6d783545
@@ -458,6 +458,7 @@ public abstract class KeymapsTestCase extends KeymapsTestCaseBase {
|
||||
"Git.Rename.Local.Branch", "ShelvedChanges.Rename", "ChangesView.Rename", "Terminal.SearchInCommandHistory"},
|
||||
{"control U", SECOND_STROKE, "CommanderSwapPanels", "org.intellij.plugins.markdown.ui.actions.styling.InsertImageAction"},
|
||||
{"control W", "CloseContent", "Terminal.DeletePreviousWord"},
|
||||
{"ctrl alt BACK_SLASH", "AgentWorkbenchPrompt.OpenGlobalPaletteAutoSelect", "ClassNameCompletion"},
|
||||
{"control alt DOWN", "MethodDown", "NextOccurence", "Console.TableResult.NextPage"},
|
||||
{"control alt E", "Console.History.Browse", "ExecuteInPyConsoleAction", "PerforceDirect.Edit", "ToggleFindInSelection"},
|
||||
{"shift alt U", "ActivateFindToolWindow", "ToggleCamelSnakeCase"},
|
||||
|
||||
@@ -24,5 +24,13 @@
|
||||
<keyboard-shortcut first-keystroke="meta BACK_SLASH" keymap="Mac OS X 10.5+"/>
|
||||
<add-to-group group-id="ToolsMenu" anchor="last"/>
|
||||
</action>
|
||||
|
||||
<action
|
||||
id="AgentWorkbenchPrompt.OpenGlobalPaletteAutoSelect"
|
||||
class="com.intellij.agent.workbench.prompt.actions.AgentWorkbenchGlobalPromptAutoSelectAction">
|
||||
<keyboard-shortcut first-keystroke="alt control BACK_SLASH" keymap="$default"/>
|
||||
<keyboard-shortcut first-keystroke="alt meta BACK_SLASH" keymap="Mac OS X 10.5+"/>
|
||||
<add-to-group group-id="ToolsMenu" anchor="last"/>
|
||||
</action>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -56,4 +56,6 @@ context.paths.title=Paths
|
||||
popup.preview.toggle.tooltip=Toggle markdown preview
|
||||
action.AgentWorkbenchPrompt.OpenGlobalPalette.text=Ask Agent with Context
|
||||
action.AgentWorkbenchPrompt.OpenGlobalPalette.description=Open global prompt palette with context from the current IDE state
|
||||
action.AgentWorkbenchPrompt.OpenGlobalPaletteAutoSelect.text=Ask Agent Depending on Context
|
||||
action.AgentWorkbenchPrompt.OpenGlobalPaletteAutoSelect.description=Open global prompt palette and auto-select the extension tab that matches the context
|
||||
context.tree.selection.title=Tree Selection ({0})
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.agent.workbench.prompt.actions
|
||||
|
||||
// @spec community/plugins/agent-workbench/spec/actions/global-prompt-entry.spec.md
|
||||
|
||||
import com.intellij.agent.workbench.prompt.context.AGENT_PROMPT_INVOCATION_ACTION_EVENT_KEY
|
||||
import com.intellij.agent.workbench.prompt.ui.AgentPromptPalettePopup
|
||||
import com.intellij.agent.workbench.sessions.core.prompt.AGENT_PROMPT_INVOCATION_DATA_CONTEXT_KEY
|
||||
import com.intellij.agent.workbench.sessions.core.prompt.AGENT_PROMPT_INVOCATION_PREFER_EXTENSIONS_KEY
|
||||
import com.intellij.agent.workbench.sessions.core.prompt.AgentPromptInvocationData
|
||||
import com.intellij.openapi.actionSystem.ActionUpdateThread
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.project.DumbAware
|
||||
|
||||
internal class AgentWorkbenchGlobalPromptAutoSelectAction : AnAction(), DumbAware {
|
||||
companion object {
|
||||
private const val ACTION_ID: String = "AgentWorkbenchPrompt.OpenGlobalPaletteAutoSelect"
|
||||
}
|
||||
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
val project = e.project ?: return
|
||||
AgentPromptPalettePopup(
|
||||
invocationData = AgentPromptInvocationData(
|
||||
project = project,
|
||||
actionId = ACTION_ID,
|
||||
actionText = e.presentation.text,
|
||||
actionPlace = e.place,
|
||||
invokedAtMs = System.currentTimeMillis(),
|
||||
attributes = mapOf(
|
||||
AGENT_PROMPT_INVOCATION_DATA_CONTEXT_KEY to e.dataContext,
|
||||
AGENT_PROMPT_INVOCATION_ACTION_EVENT_KEY to e,
|
||||
AGENT_PROMPT_INVOCATION_PREFER_EXTENSIONS_KEY to true,
|
||||
),
|
||||
)
|
||||
).show()
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
e.presentation.isEnabledAndVisible = e.project != null
|
||||
}
|
||||
|
||||
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import com.intellij.agent.workbench.sessions.core.prompt.AgentPromptContextEnvel
|
||||
import com.intellij.agent.workbench.sessions.core.prompt.AgentPromptContextItem
|
||||
import com.intellij.agent.workbench.sessions.core.prompt.AgentPromptInitialMessageRequest
|
||||
import com.intellij.agent.workbench.sessions.core.prompt.AgentPromptInvocationData
|
||||
import com.intellij.agent.workbench.sessions.core.prompt.AGENT_PROMPT_INVOCATION_PREFER_EXTENSIONS_KEY
|
||||
import com.intellij.agent.workbench.sessions.core.prompt.AgentPromptLaunchError
|
||||
import com.intellij.agent.workbench.sessions.core.prompt.AgentPromptLaunchRequest
|
||||
import com.intellij.agent.workbench.sessions.core.prompt.AgentPromptLauncherBridge
|
||||
@@ -185,8 +186,8 @@ internal class AgentPromptPalettePopup(
|
||||
restoreTaskDrafts(draft)
|
||||
refreshExtensionTaskDraftsFromContext()
|
||||
val preferExtensions = invocationData.attributes[AGENT_PROMPT_INVOCATION_PREFER_EXTENSIONS_KEY] == true
|
||||
if (preferExtensions && activeExtensionTabs.isNotEmpty()) {
|
||||
selectFirstExtensionTab()
|
||||
if (preferExtensions) {
|
||||
selectAutoSelectExtensionTab()
|
||||
}
|
||||
val initialText = invocationData.dataContextOrNull()?.getData(AGENT_PROMPT_INITIAL_TEXT_DATA_KEY)
|
||||
if (!initialText.isNullOrBlank()) {
|
||||
@@ -412,9 +413,10 @@ internal class AgentPromptPalettePopup(
|
||||
}
|
||||
}
|
||||
|
||||
private fun selectFirstExtensionTab() {
|
||||
val firstExtension = activeExtensionTabs.firstOrNull() ?: return
|
||||
val index = (0 until tabbedPane.tabCount).firstOrNull { tabbedPane.getComponentAt(it) === firstExtension.tabPanel }
|
||||
private fun selectAutoSelectExtensionTab() {
|
||||
val items = contextEntries.map { it.item }
|
||||
val target = activeExtensionTabs.firstOrNull { it.extension.shouldAutoSelect(items) } ?: return
|
||||
val index = (0 until tabbedPane.tabCount).firstOrNull { tabbedPane.getComponentAt(it) === target.tabPanel }
|
||||
if (index != null) {
|
||||
tabbedPane.selectedIndex = index
|
||||
}
|
||||
|
||||
@@ -60,6 +60,13 @@ interface AgentPromptPaletteExtension {
|
||||
* or `null` to use the default hint.
|
||||
*/
|
||||
fun getFooterHint(): @Nls String?
|
||||
|
||||
/**
|
||||
* Returns `true` if this extension's tab should be auto-selected when the popup
|
||||
* is invoked with the "prefer extensions" shortcut and this extension [matches] the context.
|
||||
* When multiple extensions return `true`, the first one wins.
|
||||
*/
|
||||
fun shouldAutoSelect(contextItems: List<AgentPromptContextItem>): Boolean = matches(contextItems)
|
||||
}
|
||||
|
||||
object AgentPromptPaletteExtensions {
|
||||
|
||||
@@ -3,6 +3,7 @@ name: Global Prompt Entry
|
||||
description: Requirements for global prompt action behavior, target routing, keyboard semantics, validation, and launcher handoff.
|
||||
targets:
|
||||
- ../../prompt/src/actions/AgentWorkbenchGlobalPromptAction.kt
|
||||
- ../../prompt/src/actions/AgentWorkbenchGlobalPromptAutoSelectAction.kt
|
||||
- ../../prompt/src/ui/AgentPromptPalettePopup.kt
|
||||
- ../../prompt/src/ui/AgentPromptPaletteView.kt
|
||||
- ../../prompt/src/ui/AgentPromptPaletteModels.kt
|
||||
@@ -10,6 +11,7 @@ targets:
|
||||
- ../../prompt/resources/intellij.agent.workbench.prompt.xml
|
||||
- ../../prompt/resources/messages/AgentPromptBundle.properties
|
||||
- ../../sessions-core/src/prompt/AgentPromptLauncherBridge.kt
|
||||
- ../../sessions-core/src/prompt/AgentPromptPaletteExtension.kt
|
||||
- ../../sessions/src/service/AgentSessionPromptLauncherBridge.kt
|
||||
- ../../prompt/testSrc/ui/AgentPromptProviderSelectionDecisionsTest.kt
|
||||
- ../../prompt/testSrc/ui/AgentPromptSubmitValidationDecisionsTest.kt
|
||||
@@ -44,6 +46,8 @@ Prompt-context collection and rendering contracts are specified separately in `s
|
||||
## Requirements
|
||||
- Global action id `AgentWorkbenchPrompt.OpenGlobalPalette` must be available only when a project is open.
|
||||
|
||||
- Global action id `AgentWorkbenchPrompt.OpenGlobalPaletteAutoSelect` must be available only when a project is open. It opens the same popup but with EP-driven extension tab auto-selection (see below).
|
||||
|
||||
- Prompt target mode must support exactly:
|
||||
- `PromptTargetMode.NEW_TASK`,
|
||||
- `PromptTargetMode.EXISTING_TASK`.
|
||||
@@ -112,6 +116,18 @@ Prompt-context collection and rendering contracts are specified separately in `s
|
||||
|
||||
- Context block soft-cap limit is `12_000` characters. When exceeded, user must explicitly choose send-full, auto-trim, or cancel before launch.
|
||||
|
||||
- Extension tab auto-selection (`Alt+Cmd+\` / `Alt+Ctrl+\`):
|
||||
- When the popup is opened via `AgentWorkbenchPrompt.OpenGlobalPaletteAutoSelect`, the `AGENT_PROMPT_INVOCATION_PREFER_EXTENSIONS_KEY` attribute is set to `true`.
|
||||
- When `preferExtensions` is true, the popup calls `AgentPromptPaletteExtension.shouldAutoSelect(contextItems)` on each active extension tab in order.
|
||||
- The first extension that returns `true` from `shouldAutoSelect` has its tab auto-selected.
|
||||
- If no extension returns `true`, the default "New Task" tab remains selected.
|
||||
- `shouldAutoSelect` defaults to `false` in the EP interface; each extension opts in independently.
|
||||
- When the popup is opened via the standard `AgentWorkbenchPrompt.OpenGlobalPalette` (`Cmd+\` / `Ctrl+\`), no auto-selection occurs regardless of extension tab state.
|
||||
|
||||
- Extension tab submit flow:
|
||||
- When an extension tab is active, submit delegates to the action returned by `AgentPromptPaletteExtension.getSubmitActionId()`.
|
||||
- Provider options, plan mode, and existing-task routing are bypassed for extension tabs.
|
||||
|
||||
## User Experience
|
||||
- Popup opens as a project-scoped launcher for both new and existing task targets.
|
||||
- Existing-task mode exposes provider-scoped thread list with loading/empty/error states.
|
||||
|
||||
Reference in New Issue
Block a user