Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
4205f28
AI Sample: Landmark detail page, semantic search, UX improvements
mattleibow Mar 18, 2026
c584171
Polish Essentials AI sample: UI improvements and bug fixes
mattleibow Mar 19, 2026
65f5ed0
Update LandmarksPage.xaml.cs
mattleibow Mar 19, 2026
8ef298a
AI Sample: Schema middleware, chat fixes, weather, language refactor,…
mattleibow Mar 19, 2026
4c90bf2
Add StreamingResponseHandler passthrough mode + tests
mattleibow Mar 19, 2026
792cbf8
Add streaming device tests (DeliversMultipleIncrementalUpdates, Conca…
mattleibow Mar 19, 2026
e81bcd1
Revert csproj to main (Windows manifest props belong in Windows PR)
mattleibow Mar 19, 2026
b342d97
Use the correct attribute
mattleibow Mar 19, 2026
47c929b
Use DisplayName instead of JsonPropertyName for schema compatibility
mattleibow Mar 26, 2026
178f1f0
Revert to JsonPropertyName for record properties
mattleibow Mar 26, 2026
e61cdee
Address PR review comments: fix IsVisible converters, language tip, a…
mattleibow Mar 31, 2026
1bd8424
Address PR review comments: fix IsVisible converters, language tip, a…
mattleibow Mar 31, 2026
2035b1a
Make ISemanticSearchService non-nullable in DataService
mattleibow Mar 31, 2026
aa6fa0f
Address round 3 review comments
mattleibow Mar 31, 2026
41e7c2f
Revert "Address PR review comments: fix IsVisible converters, languag…
mattleibow Mar 31, 2026
741a6b7
Replace emoji with FluentSystemIcons in AI sample app
mattleibow Apr 1, 2026
96cdecf
Move FluentUI.cs out of Resources/Fonts to fix CI build
mattleibow Apr 1, 2026
b14bdb5
Trigger CI rebuild
mattleibow Apr 1, 2026
b2eb0ec
Move GetWeatherIcon out of Weather.cs model
mattleibow Apr 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,19 @@ public static IHostApplicationBuilder AddItineraryWorkflow(this IHostApplication
builder.AddAIAgent(
name: "travel-planner-agent",
instructions: """
You are a simple text parser.

Extract ONLY these 3 values from the user's request:
1. destinationName: The place/location name mentioned (extract it exactly as written)
2. dayCount: The number of days mentioned (default: 3 if not specified)
3. language: The language mentioned for the output (default: English if not specified)

You are a simple text parser. Extract 3 values from the user request.

Rules:
1. ALWAYS extract the raw values.
2. NEVER make up values or interpret the user's intent.

- place: The destination name, exactly as written.
- days: Number of days (default: 3).
- language: Output language (default: English).

Examples:
- "5-day trip to Maui in French" → destinationName: "Maui", dayCount: 5, language: "French"
- "Visit the Great Wall" → destinationName: "Great Wall", dayCount: 3, language: "English"
- "Itinerary for Tokyo" → destinationName: "Tokyo", dayCount: 3, language: "English"
- "Give me a Maui itinerary" → destinationName: "Maui", dayCount: 3, language: "English"
- "Plan a 7 day Japan trip in Spanish" → destinationName: "Japan", dayCount: 7, language: "Spanish"
- "5-day trip to Maui in French" produces {"place": "Maui", "days": 5, "language": "French"}
- "Visit the Great Wall" produces {"place": "Great Wall", "days": 3, "language": "English"}
- "Plan a 7 day Japan trip in Spanish" produces {"place": "Japan", "days": 7, "language": "Spanish"}
- "Give me a Cape Town itinerary" produces {"place": "Cape Town", "days": 3, "language": "English"}
- "Itinerary for Tokyo" produces {"place": "Tokyo", "days": 3, "language": "English"}
""",
chatClientServiceKey: "local-model");

Expand Down Expand Up @@ -108,6 +104,7 @@ Return the exact name of the best matching destination from the candidates.
Name = name,
ChatOptions = new ChatOptions
{
Temperature = 0.6f,
Instructions = $"""
You create detailed travel itineraries.

Expand Down
19 changes: 10 additions & 9 deletions src/AI/samples/Essentials.AI.Sample/AI/WorkflowModels.cs
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
using System.ComponentModel;
using System.Text.Json.Serialization;

namespace Maui.Controls.Sample.AI;

/// <summary>
/// Result from the Travel Planner Agent - raw extraction of user intent.
/// These values should be extracted exactly as the user stated them, with no interpretation or expansion.
/// Short JSON names (place/days/language) reduce misspelling by small language models.
/// </summary>
public record TravelPlanResult(
[property: DisplayName("destinationName")]
[property: Description("The exact place/location name as written in the user's request. Extract the raw text only - do NOT interpret, expand, or look up actual landmarks. Example: 'Maui' not 'Maui, Hawaii' or 'Haleakala National Park'.")]
[property: JsonPropertyName("place")]
[property: Description("The destination name mentioned by the user.")]
string DestinationName,
[property: DisplayName("dayCount")]
[property: Description("The exact number of days mentioned by the user. Use 3 as default only if no number is specified.")]
[property: JsonPropertyName("days")]
[property: Description("Number of days for the trip. Default is 3.")]
int DayCount,
[property: DisplayName("language")]
[property: Description("The exact output language mentioned by the user. Use 'English' as default only if no language is specified.")]
[property: JsonPropertyName("language")]
[property: Description("Output language for the itinerary. Default is English.")]
Comment on lines 6 to +18
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

The comment says “Short JSON names (dest/days/lang) prevent misspelling…”, but TravelPlanResult uses JsonPropertyName("place"), "days", and "language". Consider updating the remark to match the actual short names (place/days/language) to avoid confusion when editing prompts/schema.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in aa6fa0f — updated comment to say \place/days/language\ to match the actual \JsonPropertyName\ values.

string Language);

/// <summary>
/// Result from the Researcher Agent - the best matching destination (for JSON schema).
/// </summary>
internal record DestinationMatchResult(
[property: DisplayName("matchedDestinationName")]
[property: JsonPropertyName("dest")]
[property: Description("The exact name of the best matching destination from the available list.")]
string MatchedDestinationName,
[property: DisplayName("matchedDestinationDescription")]
[property: JsonPropertyName("desc")]
[property: Description("A brief description of the matched destination, based on the information provided in the additional context.")]
string MatchedDestinationDescription);

Expand Down
1 change: 1 addition & 0 deletions src/AI/samples/Essentials.AI.Sample/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<converters:IsNotNullConverter x:Key="IsNotNullConverter" />
<converters:InvertedBoolConverter x:Key="InvertedBoolConverter" />
<converters:IsNotNullOrEmptyConverter x:Key="IsNotNullOrEmptyConverter" />
<converters:IsPositiveConverter x:Key="IsPositiveConverter" />
</ResourceDictionary>
</Application.Resources>
</Application>
3 changes: 1 addition & 2 deletions src/AI/samples/Essentials.AI.Sample/AppShell.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ public AppShell()
{
InitializeComponent();

// Register routes for navigation
// Only TripPlanningPage is navigable - LandmarkTripView is a child component
Routing.RegisterRoute(nameof(LandmarkDetailPage), typeof(LandmarkDetailPage));
Routing.RegisterRoute(nameof(TripPlanningPage), typeof(TripPlanningPage));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Globalization;

namespace Maui.Controls.Sample.Converters;

public class IsPositiveConverter : IValueConverter
{
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
return value is int i && i > 0;
}

public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Loading
Loading