# InteractionStatistics class

Namespace: [Grasshopper2.Components.Descriptive](https://developer.rhino3d.com/api/gh2/namespace/grasshopper2.components.descriptive.md) · Assembly: [Grasshopper2](https://developer.rhino3d.com/api/gh2/assembly/grasshopper2.md)

```cs
public sealed class InteractionStatistics
```

Tracks what the AI conversation loop has been doing on a given AiComponent: the current phase plus running counters for each kind of event (model calls, docs lookups, clarifications, compilation attempts, various failure modes). Also owns the lifecycle handle for the current run -- the [SolutionId](https://developer.rhino3d.com/api/gh2/type/grasshopper2.doc.solutionid.md) identifying it and the [CancellationToken](https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken) that aborts it. The component's attributes class draws from this state. Every property setter fires [InteractionStatistics.Changed](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/changed.md) on a real change. The owning component subscribes once and invalidates the canvas on Changed, so the drawing refreshes automatically as the loop progresses.

## Properties

- [Clarifications](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/clarifications.md): Times a clarification dialog has been shown to the user.
- [CompilationAttempts](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/compilationattempts.md): Times the model has submitted source via the Compilation tool.
- [CompileFailures](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/compilefailures.md): Submissions where Roslyn reported one or more compile errors.
- [ConstructorFailures](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/constructorfailures.md): Submissions where the Logic subclass's parameterless constructor threw.
- [ExampleLookups](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/examplelookups.md): Times the model has called the Explanation (example-fetch) tool.
- [IsBusy](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/isbusy.md): True when the conversation loop is mid-flight: the model is being called, a tool result is being computed, a clarification dialog is open, or Roslyn is compiling. False when idle or terminal.
- [ModelCalls](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/modelcalls.md): Total number of HTTP requests made to the LLM provider for this component.
- [PlainTextRetries](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/plaintextretries.md): Turns where the model returned prose instead of calling a tool.
- [RunId](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/runid.md): Identifier of the run currently owning this object, or [SolutionId.None](https://developer.rhino3d.com/api/gh2/type/grasshopper2.doc.solutionid/none.md) if no run is active.
- [ShapeFailures](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/shapefailures.md): Submissions that compiled but didn't expose exactly one concrete AiComponentLogic subclass.
- [State](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/state.md)
- [SymbolLookups](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/symbollookups.md): Times the model has called the Description (symbol-lookup) tool.
- [UnknownToolRetries](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/unknowntoolretries.md): Turns where the model called a tool we don't recognise.

## Methods

- [BeginRun](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/beginrun.md): Start a new run: cancel any prior in-flight run, allocate a fresh [SolutionId](https://developer.rhino3d.com/api/gh2/type/grasshopper2.doc.solutionid.md) and [CancellationTokenSource](https://learn.microsoft.com/dotnet/api/system.threading.cancellationtokensource), reset [InteractionStatistics.State](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/state.md) to [InteractionState.Idle](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstate.md), and return the token to thread through any awaitable work.
- [CancelCurrentRun](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/cancelcurrentrun.md): Cancel the in-flight run (if any): trip the token, mark the id as cancelled in the global registry, dispose the source, and move [InteractionStatistics.State](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/state.md) to [InteractionState.AbortedByUser](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstate.md) so the busy icon clears. Safe to call when no run is active -- a no-op in that case.
- [EndRun](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/endrun.md): Tear down the CTS at the end of a normal run. Only acts when the supplied id still matches [InteractionStatistics.RunId](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/runid.md); if a newer run has already replaced it, this is a no-op (the newer run owns the source).

## Events

- [Changed](https://developer.rhino3d.com/api/gh2/type/grasshopper2.components.descriptive.interactionstatistics/changed.md): Raised whenever any property changes.
