Class Sealed
public sealed class MokaJsonAiPanel : Microsoft.AspNetCore.Components.ComponentBase

Namespace: Moka.Blazor.Json.AI.Components

JSON-specific AI chat panel that wraps the generic MokaAiPanel and adds JSON analysis quick actions, viewer integration, and context building.

Inheritance

Inherits from: Microsoft.AspNetCore.Components.ComponentBase

Properties

NameDescription
IsSending Whether the AI panel is currently sending/streaming a response.
MessagesHeight Maximum height of the messages area. Default is "350px".
Placeholder Placeholder text for the input field. Default is "Ask about the JSON...".
ShowQuickActions Whether to show the quick action buttons (Summarize, Analyze, Schema). Default is true.
Theme Theme for the panel. When null, inherits from parent.
Title Title text shown in the panel header. Default is "AI Assistant".
Viewer The viewer instance to analyze. Required.

IsSending

public bool IsSending { get; }

Whether the AI panel is currently sending/streaming a response.

MessagesHeight

[Parameter]
public string MessagesHeight { get; set; }

Maximum height of the messages area. Default is "350px".

Placeholder

[Parameter]
public string Placeholder { get; set; }

Placeholder text for the input field. Default is "Ask about the JSON...".

ShowQuickActions

[Parameter]
public bool ShowQuickActions { get; set; }

Whether to show the quick action buttons (Summarize, Analyze, Schema). Default is true.

Theme

[Parameter]
public MokaJsonTheme? Theme { get; set; }

Theme for the panel. When null, inherits from parent.

Title

[Parameter]
public string Title { get; set; }

Title text shown in the panel header. Default is "AI Assistant".

Viewer

[Parameter]
public MokaJsonViewer? Viewer { get; set; }

The viewer instance to analyze. Required.

Methods

NameDescription
AddSource(string label, string json) Adds a named JSON data source to the multi-source scope. When multiple sources are added, the AI sees all of them labeled by name. This replaces the single-viewer context for the duration of the scope.
AskAboutNode(string path) Sends a prompt to the AI asking it to analyze the node at the given JSON Pointer path. Automatically scopes the context to the target node so the AI sees only the relevant subtree. Can be called from external components such as context menu actions.
ClearScope() Clears any active scope so the AI sees the full document context.
CreateAskAiContextAction(…) Creates a MokaJsonContextAction that sends a "Ask AI" prompt for the right-clicked node. Add the returned action to the viewer's MokaJsonViewer.ContextMenuActions list.
OnParametersSet() override
RemoveSource(string label) Removes a named data source from the multi-source scope.
ScopeToNode(string path) Scopes the AI context to a specific node path. Subsequent AI calls will include only the subtree at this path rather than the full document.

AddSource(string label, string json)

public void AddSource(string label, string json)

Adds a named JSON data source to the multi-source scope. When multiple sources are added, the AI sees all of them labeled by name. This replaces the single-viewer context for the duration of the scope.

Parameters

NameTypeDescription
labelstringHuman-readable label (e.g., "Customer", "Order").
jsonstringThe JSON string for this source.

AskAboutNode(string path)

public Task AskAboutNode(string path)

Sends a prompt to the AI asking it to analyze the node at the given JSON Pointer path. Automatically scopes the context to the target node so the AI sees only the relevant subtree. Can be called from external components such as context menu actions.

Parameters

NameTypeDescription
pathstringJSON Pointer path (e.g., "/users/0/name").

ClearScope()

public void ClearScope()

Clears any active scope so the AI sees the full document context.

CreateAskAiContextAction(string label, string? tooltip, int order)

public MokaJsonContextAction CreateAskAiContextAction(string label = "Ask AI", string? tooltip = null, int order = 900)

Creates a MokaJsonContextAction that sends a "Ask AI" prompt for the right-clicked node. Add the returned action to the viewer's MokaJsonViewer.ContextMenuActions list.

Examples


        <MokaJsonViewer @ref="_viewer" Json="@json" ContextMenuActions="_contextActions" />
        <MokaJsonAiPanel @ref="_aiPanel" Viewer="_viewer" />
    
        @code {
            private MokaJsonAiPanel _aiPanel = null!;
            private List<MokaJsonContextAction> _contextActions = null!;
    
            protected override void OnInitialized()
                => _contextActions = [_aiPanel.CreateAskAiContextAction()];
        }
        

RemoveSource(string label)

public void RemoveSource(string label)

Removes a named data source from the multi-source scope.

ScopeToNode(string path)

public void ScopeToNode(string path)

Scopes the AI context to a specific node path. Subsequent AI calls will include only the subtree at this path rather than the full document.

Parameters

NameTypeDescription
pathstringJSON Pointer path (e.g., "/users/0").
Type Relationships
classDiagram
    style MokaJsonAiPanel fill:#f9f,stroke:#333,stroke-width:2px
    MokaJsonAiPanel --|> ComponentBase : inherits
View Source
/// <summary>
///     JSON-specific AI chat panel that wraps the generic <see cref = "MokaAiPanel"/>
///     and adds JSON analysis quick actions, viewer integration, and context building.
/// </summary>
public sealed partial class MokaJsonAiPanel : ComponentBase
{
    /// <summary>
    ///     The viewer instance to analyze. Required.
    /// </summary>
    [Parameter]
    public MokaJsonViewer? Viewer { get; set; }

    /// <summary>
    ///     Theme for the panel. When <c>null</c>, inherits from parent.
    /// </summary>
    [Parameter]
    public MokaJsonTheme? Theme { get; set; }

    /// <summary>
    ///     Maximum height of the messages area. Default is <c>"350px"</c>.
    /// </summary>
    [Parameter]
    public string MessagesHeight { get; set; } = "350px";

    /// <summary>
    ///     Placeholder text for the input field. Default is <c>"Ask about the JSON..."</c>.
    /// </summary>
    [Parameter]
    public string Placeholder { get; set; } = "Ask about the JSON...";

    /// <summary>
    ///     Whether to show the quick action buttons (Summarize, Analyze, Schema). Default is <c>true</c>.
    /// </summary>
    [Parameter]
    public bool ShowQuickActions { get; set; } = true;

    /// <summary>
    ///     Title text shown in the panel header. Default is <c>"AI Assistant"</c>.
    /// </summary>
    [Parameter]
    public string Title { get; set; } = "AI Assistant";
    /// <summary>
    ///     Whether the AI panel is currently sending/streaming a response.
    /// </summary>
    public bool IsSending => _panel?.IsSending ?? false;

    protected override void OnParametersSet()
    {
        // Keep the context builder in sync with the current viewer
        ContextBuilder.SetViewer(Viewer);
    }

    /// <summary>
    ///     Scopes the AI context to a specific node path. Subsequent AI calls will include
    ///     only the subtree at this path rather than the full document.
    /// </summary>
    /// <param name = "path">JSON Pointer path (e.g., "/users/0").</param>
    public void ScopeToNode(string path) => ContextBuilder.SetScope("path", path);
    /// <summary>
    ///     Adds a named JSON data source to the multi-source scope.
    ///     When multiple sources are added, the AI sees all of them labeled by name.
    ///     This replaces the single-viewer context for the duration of the scope.
    /// </summary>
    /// <param name = "label">Human-readable label (e.g., "Customer", "Order").</param>
    /// <param name = "json">The JSON string for this source.</param>
    public void AddSource(string label, string json)
    {
        if (!ContextBuilder.GetScopes().TryGetValue("sources", out object? existing) || existing is not Dictionary<string, string> sources)
        {
            sources = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            ContextBuilder.SetScope("sources", sources);
        }

        sources[label] = json;
    }

    /// <summary>
    ///     Removes a named data source from the multi-source scope.
    /// </summary>
    public void RemoveSource(string label)
    {
        if (ContextBuilder.GetScopes().TryGetValue("sources", out object? existing) && existing is Dictionary<string, string> sources)
        {
            sources.Remove(label);
            if (sources.Count == 0)
            {
                ContextBuilder.ClearScope("sources");
            }
        }
    }

    /// <summary>
    ///     Clears any active scope so the AI sees the full document context.
    /// </summary>
    public void ClearScope() => ContextBuilder.ClearScope();
    /// <summary>
    ///     Sends a prompt to the AI asking it to analyze the node at the given JSON Pointer path.
    ///     Automatically scopes the context to the target node so the AI sees only the relevant subtree.
    ///     Can be called from external components such as context menu actions.
    /// </summary>
    /// <param name = "path">JSON Pointer path (e.g., "/users/0/name").</param>
    public async Task AskAboutNode(string path)
    {
        if (_panel is null || _panel.IsSending || string.IsNullOrEmpty(path))
        {
            return;
        }

        // Scope context to the target node so the AI receives the subtree, not the full document
        ContextBuilder.SetScope("path", path);
        string prompt = $"Describe and analyze the node at path `{path}`. What is this data, what are its properties, and is there anything notable?";
        await _panel.SendToAi(prompt);
        // Clear scope after sending so subsequent general questions see the full document
        ContextBuilder.ClearScope("path");
    }

    /// <summary>
    ///     Creates a <see cref = "MokaJsonContextAction"/> that sends a "Ask AI" prompt
    ///     for the right-clicked node. Add the returned action to the viewer's
    ///     <see cref = "MokaJsonViewer.ContextMenuActions"/> list.
    /// </summary>
    /// <example>
    ///     <code>
    ///     &lt;MokaJsonViewer @ref="_viewer" Json="@json" ContextMenuActions="_contextActions" /&gt;
    ///     &lt;MokaJsonAiPanel @ref="_aiPanel" Viewer="_viewer" /&gt;
    /// 
    ///     @code {
    ///         private MokaJsonAiPanel _aiPanel = null!;
    ///         private List&lt;MokaJsonContextAction&gt; _contextActions = null!;
    /// 
    ///         protected override void OnInitialized()
    ///             =&gt; _contextActions = [_aiPanel.CreateAskAiContextAction()];
    ///     }
    ///     </code>
    /// </example>
    public MokaJsonContextAction CreateAskAiContextAction(string label = "Ask AI", string? tooltip = null, int order = 900)
    {
        return new MokaJsonContextAction
        {
            Id = "moka-ask-ai",
            Label = label,
            IconSvg = """<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 2a4 4 0 0 1 4 4v1a4 4 0 0 1-8 0V6a4 4 0 0 1 4-4z"/><circle cx="6.5" cy="6" r="0.6" fill="currentColor" stroke="none"/><circle cx="9.5" cy="6" r="0.6" fill="currentColor" stroke="none"/><path d="M6.5 8.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5"/><path d="M4 13h8"/></svg>""",
            ShortcutHint = tooltip,
            Order = order,
            HasSeparatorBefore = true,
            IsEnabled = _ => _panel is not null && !_panel.IsSending,
            OnExecute = async ctx =>
            {
                await AskAboutNode(ctx.Path);
            }
        };
    }
}
Was this page helpful?