# AiAgentStepView
## Description
BitAiAgentStepView is one step of an agent run, drawn as an entry of a timeline so the sequence and the current position read at a glance: a marker that says the state (pending, running, blocked, completed, failed, skipped), the title with how long the step took or has been taking, its detail and summary, the tool calls it made - by name and status when the conversation is given - and the error of a failed step. A BitAiAgentRunView renders one per step; on its own it draws any step an application keeps.
## Parameters
| Name | Type | Default Value | Description |
| :--- | :--- | :------------ | :---------- |
| Classes | `BitAiAgentStepViewClassStyles?` | null | Custom CSS classes for different parts of the agent step view. |
| Conversation | `BitAiConversation?` | null | The conversation the run belongs to, in which the tool calls of the step are looked up (newest message first) to show them by tool name and status: a running call with the dots of a loader, a failed one in the error color. Without it the calls are listed by their identifiers. A BitAiAgentRunView hands down the conversation of its Session. |
| Step | `BitAiAgentStep` | | The step to render (required). The view subscribes to its Changed event and re-renders at most once per render interval as it changes; a tool call changing on its own is drawn with the next change of the step. |
| Styles | `BitAiAgentStepViewClassStyles?` | null | Custom CSS styles for different parts of the agent step view. |
| AriaLabel | `string?` | null | Gets or sets the accessible label for the component, used by assistive technologies. |
| Class | `string?` | null | Gets or sets the CSS class name(s) to apply to the rendered element. |
| Dir | `BitDir?` | null | Gets or sets the text directionality for the component's content. |
| Disabled | `bool` | false | Gets or sets a value indicating whether the component is disabled and cannot respond to user interaction. |
| ForceAnimation | `bool` | false | Gets or sets a value indicating whether the component's animations play at their full duration even when reduced motion is requested. |
| HtmlAttributes | `Dictionary<string, object>` | new Dictionary<string, object>() | Captures additional HTML attributes to be applied to the rendered element, in addition to the component's parameters. An attribute written on the component wins over an entry of the same name. |
| Id | `string?` | null | Gets or sets the unique identifier for the component's root element. |
| Style | `string?` | null | Gets or sets the CSS style string to apply to the rendered element. |
| TabIndex | `string?` | null | Gets or sets the tab order index for the component when navigating with the keyboard. |
| Visibility | `BitVisibility` | BitVisibility.Visible | Gets or sets the visibility state (visible, hidden, or collapsed) of the component. |
## Public Members
| Name | Type | Default Value | Description |
| :--- | :--- | :------------ | :---------- |
| UniqueId | `Guid` | Guid.NewGuid() | Gets the readonly unique identifier for the component's root element, assigned when the component instance is constructed. |
| RootElement | `ElementReference` | | Gets the reference to the root HTML element associated with this component. |
## Enums
### BitAiAgentStepStatus Enum
| Name | Value | Description |
| :--- | :--- | :---------- |
| Pending | 0 | Planned but not started. Its marker is an empty ring and its title is dimmed. |
| Running | 1 | Currently executing. Its marker pulses, and the time it has been running shows beside the title. |
| Blocked | 2 | Paused pending human input or approval: a question of its run (BitAiAgentRun.RequestInput) blocks the steps running with it until it is answered. Its marker is drawn in the warning color. |
| Completed | 3 | Finished successfully. Its marker carries a check mark, and the time it took shows beside the title. |
| Failed | 4 | Finished unsuccessfully. Its marker is drawn in the error color, and the message of its error shows under it, with the detail of the error behind a disclosure. |
| Skipped | 5 | Abandoned because the run ended or the plan changed: a run that fails or is cancelled skips every step it did not finish. Drawn like a pending step. |
### BitVisibility Enum
| Name | Value | Description |
| :--- | :--- | :---------- |
| Visible | 0 | The content of the component is visible. |
| Hidden | 1 | The content of the component is hidden, but the space it takes on the page remains (visibility:hidden). |
| Collapsed | 2 | The component is hidden (display:none). |
### BitDir Enum
| Name | Value | Description |
| :--- | :--- | :---------- |
| Ltr | 0 | Ltr (left to right) is to be used for languages that are written from the left to the right (like English). |
| Rtl | 1 | Rtl (right to left) is to be used for languages that are written from the right to the left (like Arabic). |
| Auto | 2 | Auto lets the user agent decide. It uses a basic algorithm as it parses the characters inside the element until it finds a character with a strong directionality, then applies that directionality to the whole element. |
## Sub Classes
### BitAiAgentStepViewClassStyles Properties
| Name | Type | Default Value | Description |
| :--- | :--- | :------------ | :---------- |
| Root | `string?` | null | Custom CSS classes/styles for the root element of the BitAiAgentStepView. |
| Marker | `string?` | null | Custom CSS classes/styles for the timeline marker of the BitAiAgentStepView. |
| MarkerIcon | `string?` | null | Custom CSS classes/styles for the check icon of the marker of a completed BitAiAgentStepView. |
| Body | `string?` | null | Custom CSS classes/styles for the body (everything beside the marker) of the BitAiAgentStepView. |
| Title | `string?` | null | Custom CSS classes/styles for the title row (the title and the duration) of the BitAiAgentStepView. |
| Duration | `string?` | null | Custom CSS classes/styles for the duration (or the time elapsed so far) of the BitAiAgentStepView. |
| Detail | `string?` | null | Custom CSS classes/styles for the detail of the BitAiAgentStepView. |
| Summary | `string?` | null | Custom CSS classes/styles for the summary of the BitAiAgentStepView. |
| ToolCalls | `string?` | null | Custom CSS classes/styles for the list of tool calls of the BitAiAgentStepView. |
| ToolCall | `string?` | null | Custom CSS classes/styles for each item of the list of tool calls of the BitAiAgentStepView. |
| ToolCallTag | `BitTagClassStyles?` | null | Custom CSS classes/styles for the BitTag of each tool call of the BitAiAgentStepView. |
| Error | `string?` | null | Custom CSS classes/styles for the error message of the BitAiAgentStepView. |
| ErrorDetailButton | `BitButtonClassStyles?` | null | Custom CSS classes/styles for the button (a BitButton) disclosing the detail of the error of a failed BitAiAgentStepView. |
| ErrorDetail | `string?` | null | Custom CSS classes/styles for the detail of the error of a failed BitAiAgentStepView, shown behind the disclosure. |
### BitAiAgentStep Properties
One step of an agent run - the unit the user reasons about ("search the docs"), which usually contains one or more tool calls. A run creates its steps from its plan (BitAiAgentRun.SetPlan, GetOrAddStep); an application keeping steps of its own creates one with new BitAiAgentStep(stepId, title). Every change raises Changed.
| Name | Type | Default Value | Description |
| :--- | :--- | :------------ | :---------- |
| StepId | `string` | | The stable identifier of the step, preserved across plan revisions. |
| Title | `string` | | What the step does. Set by the constructor and renewed by a plan revision. |
| Detail | `string?` | null | An elaboration of the step, shown under its title. |
| Status | `BitAiAgentStepStatus` | BitAiAgentStepStatus.Pending | Where the step is in its lifecycle: moved by Start, Block and Complete. |
| Summary | `string?` | null | A short account of what the step produced, given to Complete. |
| Error | `BitAiError?` | null | The failure, when the step failed: its Message is shown under the step, and its Detail behind a Show details disclosure. |
| StartedAt | `DateTimeOffset?` | null | When the step started (the first Start). |
| CompletedAt | `DateTimeOffset?` | null | When the step finished. |
| Duration | `TimeSpan?` | null | How long the step took, once it has both started and finished; a step completed without being started has none, so the view shows no time for it. |
| ToolCallIds | `IReadOnlyList<string>` | [] | The identifiers of the tool calls made during this step. |
| Version | `int` | 0 | Increments on every change, for cheap render checks. |
| Changed | `event Action<BitAiAgentStep>?` | | Raised after the step changes. |
| Start | `void` | | Start(): marks the step running, and records when it started the first time. |
| Block | `void` | | Block(): marks the step blocked on the user (a question, an approval). |
| AddToolCall | `void` | | AddToolCall(string toolCallId): records a tool call made during this step. Recording the same call twice has no effect, and calls reported in parallel are all kept. |
| Complete | `void` | | Complete(BitAiAgentStepStatus status = Completed, string? summary = null, BitAiError? error = null): marks the step finished - Completed, Failed or Skipped - with what it produced or what it failed with, and records when it finished. |
## CSS Variables
Public CSS custom properties read off the component's root. Set one on `:root` to restyle every instance, on any ancestor to restyle the ones inside it, or on the `Style` of one instance to restyle it and every instance nested inside it, which inherits the value too - a parameter changes one alone, as does the real CSS property on its `Style` / `Styles` when that property does not inherit (`opacity`); an inherited one (`color`, `font-family`) reaches the nested instances that do not set it themselves.
| Name | Default Value | Description |
| :--- | :------------ | :---------- |
| `--bit-AiAgentStepView-gap` | spacing(1.5) | Room between the marker and the body. |
| `--bit-AiAgentStepView-marker-size` | var(--bit-siz-icon-md) | Diameter of the timeline marker, which the line to the next step is placed by too. |
| `--bit-AiAgentStepView-marker-color` | var(--bit-clr-brd-pri) | Ring of a pending or skipped step. |
| `--bit-AiAgentStepView-running-color` | var(--bit-clr-pri) | Ring and pulse of the running step. |
| `--bit-AiAgentStepView-completed-color` | var(--bit-clr-suc) | Marker of a completed step. |
| `--bit-AiAgentStepView-completed-icon-color` | var(--bit-clr-suc-text) | Check mark of a completed step. |
| `--bit-AiAgentStepView-failed-color` | var(--bit-clr-err) | Marker of a failed step. |
| `--bit-AiAgentStepView-blocked-color` | var(--bit-clr-wrn) | Marker of a step waiting on the user. |
| `--bit-AiAgentStepView-line-color` | var(--bit-clr-brd-sec) | Line joining a step to the next one. |
| `--bit-AiAgentStepView-title-font-size` | var(--bit-tpg-fs-sm) | Size of the title (the rest of the step is sized from it). |
| `--bit-AiAgentStepView-text-color` | var(--bit-clr-fg-sec) | The detail, the summary and the duration, and the detail of the error of a failed step. |
| `--bit-AiAgentStepView-error-color` | var(--bit-clr-err-fg) | The error message of a failed step. |
## Examples
\n**Basic**:
```razor
Run the step
```
```csharp
private BitAiAgentStep basicStep = new("search", "Search the documentation");
private bool isBasicRunning;
private async Task RunBasicStep()
{
isBasicRunning = true;
var step = new BitAiAgentStep("search", "Search the documentation");
basicStep = step;
step.Start();
await Task.Delay(1500);
step.Complete(summary: "2 passages matched");
isBasicRunning = false;
}
```
\n**Statuses**:
```razor
```
```csharp
private readonly BitAiAgentStep detailStep = CreateDetailStep();
private static BitAiAgentStep CreateDetailStep()
{
var step = new BitAiAgentStep("reconcile", "Reconcile the disagreements")
{
Detail = "Compare how each study chose its population, and whether that explains the gap.",
};
step.Complete(summary: "The disagreement is about scope, not direction");
return step;
}
```
\n**Tool calls**:
```razor
Run the step
```
```csharp
private BitAiConversation toolConversation = new();
private BitAiAgentStep toolStep = new("forecast", "Look up the forecast and the travel advice");
private bool isToolRunning;
private async Task RunToolStep()
{
isToolRunning = true;
var conversation = new BitAiConversation();
var message = conversation.AddMessage(new BitAiMessage(BitAiRole.Assistant));
var step = new BitAiAgentStep("forecast", "Look up the forecast and the travel advice");
toolConversation = conversation;
toolStep = step;
step.Start();
var weather = message.AddPart(new BitAiToolCallPart(BitAiId.NewToolCallId(), "get_weather"));
weather.SetStatus(BitAiToolCallStatus.Running);
step.AddToolCall(weather.ToolCallId);
await Task.Delay(1500);
weather.SetResult(BitAiToolOutcome.FromText("Oslo: -3 degrees, snow"));
var advice = message.AddPart(new BitAiToolCallPart(BitAiId.NewToolCallId(), "search_docs"));
advice.SetStatus(BitAiToolCallStatus.Running);
step.AddToolCall(advice.ToolCallId);
await Task.Delay(1500);
advice.SetResult(BitAiToolOutcome.Failure("The travel advice index is unavailable."));
step.Complete(summary: "The forecast is in; the travel advice could not be read");
isToolRunning = false;
}
```
\n**Disabled**:
```razor
```
```csharp
private readonly (BitAiConversation Conversation, BitAiAgentStep Step) disabled = CreateDisabledStep();
private static (BitAiConversation Conversation, BitAiAgentStep Step) CreateDisabledStep()
{
var conversation = new BitAiConversation();
var message = conversation.AddMessage(new BitAiMessage(BitAiRole.Assistant));
var call = message.AddPart(new BitAiToolCallPart(BitAiId.NewToolCallId(), "run_tests"));
call.SetResult(BitAiToolOutcome.Failure("3 of 812 tests failed."));
var step = new BitAiAgentStep("test", "Run the test suite");
step.Start();
step.AddToolCall(call.ToolCallId);
step.Complete(BitAiAgentStepStatus.Failed, error: new BitAiError("3 of 812 tests failed.")
{
Detail = "Checkout.AppliesDiscount\nCheckout.RoundsTax\nCheckout.HandlesRefund",
});
return (conversation, step);
}
```
\n**Cascading parameters**:
```razor
```
```csharp
private readonly BitAiAgentStepViewParams[] stepViewParams =
[
new() { Styles = new() { Summary = "font-style: italic", Title = "color: var(--bit-clr-pri)" } }
];
private readonly BitAiAgentStep[] cascadingSteps = CreateCascadingSteps();
private static BitAiAgentStep[] CreateCascadingSteps()
{
var outline = new BitAiAgentStep("outline", "Outline the post");
outline.Complete(summary: "Five sections");
var draft = new BitAiAgentStep("draft", "Draft it");
draft.Complete(summary: "1,200 words");
var proofread = new BitAiAgentStep("proofread", "Proofread it");
proofread.Complete(summary: "Two typos fixed");
return [outline, draft, proofread];
}
```
\n**Style & Class**:
```razor
```
```csharp
private readonly BitAiAgentStep[] rtlSteps = CreateRtlSteps();
private static BitAiAgentStep[] CreateRtlSteps()
{
var search = new BitAiAgentStep("search", "جستجوی منابع اصلی");
search.Complete(summary: "۱۱ نتیجه، ۳ تا اصلی به نظر میرسند");
var read = new BitAiAgentStep("read", "خواندن سه منبع مرتبطتر");
read.Start();
var write = new BitAiAgentStep("write", "نوشتن خلاصه");
return [search, read, write];
}
```
@foreach (var step in statusSteps)
{
}
```
```csharp
private readonly BitAiAgentStep[] statusSteps = CreateStatusSteps();
private static BitAiAgentStep[] CreateStatusSteps()
{
var pending = new BitAiAgentStep("pending", "Pending: planned, not started yet");
var running = new BitAiAgentStep("running", "Running: being worked on");
running.Start();
var blocked = new BitAiAgentStep("blocked", "Blocked: waiting on the user");
blocked.Start();
blocked.Block();
var completed = new BitAiAgentStep("completed", "Completed: finished successfully");
completed.Complete(summary: "11 results, 3 look primary");
var failed = new BitAiAgentStep("failed", "Failed: finished unsuccessfully");
failed.Complete(BitAiAgentStepStatus.Failed, error: new BitAiError("3 of 812 tests failed.")
{
Detail = "Checkout.AppliesDiscount\nCheckout.RoundsTax\nCheckout.HandlesRefund",
});
var skipped = new BitAiAgentStep("skipped", "Skipped: abandoned when the run ended");
skipped.Complete(BitAiAgentStepStatus.Skipped);
return [pending, running, blocked, completed, failed, skipped];
}
```
\n**Detail & summary**:
```razor
@foreach (var step in styleSteps)
{
}
```
```csharp
private readonly BitAiAgentStep[] styleSteps = CreateStyleSteps();
private static BitAiAgentStep[] CreateStyleSteps()
{
var venue = new BitAiAgentStep("venue", "Book the venue");
venue.Complete(summary: "The lakeside hall, for 40");
var invitations = new BitAiAgentStep("invitations", "Send the invitations");
invitations.Start();
return [venue, invitations];
}
```
\n**RTL**:
```razor
@foreach (var step in rtlSteps)
{
}