Class TaskCardComponent

java.lang.Object
ai.mindconnect.adminui.ui.component.TaskCardComponent
All Implemented Interfaces:
UiComponent

public final class TaskCardComponent extends Object implements UiComponent
One tool-call or sub-agent-call card rendered as a collapsible <details> list item.

A card has three lifecycle states; this component is constructed directly in the state it should render in (no internal mutation):

  • running — header shows ⏳ name — running…, body shows the input arguments, card is open by default so the user can see what's executing.
  • done — header shows ✓ name (duration ms), body shows input + output, card is collapsed.
  • failed — header shows ✗ name (duration ms), body shows input + the error message, card is collapsed.

Sub-agent cards build a real tree. Instead of indenting nested tool calls with whitespace, a sub-agent card's body is a UiStack that contains a nested UiList with a stable id (childListId(String)). The sub-agent's own tool-call cards are appended into that nested list, so the DOM hierarchy mirrors the agent call hierarchy. A patch targeting the nested list's id appends straight into its <ul>; a patch targeting a child card's id morphs that <li> in place — both work regardless of nesting depth because the SPA patch dispatcher resolves targets by element id.

Cards live as a single <li> inside their list's <ul>. The rendered UiList wraps a single UiList.Item so the JS append-into-list path treats it as a one-item insert.

  • Constructor Details

    • TaskCardComponent

      public TaskCardComponent(String nodeId, String headerLabel, ai.mindconnect.ui.model.UiNode body, boolean open)
      Primary constructor — caller supplies the fully-built body node.
    • TaskCardComponent

      public TaskCardComponent(String nodeId, String headerLabel, ai.mindconnect.ui.model.UiNode body, boolean open, String summaryId)
      Full constructor — summaryId makes the summary text individually REPLACEable.
    • TaskCardComponent

      public TaskCardComponent(String nodeId, String headerLabel, String bodyMarkdown, boolean open)
      Convenience constructor for the common markdown-body case.
  • Method Details

    • summaryId

      public static String summaryId(String taskId)
      Stable id of a sub-agent card's summary span (the running/done marker shown even when collapsed).
    • id

      public String id()
      The id of the card's <li>; what REPLACE patches target.
      Specified by:
      id in interface UiComponent
    • childListId

      public static String childListId(String subAgentTaskId)
      Stable id of the nested <ul>-bearing list that holds a sub-agent's child task cards. Inner tool-call events APPEND into this id so they nest under the sub-agent instead of going flat into the message list. Derived purely from the sub-agent's taskId so the streaming handler can compute it without holding a reference to the card object.
    • render

      public ai.mindconnect.ui.model.UiList render()
      Renders as a single-item UiList wrapper. The wrapper id differs from the item id so a REPLACE on the item (id()) morphs the <li> content without disturbing the surrounding list — but APPEND on the message list's id can also take this wrapper directly: the renderer's "append a list" path extracts its items into the existing <ul>.
      Specified by:
      render in interface UiComponent
    • runningTool

      public static TaskCardComponent runningTool(String nodeId, String toolName, Object arguments)
      Card representing a tool call that has just started.
    • doneTool

      public static TaskCardComponent doneTool(String nodeId, String toolName, Object arguments, String result, long durationMs)
      Card representing a tool call that finished successfully.
    • failedTool

      public static TaskCardComponent failedTool(String nodeId, String toolName, Object arguments, String error, long durationMs)
      Card representing a tool call that failed.
    • stackId

      public static String stackId(String taskId)
      Stable id of a sub-agent card's body stack (append target for the final answer).
    • openSessionLink

      public static ai.mindconnect.ui.model.UiLink openSessionLink(String subSessionId)
      A link that opens the sub-agent's own session page in a new browser tab. external → target="_blank" with no SPA interception. subSessionId is the sub-session's id (== the card's taskId).
    • runningSubAgent

      public static TaskCardComponent runningSubAgent(String nodeId, String agentName, String taskId, String subSessionId, String inputJson)
      The running sub-agent card. Built once at SubAgentStarted. The <details> summary carries the live status marker (⏳ + agent name) inside an id'd span so it can be flipped to ✓/✗ on completion without touching the nested tree — and stays visible when the card is collapsed. The body opens with a link to the sub-session and (once known) the input, then the nested child list; the final answer is appended beneath it on done.

      subSessionId is the durable session id this card is keyed on (== taskId for live cards). inputJson is the run_agent call's arguments, or null when not yet known live.

    • subAgentChildList

      public static ai.mindconnect.ui.model.UiList subAgentChildList(String taskId)
      The nested child list (subtasks-{taskId}) that child cards append into.
    • doneSubAgentSummary

      public static ai.mindconnect.ui.model.UiText doneSubAgentSummary(String taskId, String agentName, long durationMs)
      Summary-span REPLACE node flipping the marker to "done". Visible while collapsed.
    • failedSubAgentSummary

      public static ai.mindconnect.ui.model.UiText failedSubAgentSummary(String taskId, String agentName)
      Summary-span REPLACE node flipping the marker to "failed".
    • subAgentAnswer

      public static ai.mindconnect.ui.ext.markdown.UiMarkdown subAgentAnswer(String taskId, String finalText)
      Markdown node holding the sub-agent's final answer — APPENDed into the body stack on done.
    • historic

      public static TaskCardComponent historic(String nodeId, String header, String body)
      Card rebuilt from persisted TOOL_CALL + TOOL_RESULT messages. Caller passes a pre-computed header (already labelled done/failed) and the card body produced by taskCardBody(String, String).
    • historicSubAgent

      public static TaskCardComponent historicSubAgent(String nodeId, String agentName, String taskId, boolean running, boolean failed, long durationMs, String inputJson, String resultText, ai.mindconnect.ui.model.UiList childList, String finalTextMarkdown)
      Sub-agent card rebuilt from persisted state on a full page load. Keyed on the sub-session id (taskId) so its ids match the ones the live stream uses — a reload mid-run produces the identical nodes and the run's continuing live patches (summary flip, answer append) still land. childList holds the recursively-built child cards; pass finalTextMarkdown == null while the sub-agent is still running so no answer block is shown yet.

      The body reads like a normal tool card plus the tree: a link to open the sub-session in a new tab, the call's **Input** (and **Output** when it differs from the rendered answer), the nested child tree, then the sub-agent's final answer as a chat bubble.

      Parameters:
      running - when true the summary shows the ⏳ marker and the card starts open; the summary id lets a later done patch flip it.
      inputJson - the run_agent call's pretty-printed arguments, or null.
      resultText - the persisted tool-result text (≈ the answer), or null while running.
    • runningToolHeader

      public static String runningToolHeader(String toolName)
      "⏳ toolName — running…".
    • doneToolHeader

      public static String doneToolHeader(String toolName, long durationMs)
      "✓ toolName (123 ms)".
    • failedToolHeader

      public static String failedToolHeader(String toolName, long durationMs)
      "✗ toolName (123 ms)".
    • runningSubAgentHeader

      public static String runningSubAgentHeader(String agentName)
    • doneSubAgentHeader

      public static String doneSubAgentHeader(String agentName, long durationMs)
    • failedSubAgentHeader

      public static String failedSubAgentHeader(String agentName)
    • taskCardBody

      public static String taskCardBody(String inputJsonOrText, String output)
      Builds the markdown body of a task card: optional **Input** code block, optional **Output** code block, or a placeholder when both are null.
    • prettyJson

      public static String prettyJson(Object value)
      Pretty-prints arguments map as JSON; falls back to toString on errors.