From 133685f0bb52cd331d4bc970109c2596ebc70e7e Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Thu, 14 May 2026 12:50:00 -0700 Subject: [PATCH 1/4] fix: surface catalog ID in PromptBuilder --- packages/genui/lib/src/facade/prompt_builder.dart | 2 ++ packages/genui/test/facade/prompt_builder_test.dart | 11 +++++++++++ .../all_operations_with_dataModel_false.txt | 4 ++++ .../all_operations_with_dataModel_true.txt | 4 ++++ .../create_and_update_with_dataModel_false.txt | 4 ++++ .../create_and_update_with_dataModel_true.txt | 4 ++++ .../create_only_with_dataModel_false.txt | 4 ++++ .../create_only_with_dataModel_true.txt | 4 ++++ .../update_only_with_dataModel_false.txt | 4 ++++ .../update_only_with_dataModel_true.txt | 4 ++++ 10 files changed, 45 insertions(+) diff --git a/packages/genui/lib/src/facade/prompt_builder.dart b/packages/genui/lib/src/facade/prompt_builder.dart index 77ecada7c..1ca4a586c 100644 --- a/packages/genui/lib/src/facade/prompt_builder.dart +++ b/packages/genui/lib/src/facade/prompt_builder.dart @@ -366,6 +366,8 @@ final class _BasicPromptBuilder extends PromptBuilder { final fragments = [ ...systemPromptFragments, 'Use the provided tools to respond to user using rich UI elements.', + if (catalog.catalogId != null) + 'The active catalog ID is: "${catalog.catalogId}".', ...technicalPossibilities.systemPromptFragment(), ...catalog.systemPromptFragments, ...allowedOperations.systemPromptFragments, diff --git a/packages/genui/test/facade/prompt_builder_test.dart b/packages/genui/test/facade/prompt_builder_test.dart index dc573fdc5..954ae8e78 100644 --- a/packages/genui/test/facade/prompt_builder_test.dart +++ b/packages/genui/test/facade/prompt_builder_test.dart @@ -123,4 +123,15 @@ void main() { }); } }); + + group('Catalog ID', () { + test('is surfaced in system prompt when provided', () { + final catalog = Catalog([ + BasicCatalogItems.text, + ], catalogId: 'my_custom_catalog'); + final builder = PromptBuilder.chat(catalog: catalog); + final String prompt = builder.systemPromptJoined(); + expect(prompt, contains('The active catalog ID is: "my_custom_catalog"')); + }); + }); } diff --git a/packages/genui/test/facade/prompt_builder_test.golden/all_operations_with_dataModel_false.txt b/packages/genui/test/facade/prompt_builder_test.golden/all_operations_with_dataModel_false.txt index 55f3a5978..82a145d6c 100644 --- a/packages/genui/test/facade/prompt_builder_test.golden/all_operations_with_dataModel_false.txt +++ b/packages/genui/test/facade/prompt_builder_test.golden/all_operations_with_dataModel_false.txt @@ -16,6 +16,10 @@ Use the provided tools to respond to user using rich UI elements. ------------------------------------- +The active catalog ID is: "test_catalog". + +------------------------------------- + IMPORTANT: You do not have the ability to execute code. If you need to perform calculations, do them yourself. ------------------------------------- diff --git a/packages/genui/test/facade/prompt_builder_test.golden/all_operations_with_dataModel_true.txt b/packages/genui/test/facade/prompt_builder_test.golden/all_operations_with_dataModel_true.txt index 37e522f94..28d04fda5 100644 --- a/packages/genui/test/facade/prompt_builder_test.golden/all_operations_with_dataModel_true.txt +++ b/packages/genui/test/facade/prompt_builder_test.golden/all_operations_with_dataModel_true.txt @@ -16,6 +16,10 @@ Use the provided tools to respond to user using rich UI elements. ------------------------------------- +The active catalog ID is: "test_catalog". + +------------------------------------- + IMPORTANT: You do not have the ability to execute code. If you need to perform calculations, do them yourself. ------------------------------------- diff --git a/packages/genui/test/facade/prompt_builder_test.golden/create_and_update_with_dataModel_false.txt b/packages/genui/test/facade/prompt_builder_test.golden/create_and_update_with_dataModel_false.txt index 6dd36efd5..75f9e82d8 100644 --- a/packages/genui/test/facade/prompt_builder_test.golden/create_and_update_with_dataModel_false.txt +++ b/packages/genui/test/facade/prompt_builder_test.golden/create_and_update_with_dataModel_false.txt @@ -16,6 +16,10 @@ Use the provided tools to respond to user using rich UI elements. ------------------------------------- +The active catalog ID is: "test_catalog". + +------------------------------------- + IMPORTANT: You do not have the ability to execute code. If you need to perform calculations, do them yourself. ------------------------------------- diff --git a/packages/genui/test/facade/prompt_builder_test.golden/create_and_update_with_dataModel_true.txt b/packages/genui/test/facade/prompt_builder_test.golden/create_and_update_with_dataModel_true.txt index cdc0a60ad..233fb54d3 100644 --- a/packages/genui/test/facade/prompt_builder_test.golden/create_and_update_with_dataModel_true.txt +++ b/packages/genui/test/facade/prompt_builder_test.golden/create_and_update_with_dataModel_true.txt @@ -16,6 +16,10 @@ Use the provided tools to respond to user using rich UI elements. ------------------------------------- +The active catalog ID is: "test_catalog". + +------------------------------------- + IMPORTANT: You do not have the ability to execute code. If you need to perform calculations, do them yourself. ------------------------------------- diff --git a/packages/genui/test/facade/prompt_builder_test.golden/create_only_with_dataModel_false.txt b/packages/genui/test/facade/prompt_builder_test.golden/create_only_with_dataModel_false.txt index fda9dd04c..2cfdb9b42 100644 --- a/packages/genui/test/facade/prompt_builder_test.golden/create_only_with_dataModel_false.txt +++ b/packages/genui/test/facade/prompt_builder_test.golden/create_only_with_dataModel_false.txt @@ -16,6 +16,10 @@ Use the provided tools to respond to user using rich UI elements. ------------------------------------- +The active catalog ID is: "test_catalog". + +------------------------------------- + IMPORTANT: You do not have the ability to execute code. If you need to perform calculations, do them yourself. ------------------------------------- diff --git a/packages/genui/test/facade/prompt_builder_test.golden/create_only_with_dataModel_true.txt b/packages/genui/test/facade/prompt_builder_test.golden/create_only_with_dataModel_true.txt index 75f6319ff..ff26e08ad 100644 --- a/packages/genui/test/facade/prompt_builder_test.golden/create_only_with_dataModel_true.txt +++ b/packages/genui/test/facade/prompt_builder_test.golden/create_only_with_dataModel_true.txt @@ -16,6 +16,10 @@ Use the provided tools to respond to user using rich UI elements. ------------------------------------- +The active catalog ID is: "test_catalog". + +------------------------------------- + IMPORTANT: You do not have the ability to execute code. If you need to perform calculations, do them yourself. ------------------------------------- diff --git a/packages/genui/test/facade/prompt_builder_test.golden/update_only_with_dataModel_false.txt b/packages/genui/test/facade/prompt_builder_test.golden/update_only_with_dataModel_false.txt index ca6bf4884..effed272a 100644 --- a/packages/genui/test/facade/prompt_builder_test.golden/update_only_with_dataModel_false.txt +++ b/packages/genui/test/facade/prompt_builder_test.golden/update_only_with_dataModel_false.txt @@ -16,6 +16,10 @@ Use the provided tools to respond to user using rich UI elements. ------------------------------------- +The active catalog ID is: "test_catalog". + +------------------------------------- + IMPORTANT: You do not have the ability to execute code. If you need to perform calculations, do them yourself. ------------------------------------- diff --git a/packages/genui/test/facade/prompt_builder_test.golden/update_only_with_dataModel_true.txt b/packages/genui/test/facade/prompt_builder_test.golden/update_only_with_dataModel_true.txt index e04604e4f..a68662989 100644 --- a/packages/genui/test/facade/prompt_builder_test.golden/update_only_with_dataModel_true.txt +++ b/packages/genui/test/facade/prompt_builder_test.golden/update_only_with_dataModel_true.txt @@ -16,6 +16,10 @@ Use the provided tools to respond to user using rich UI elements. ------------------------------------- +The active catalog ID is: "test_catalog". + +------------------------------------- + IMPORTANT: You do not have the ability to execute code. If you need to perform calculations, do them yourself. ------------------------------------- From 061a5bccc088839fb9e95e00e019d32ab15c4be6 Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Thu, 14 May 2026 13:34:21 -0700 Subject: [PATCH 2/4] fix: sanitize catalog ID and add tests for null case in PromptBuilder --- .../genui/lib/src/facade/prompt_builder.dart | 2 +- .../test/facade/prompt_builder_test.dart | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/genui/lib/src/facade/prompt_builder.dart b/packages/genui/lib/src/facade/prompt_builder.dart index 1ca4a586c..9ddd6fa80 100644 --- a/packages/genui/lib/src/facade/prompt_builder.dart +++ b/packages/genui/lib/src/facade/prompt_builder.dart @@ -367,7 +367,7 @@ final class _BasicPromptBuilder extends PromptBuilder { ...systemPromptFragments, 'Use the provided tools to respond to user using rich UI elements.', if (catalog.catalogId != null) - 'The active catalog ID is: "${catalog.catalogId}".', + 'The active catalog ID is: "${catalog.catalogId!.replaceAll('"', '\\"').replaceAll('\n', '\\n')}".', ...technicalPossibilities.systemPromptFragment(), ...catalog.systemPromptFragments, ...allowedOperations.systemPromptFragments, diff --git a/packages/genui/test/facade/prompt_builder_test.dart b/packages/genui/test/facade/prompt_builder_test.dart index 954ae8e78..bb4933f07 100644 --- a/packages/genui/test/facade/prompt_builder_test.dart +++ b/packages/genui/test/facade/prompt_builder_test.dart @@ -133,5 +133,24 @@ void main() { final String prompt = builder.systemPromptJoined(); expect(prompt, contains('The active catalog ID is: "my_custom_catalog"')); }); + + test('is not surfaced in system prompt when not provided', () { + final catalog = Catalog([BasicCatalogItems.text]); + final builder = PromptBuilder.chat(catalog: catalog); + final String prompt = builder.systemPromptJoined(); + expect(prompt, isNot(contains('The active catalog ID is:'))); + }); + + test('is sanitized in system prompt', () { + final catalog = Catalog([ + BasicCatalogItems.text, + ], catalogId: 'my_custom_\ncatalog"'); + final builder = PromptBuilder.chat(catalog: catalog); + final String prompt = builder.systemPromptJoined(); + expect( + prompt, + contains('The active catalog ID is: "my_custom_\\ncatalog\\"".'), + ); + }); }); } From ff3caa6a78b70311437023b3714ebcb2d29cde1f Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Thu, 14 May 2026 18:00:13 -0700 Subject: [PATCH 3/4] Fix lint --- packages/genui/lib/src/facade/prompt_builder.dart | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/genui/lib/src/facade/prompt_builder.dart b/packages/genui/lib/src/facade/prompt_builder.dart index 9ddd6fa80..2dd8d0f54 100644 --- a/packages/genui/lib/src/facade/prompt_builder.dart +++ b/packages/genui/lib/src/facade/prompt_builder.dart @@ -363,11 +363,15 @@ final class _BasicPromptBuilder extends PromptBuilder { catalog, ).toJson(indent: ' '); + String? activeCatalogId = catalog.catalogId + ?.replaceAll('"', '\\"') + .replaceAll('\n', '\\n'); + final fragments = [ ...systemPromptFragments, 'Use the provided tools to respond to user using rich UI elements.', - if (catalog.catalogId != null) - 'The active catalog ID is: "${catalog.catalogId!.replaceAll('"', '\\"').replaceAll('\n', '\\n')}".', + if (activeCatalogId != null) + 'The active catalog ID is: "$activeCatalogId".', ...technicalPossibilities.systemPromptFragment(), ...catalog.systemPromptFragments, ...allowedOperations.systemPromptFragments, From 5d1502f2c152a794f1bbbfee27bada385b08897a Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Fri, 15 May 2026 14:41:05 -0700 Subject: [PATCH 4/4] Fix formatting --- packages/genui/test/functions/format_string_test.dart | 1 + packages/genui/test/model/catalog_exception_test.dart | 1 + pubspec.yaml | 3 +-- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/genui/test/functions/format_string_test.dart b/packages/genui/test/functions/format_string_test.dart index 979af193d..144ffbf6c 100644 --- a/packages/genui/test/functions/format_string_test.dart +++ b/packages/genui/test/functions/format_string_test.dart @@ -8,6 +8,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:genui/src/catalog/basic_catalog.dart'; import 'package:genui/src/functions/format_string.dart'; import 'package:genui/src/model/data_model.dart'; + // import 'package:genui/src/primitives/simple_items.dart'; // Unused void main() { diff --git a/packages/genui/test/model/catalog_exception_test.dart b/packages/genui/test/model/catalog_exception_test.dart index 61a17fda1..98b982639 100644 --- a/packages/genui/test/model/catalog_exception_test.dart +++ b/packages/genui/test/model/catalog_exception_test.dart @@ -5,6 +5,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:genui/genui.dart'; + // import 'package:genui/src/model/catalog.dart'; // Exceptions should be exported by genui.dart, but if not we might need this. // Assuming CatalogItemNotFoundException is exported or available. diff --git a/pubspec.yaml b/pubspec.yaml index 230463c2e..159ec24a7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,13 +15,12 @@ workspace: - examples/composer - examples/e2e - examples/simple_chat - - examples/travel_app - examples/verdure/client - packages/a2ui_core - packages/genui - packages/genui_a2a - - packages/json_schema_builder + - packages/json_schema_builder - tool/fix_copyright - tool/release