Skip to main content

REFERENCE

SDK Demos

How to use @asgard-js/core and @asgard-js/react, with demos you can try on the page.

Dock the Run-Chrome Yourself

The Task Check List and Subagent List are run-level chrome — they describe the state of the whole turn, not of any one message. So the SDK docks them in a fixed strip that sits outside the thread's scroll box, between it and the composer.

  1. Why Outside the Scroll Box​

    They used to render at the tail of the thread and scroll with the messages. The result: during a streaming run the thread kept growing and auto-scrolling, shoving the panels around. Moved into a fixed strip, they now stay put while a run streams.

    The strip has two more rules:

    • Capped at 50% of the body height, scrolling internally past that — the thread always keeps the other half
    • When there is no chrome, the strip does not exist and takes no space — the composer sits flush against the last message
  2. Placing Them Yourself​

    <Chatbot hideRunChrome {...rest} />

    With that set, the built-in panels are not rendered and you can put the exported <TaskList> / <SubagentList> anywhere — a right rail, a drawer, a separate tab.

    import { TaskList, SubagentList, AsgardThemeScope } from "@asgard-js/react";
    import { deriveTasks, deriveSubagents } from "@asgard-js/core";

    // conversation comes from useAsgardContext()
    const tasks = deriveTasks(conversation);
    const subagents = deriveSubagents(conversation);

    <AsgardThemeScope theme={theme}>
    <SubagentList subagents={subagents} locale="en-US" />
    <TaskList tasks={tasks} locale="en-US" />
    </AsgardThemeScope>
    Always wrap in AsgardThemeScope

    Outside <Chatbot> the panels miss the design tokens the chat shell emits and fall back to the light-themed defaults. See Re-establish the Theme.

  3. Where the Data Comes From​

    Both panels take plain arrays — they are not coupled to SDK state:

    function TaskList(props: { tasks: Task[]; locale?: Locale }): ReactNode;
    function SubagentList(props: { subagents: Subagent[]; locale?: Locale }): ReactNode;

    deriveTasks / deriveSubagents fold both out of a Conversation. To subscribe rather than recompute, core also offers createDerivedStores, with tasksEqual / subagentsEqual for comparison.

    import {
    deriveTasks, deriveSubagents,
    tasksEqual, subagentsEqual,
    createDerivedStores,
    } from "@asgard-js/core";
  4. Types​

    interface Task {
    id: string;
    subject: string; // Noun-form title; shown when not in progress
    activeForm?: string; // Present-continuous label; preferred while in progress
    description?: string; // Full detail, shown when the row is expanded
    status: "pending" | "in_progress" | "completed";
    }

    interface Subagent {
    parentToolUseId: string; // Correlation key = the Agent tool-call that spawned it
    agentId?: string;
    subagentType?: string; // e.g. general-purpose
    description?: string;
    status: "running" | "completed" | "failed" | "cancelled";
    summary?: string;
    tools: SubagentToolCall[]; // The child tool-calls this subagent ran
    }

    A subagent's terminal status comes only from the subagent.complete event — it is never inferred from the Agent tool-call's own completion (async subagents complete their tool-call early with async_launched).

  5. See Also​

Ready to get started?

Want to see how Asgard fits your team? Talk to us.

Contact us