feat(desktop): handle blocking dialogs safely - #901
Merged
myu404 merged 4 commits intoSep 11, 2026
Conversation
mattcfilbert
left a comment
Contributor
There was a problem hiding this comment.
Andy-lens review (HEAD f686a76)
Strong PR, Michael. The safety core is right: the "indeterminate outcome" handling that treats a 5xx / lost-socket / timeout after the POST as maybe-fired and forbids a second click, while keeping the pre-dispatch api-disabled 503 definitive, is exactly the conservative call this tool needs. The 0.2.12 version gate (with the 0.2.11-hides / 0.2.12-exposes test), the log redaction of dialog identity and label, and the contract test pinning the real 0.2.12 fixture are all credit-worthy. Test coverage is thorough.
One thing to fix before merge, and two questions.
Please (before merge)
- Version collision with #875. This PR and #875 both bump to
2.68.1, and the base (feature/desktop) is at2.68.0. Two PRs making the identicalx → x+1edit merge clean with no conflict, and CI has no version-increment guard — so whichever lands second ships silently under a duplicate version, two code states under one number. Also, #884–#889 currently sit at2.67.6/2.67.7, below the base. Rebase the stack so each PR lands with a distinct, ascending version.
Questions (your call)
- Does a 401 from
invokeDialogActionguarantee the action never dispatched?invoke-dialog-actionis destructive and non-idempotent, but it runs throughwithRescan('command', …), which re-POSTs once after a 401 with a refreshed credential (externalApiToolExecutor.test.tsconfirms two POSTs on a stale token). That's safe only if a 401 is always a pre-dispatch auth rejection — i.e. the click never fired. If the producer can ever return 401 after dispatching, the rescan would invoke the action twice and break the "at most one action" rule this PR is built on. This is really a question for the monolith side (#65450) — can we confirm 401 is always pre-dispatch here? - Reuse
dialogActionSchemafor the tool param?invokeDialogAction.tsdefines its ownactionSchema(z.enum+.refine) rather than reusingdialogActionSchema(the discriminated union intypes.ts). Reusing it would drop theaction.label as stringcast and the manual re-normalization in the callback, and keep one source of truth if a third action kind ever appears. Was the flat shape deliberate (e.g. cleaner JSON Schema for the client)?
nit
- The
@deprecated ExternalApiReadalias and therunExternalApiReadToolwrapper are source-compat retainers. Keeping them to avoid churning every read tool is a fair call; worth a follow-up to rename the call sites and drop both.
Fine as-is
invoke-dialog-actionnamingget-active-dialogsin its description is safe: both share the0.2.12floor so the reference can't dangle, andemittedToolReferences/corpusIntegrityguard against a rename rotting it.
Posted by MattGPT on Matt's behalf.
Author
|
🤖 Posted by MichaelGPT Re @mattcfilbert's comment:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Decision
Desktop agents inspect the exact current dialog and invoke at most one exact returned action; when they cannot establish a safe action, they hand control to the user.
Description
get-active-dialogsandinvoke-dialog-actiontools over the Desktop External Client API0.2.13dialog routes.2.68.6. This change introduces no breaking changes.Known Limitation
Dialog inspection and action invocation cover Tableau-owned application dialogs. Dialogs handed off to OS platform-native controls, such as file choosers or print dialogs, are outside the External Client API and require user interaction or separate OS automation.
Motivation and Context
Tableau Desktop operations can surface application-owned dialogs that block subsequent agent interaction. Agents need structured evidence about the active dialog and a guarded way to invoke one explicit available action, with a human fallback when safe automation is not possible.
Type of Change
How Has This Been Tested?
scripts/agent-checkRelated Issues
Checklist
npm run version. For example,use
npm run version:patchfor a patch version bump.environment variable or changing its default value.
Contributor Agreement
By submitting this pull request, I confirm that:
its Contribution Checklist.