Table of Contents

Auto-suggest

Auto-suggest is an AI-powered feature that automatically suggests property values when users modify related fields. This feature helps users fill in form fields faster by leveraging AI to predict appropriate values based on context.

Overview

When a user modifies a property in a UI view, the auto-suggest feature analyzes the change and generates suggestions for related properties. For example, when entering a city name, the system can suggest the corresponding postal code or country.

flowchart LR
    A[User modifies property] --> B[Client detects change]
    B --> C[API call to backend]
    C --> D[AI generates suggestions]
    D --> E[Suggestions displayed]
    E --> F{User decision}
    F -->|Accept| G[Value applied]
    F -->|Reject| H[Suggestion dismissed]

Enabling auto-suggest

To enable the auto-suggest feature, configure the AI model in your cluster configuration:

dotnet user-secrets set "AI:AutoSuggestModel" "[Your chosen model]" --id "[Your cluster root namespace].AspNetCore"

Configuring auto-suggest prompts

Auto-suggest is configured at the UI view property level using two metadata properties:

Property Description
AIAutoSuggestPrompt The prompt template that describes how to generate suggestions for this property
AIAutoSuggestTriggers List of property names that trigger auto-suggest for this property when modified. If empty, the property itself acts as the trigger.

Self-triggered suggestions

When AIAutoSuggestTriggers is empty or not specified, the suggestion is triggered when the property itself is modified:

- Name: Description
  AIAutoSuggestPrompt: Improve the description to make it clearer and more professional

In this example, when the user modifies the Description property, the AI will suggest an improved version of the text they entered.

Basic configuration

In your UI view properties metadata file, configure the target property:

- Name: PostalCode
  AIAutoSuggestPrompt: Suggest a postal code based on the city {{ city }}
  AIAutoSuggestTriggers:
  - City

When the user modifies the City property, the AI will generate a postal code suggestion.

Multiple triggers

You can specify multiple trigger properties:

- Name: FullAddress
  AIAutoSuggestPrompt: Generate a complete address based on {{ street }}, {{ city }}, and {{ country }}
  AIAutoSuggestTriggers:
  - Street
  - City
  - Country

Cross-property suggestions

A single trigger can generate suggestions for multiple properties:

- Name: PostalCode
  AIAutoSuggestPrompt: Suggest a postal code based on the city {{ city }}
  AIAutoSuggestTriggers:
  - City

- Name: Country
  AIAutoSuggestPrompt: Suggest the country based on the city {{ city }}
  AIAutoSuggestTriggers:
  - City

When the user enters a city, both the postal code and country fields receive suggestions.

Prompt template syntax

Auto-suggest prompts use Scriban template syntax. You can reference properties and use various built-in variables and functions.

Available variables

Property values

You can directly reference any property value from the current object using camelCase:

AIAutoSuggestPrompt: Suggest a postal code based on the city {{ city }} and country {{ country }}

Context objects

Variable Description
current The current object being edited
parent The parent object (for sub-UI views)
root The root ViewModel object

Example accessing parent properties:

AIAutoSuggestPrompt: Suggest based on parent name {{ parent.name }}

Modified property information

Variable Description
modifiedProperty.name Name of the property that triggered the suggestion
modifiedProperty.description Caption/description of the modified property
modifiedProperty.value Current value of the modified property

Example:

AIAutoSuggestPrompt: |-
  The user modified "{{ modifiedProperty.description }}" to "{{ modifiedProperty.value }}".
  Suggest an appropriate value for this field.

Current property metadata

Variable Description
currentProperty.name Name of the property receiving the suggestion
currentProperty.characterCasing Character casing rule (e.g., PascalCasing, CamelCasing)
currentProperty.dataType Data type of the property
currentProperty.enumTypeName Enum type name (if applicable)
currentProperty.defaultValue Default value of the property

Example:

AIAutoSuggestPrompt: |-
  Generate a value using {{ currentProperty.characterCasing }} naming convention.

Application information

Variable Description
app.languages Array of configured language codes (e.g., ["en", "fr"])

Example:

AIAutoSuggestPrompt: Translate to {{ app.languages[0] }}

Helper functions

Function Description
exists(path) Returns true if the JSONPath exists
not_exists(path) Returns true if the JSONPath does not exist
equals(path, value) Returns true if the value at path equals the expected value
not_equals(path, value) Returns true if the value at path differs from the expected value
count(path) Returns the number of elements matching the JSONPath

Path prefixes for context:

  • root: - Query from root object
  • parent: - Query from parent object
  • current: - Query from current object (default)

Advanced example: order line description

This example demonstrates a complex prompt using JSONPath queries to analyze collections. The prompt adapts its behavior based on the content of related order lines:

- Name: Description
  AIAutoSuggestPrompt: |-
    Generate a description for the product "{{ productName }}" in the language {{ app.languages[0] }}.
    {{ if exists("parent:orderLines[?(@.status=='Pending')]") }}
    Note: This order contains pending items that may affect delivery.
    {{ end }}
    {{ if count("parent:orderLines[?(@.quantity > 10)]") > 0 }}
    This is a bulk order with {{ count("parent:orderLines[?(@.quantity > 10)]") }} high-quantity items. Keep the description concise.
    {{ end }}
    {{ if equals("parent:orderLines[0].productCategory", "Hazardous") }}
    Include safety handling instructions as the first item is hazardous.
    {{ end }}
  AIAutoSuggestTriggers:
  - ProductName

This prompt uses JSONPath filter expressions to:

  • Check if any order line has a "Pending" status using [?(@.status=='Pending')]
  • Count order lines where quantity exceeds 10
  • Check the category of the first order line

Including templates

Use {{ include "TemplateName" }} to include reusable templates defined in your cluster configuration:

AIAutoSuggestPrompt: |-
  {{ include "AddressPrompt" }}
  Suggest a postal code for {{ city }}.

Reusable templates

For complex or repeated prompt patterns, define reusable templates in your cluster configuration:

AI:
  AutoSuggestTemplates:
    ApplicationDescription: Your application business context description here
    AddressPrompt: Consider the address format conventions for the target country.
    IdentifierPrompt: Use {{ currentProperty.characterCasing }} naming convention.

Then reference them in your prompts:

- Name: PostalCode
  AIAutoSuggestPrompt: |-
    {{ include "AddressPrompt" }}
    Suggest a postal code based on the city {{ city }}.
  AIAutoSuggestTriggers:
  - City
Note

The ApplicationDescription template is special: it is automatically included in the AI context to provide your application's business context. You do not need to include it manually in your property prompts.

Localizable string support

For LocalizableString properties, auto-suggest can automatically translate values across all configured languages. When a property has the LocalizableString data type and a default prompt is configured, the system ensures consistency across translations.

Configure a default prompt template for localizable strings:

AI:
  AutoSuggestTemplates:
    LocalizableStringDefaultPrompt: |-
      Verify that the string is correct, consistent, and appropriate across all target languages.
      Ensure all translations convey the same meaning.

Auto-suggest behavior

User experience

  1. User modifies a trigger property
  2. After a brief delay, suggestion indicators appear on target properties
  3. User can accept or reject each suggestion individually
  4. Accepted suggestions are applied to the model
  5. Rejected suggestions are dismissed

Automatic cancellation

  • When the user continues typing, previous pending suggestions are automatically cancelled
  • When the user clears the trigger property value, related suggestions are removed
  • When the user manually modifies a suggested property before accepting, the suggestion is dismissed

Filtering rules

Suggestions are automatically filtered out when:

  • The target property is not visible
  • The target property is read-only
  • The property value has been modified by the user since the suggestion was generated
  • The suggested value equals the current value

Using skills in prompts

For advanced scenarios, you can reference AI skills in your prompts to provide the AI with additional capabilities. Skills allow the AI to call functions during suggestion generation.

Skill reference syntax

Use the {skill:SkillName.FunctionName} syntax to reference a skill function:

- Name: PostalCode
  AIAutoSuggestPrompt: |-
    Suggest a postal code for the city "{{ city }}" in country "{{ country }}".
    Call {skill:Location.GetPostalCode} to lookup the postal code.
  AIAutoSuggestTriggers:
  - City
  - Country

Registering a skill

Skills must be registered in your application's Startup.cs file using the RegisterAutoSuggestSkill extension method:

using GroupeIsa.Neos.Application.AutoSuggest;

public class Startup : IStartup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.RegisterAutoSuggestSkill<LocationSkill>("Location");
    }
}

The skill name passed to RegisterAutoSuggestSkill (e.g., "Location") is the name you use in prompts with the {skill:SkillName.FunctionName} syntax.

Creating a skill

Create a class that implements IAutoSuggestSkill and define functions using the [KernelFunction] attribute:

using System.ComponentModel;
using GroupeIsa.Neos.Application.AutoSuggest;
using Microsoft.SemanticKernel;

public class LocationSkill : IAutoSuggestSkill
{
    public string Instructions => "You can get postal codes using the GetPostalCode function.";

    public string? DependencyInstructions => null;

    public IEnumerable<Type> Dependencies => [];

    [KernelFunction("GetPostalCode")]
    [Description("Get the postal code for a city in a specific country")]
    public string GetPostalCode(
        [Description("The city name")] string city,
        [Description("The country code")] string countryCode)
    {
        // Implementation to lookup postal code from a database or external service
        return "75001"; // Example
    }
}
Note

For more details on creating skills, see Create your own skill.

Customizing the prompt provider

For advanced customization, you can decorate the default IAutoSuggestPromptProvider or IAutoSuggestTemplateLoader implementations:

using GroupeIsa.Neos.Application.AutoSuggest;

public class Startup : IStartup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.Decorate<IAutoSuggestTemplateLoader, CustomAutoSuggestTemplateLoader>();
        services.Decorate<IAutoSuggestPromptProvider, CustomAutoSuggestPromptProvider>();
    }
}

The decorator pattern allows you to extend the default behavior while preserving the original implementation:

public class CustomAutoSuggestPromptProvider : IAutoSuggestPromptProvider
{
    private readonly IAutoSuggestPromptProvider _inner;

    public CustomAutoSuggestPromptProvider(IAutoSuggestPromptProvider inner)
    {
        _inner = inner;
    }

    public async Task<IReadOnlyList<AutoSuggestPrompt>> BuildPromptsAsync(
        AutoSuggestContext context,
        CancellationToken cancellationToken = default)
    {
        // Add custom logic before or after calling the inner provider
        return await _inner.BuildPromptsAsync(context, cancellationToken);
    }

    public string GetPromptTemplate()
    {
        // Customize or extend the default template
        return _inner.GetPromptTemplate();
    }
}
Tip

For Neos Studio specific customizations, see Neos Studio auto-suggest configuration.

See also