From a404b4c9ee2b0430ec1c1daaddefc3572c338256 Mon Sep 17 00:00:00 2001 From: ugur-vaadin Date: Tue, 23 Jun 2026 16:11:51 +0300 Subject: [PATCH] refactor: improve instructions for ambiguous values --- .../flow/component/ai/form/FormAIController.java | 10 +++++++++- .../flow/component/ai/form/FormAIControllerTest.java | 5 ++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/vaadin-ai-components-flow-parent/vaadin-ai-components-flow/src/main/java/com/vaadin/flow/component/ai/form/FormAIController.java b/vaadin-ai-components-flow-parent/vaadin-ai-components-flow/src/main/java/com/vaadin/flow/component/ai/form/FormAIController.java index 338f78a1866..a09e5f0745c 100644 --- a/vaadin-ai-components-flow-parent/vaadin-ai-components-flow/src/main/java/com/vaadin/flow/component/ai/form/FormAIController.java +++ b/vaadin-ai-components-flow-parent/vaadin-ai-components-flow/src/main/java/com/vaadin/flow/component/ai/form/FormAIController.java @@ -201,7 +201,15 @@ public class FormAIController implements AIController { and pick a returned label. Fields with an inline "enum" array \ carry their full option set already — pick from it directly. 3. Call fill_form({"values": {: }}) with every value \ - you mean to set this turn. Skip fields the user did not mention. + you mean to set this turn. Skip fields the user did not mention. \ + Before writing a queryable field whose query returned multiple \ + matches, check its "description" for an ambiguity directive \ + (e.g. "let the user pick when the query returns multiple \ + items"). If present AND the user's prompt does not name the \ + subset to write, omit that field and ask the user instead. \ + Prompts like "Add both X and Y" or "Pick all of them" already \ + name the subset — proceed. Without a directive, pick the most \ + reasonable match (or all of them for a plural prompt). 4. Read fill_form's response. The "fields" array is the \ post-write form state and may differ from what get_form_state \ showed at the start of the turn: value-change listeners can \ diff --git a/vaadin-ai-components-flow-parent/vaadin-ai-components-flow/src/test/java/com/vaadin/flow/component/ai/form/FormAIControllerTest.java b/vaadin-ai-components-flow-parent/vaadin-ai-components-flow/src/test/java/com/vaadin/flow/component/ai/form/FormAIControllerTest.java index 9a1d6c9fe79..69009d85d88 100644 --- a/vaadin-ai-components-flow-parent/vaadin-ai-components-flow/src/test/java/com/vaadin/flow/component/ai/form/FormAIControllerTest.java +++ b/vaadin-ai-components-flow-parent/vaadin-ai-components-flow/src/test/java/com/vaadin/flow/component/ai/form/FormAIControllerTest.java @@ -140,7 +140,10 @@ void instructionsToolDescriptionCarriesTheFullWorkflow() { ".ignoreField()", "SAME turn", "newly-appeared", // bean-level cross-field rejections key on the "__form__" // sentinel id, not a real field id. - "__form__", "cross-field")) { + "__form__", "cross-field", + // ambiguity-handling is conditional on a per-field + // description directive. + "user", "pick", "multiple")) { Assertions.assertTrue(description.contains(anchor), "Workflow description must mention '" + anchor + "', got: " + description);