architects-toolkit/SmartHopperGitHubLast refreshed Oct 3, 2026
This is a public, read-only report. Striff reads this repository's docs, turns each sentence that makes a claim about the code into a rule, and checks the rule against the code on the default branch. How this works
Names these docs write that the code no longer has1
Each sentence below names a type the default branch doesn't declare, or declares somewhere else. Edit the doc so it matches the code, or bring the type back.
GoneProviderComponentHelper
Delegates the menu and serialization to [ProviderComponentHelper](./ProviderComponentHelper.md).
The repository once held src/SmartHopper.Core/ComponentBase/ProviderComponentHelper.cs. It doesn't now. Closest name there: ProviderComponentBase.
GH_AIInputPayload — Wraps an AIInputPayload (a collection of IAIInteraction items with a capability hint and payload type).
GH_AIInputPayload depends on AIInputPayload
Holds
Read Oct 3
GH_AIInputPayload — Wraps an AIInputPayload (a collection of IAIInteraction items with a capability hint and payload type). Persisted as JSON via AIInputPayloadCodec.
AIInputPayloadCodec depends on GH_AIInputPayload
Holds
Read Oct 3
GH_AIInputPayload — Wraps an AIInputPayload (a collection of IAIInteraction items with a capability hint and payload type).
GH_AIInputPayload depends on IAIInteraction
Holds
Read Oct 2
Provider EnvironmentContextProvider, Source SmartHopper.Core, Data OS, Rhino version, platform
EnvironmentContextProvider is in SmartHopper.Core
Holds
Read Oct 2
Provider TimeContextProvider, Source SmartHopper.Core, Data Current time and timezone
TimeContextProvider is in SmartHopper.Core
Holds
Read Oct 2
Provider FileContextProvider, Source SmartHopper.Core, Data Current file, selection, object counts
FileContextProvider is in SmartHopper.Core
Holds
Read Oct 3
Type CanvasMutationConsentProposal, Responsibility Adapts CanvasChangeReviewSession to consent
CanvasMutationConsentProposal depends on CanvasChangeReviewSession
Holds
Read Oct 3
McpServerLifecycle is ref-counted: Acquire(object key, McpServerOptions options) starts the shared server for a port when needed.
McpServerLifecycle has an Acquire method
Holds
Read Oct 3
The user-facing component is SmartHopperMcpServerComponent in src/SmartHopper.Components/Mcp/.
SmartHopperMcpServerComponent is in SmartHopper.Components.Mcp
Holds
Read Oct 3
Field inputSchema, Source AITool.ParametersSchema, Purpose JSON schema for tool arguments
AITool has a ParametersSchema field
Holds
Read Oct 3
Field outputSchema, Source AITool.OutputSchema, Purpose JSON schema describing the tool's result payload
AITool has an OutputSchema field
Holds
Read Oct 3
Field tags, Source AITool.Tags, Purpose Category and behavior tags (e.g., canvas , scripting , read-only , mutating )
AITool has a Tags field
Holds
Read Oct 3
Field annotations, Source AITool.Annotations, Purpose MCP hints readOnlyHint , destructiveHint , openWorldHint , idempotentHint , title
AITool has an Annotations field
Holds
Read Oct 3
AIToolMcpAdapter checks the tool exists, then AITool.Enabled, then EnabledTools, then ExposeMutatingTools/AITool.MutatesCanvas and AllowViewControl/AITool.Category.
AIToolMcpAdapter depends on AITool
Holds
Read Oct 3
AIToolMcpAdapter builds an AIToolCall and invokes it through the configured executor (AIToolCall.Exec() by default).
AIToolMcpAdapter depends on AIToolCall
Holds
Read Oct 3
AIToolMcpAdapter builds an AIToolCall and invokes it through the configured executor (AIToolCall.Exec() by default).
AIToolCall has an Exec method
Holds
Read Oct 3
The adapter extracts the last AIInteractionToolResult from AIReturn.Body and returns it as the MCP response payload;
AIReturn has Body
Holds
Read Oct 3
McpServerOptions.BypassMutationsApproval (component input Bypass Edition Validation) flows into MutationInvocationContext.BypassMutationsApproval when the adapter builds the call.
McpServerOptions has BypassMutationsApproval
Holds
Read Oct 3
McpServerOptions.BypassMutationsApproval (component input Bypass Edition Validation) flows into MutationInvocationContext.BypassMutationsApproval when the adapter builds the call.
MutationInvocationContext has BypassMutationsApproval
Holds
Read Oct 3
ConsentGate.RequestAsync short-circuits before presenter resolution when Surface == AIToolSurface.Mcp and the flag is set, returning Approved with every proposal item key — the review dialog is never invoked and undo recording is unaffected.
ConsentGate has RequestAsync
Holds
Read Oct 3
ConsentGate.RequestAsync short-circuits before presenter resolution when Surface == AIToolSurface.Mcp and the flag is set, returning Approved with every proposal item key — the review dialog is never invoked and undo recording is unaffected.
AIToolSurface has Mcp
Holds
Read Oct 3
When argument validation fails (SHRuntimeMessageOrigin.Validation), the MCP error payload includes only the called tool's expectedSchema plus the error message — the full tool catalog is never echoed inside an error response.
SHRuntimeMessageOrigin has Validation
Holds
Read Oct 3
WebChatUtils.CreateWebChatRequest prepends the internal assistant-core document to every WebChat system prompt before caller/user specialization.
WebChatUtils has CreateWebChatRequest
Holds
Read Oct 3
Release(object key, int port) stops it when the last holder leaves.
McpServerLifecycle has a Release method
Holds
Read Oct 3
Find(int port) returns the currently running instance, if any.
resolved at use-time through ProviderManager.GetDefaultAIProvider().
ProviderManager has a GetDefaultAIProvider method
Holds
Read Oct 2
**Provider change is a real input change.** InputsChanged() is overridden to add "AIProvider" to the list whenever HasProviderChanged() is true, so the state machine treats it like any other input change.
AIProviderComponentBase has an InputsChanged method
Holds
Read Oct 2
**Custom attributes.** CreateAttributes() installs AIProviderComponentAttributes, which renders the provider logo and the small status badge.
AIProviderComponentBase has a CreateAttributes method
Holds
Read Oct 2
string SelectedProviderName — the literal stored value (may be "Default").
AIProviderComponentBase has SelectedProviderName
Holds
Read Oct 2
string GetActualAIProviderName() — resolves "Default" through ProviderManager.
AIProviderComponentBase has a GetActualAIProviderName method
Holds
Read Oct 2
AIProvider GetActualAIProvider() — the concrete provider instance, or null.
AIProviderComponentBase has a GetActualAIProvider method
Holds
Read Oct 2
void SetSelectedProviderName(string name).
AIProviderComponentBase has a SetSelectedProviderName method
Holds
Read Oct 2
ProcessingUnit<T> (internal struct in DataTreeProcessor)
ProcessingUnit is a value type
Holds
Read Oct 2
GH_Path InputPath – original branch path.
ProcessingUnit has InputPath
Holds
Read Oct 2
int? ItemIndex – index within the branch for item mode;
ProcessingUnit has ItemIndex
Holds
Read Oct 2
IReadOnlyList<GH_Path> TargetPaths – one or more output paths mapped from this input path.
ProcessingUnit has TargetPaths
Holds
Read Oct 2
Workers/components choose a topology through ProcessingOptions.Topology, and the runner derives the appropriate schedule internally.
ProcessingOptions has Topology
Holds
Read Oct 2
**AIChatComponent** (AIStatefulAsyncComponentBase) — schema not applicable.
ProviderComponentBase has an OnProviderChanged method
Holds
Read Oct 2
**Tooltip template.** Sets AIProviderComponentAttributes.ProviderTooltipTemplate = "Settings for %provider%" so the badge tooltip reflects the menu's intent.
AIProviderComponentAttributes has ProviderTooltipTemplate
ProviderComponentBase has a GetActualAIProvider method
Holds
Read Oct 2
File2AIComponent and Web2AIComponent inherit from AIStatefulAsyncComponentBase so they can perform AI-powered image descriptions through the batch system.
File2AIComponent and Web2AIComponent inherit from AIStatefulAsyncComponentBase so they can perform AI-powered image descriptions through the batch system.
Component Class Text2AIComponent, Nickname Text2AI, Category Text, Description Wraps text input into an AIInputPayload
Text2AIComponent depends on AIInputPayload
Holds
Read Oct 2
Component Class Json2AIComponent, Nickname Json2AI, Category JSON, Description Wraps JSON data into an AIInputPayload
Json2AIComponent depends on AIInputPayload
Holds
Read Oct 2
StatefulComponentBase.Write(GH_IWriter) writes current output trees using GHPersistenceService.WriteOutputsV2(). StatefulComponentBase.Read(GH_IReader) reads output trees using GHPersistenceService.ReadOutputsV2() and restores them to the component's outputs.
StatefulComponentBase depends on GHPersistenceService
All output components inherit from AIOutputAdapterBase:
AI2ImgComponent extends AIOutputAdapterBase
Holds
Read Oct 2
All output components inherit from AIOutputAdapterBase:
AI2JsonComponent extends AIOutputAdapterBase
Holds
Read Oct 2
All output components inherit from AIOutputAdapterBase:
AI2GhJsonComponent extends AIOutputAdapterBase
Holds
Read Oct 2
All output components inherit from AIOutputAdapterBase:
AI2ScriptComponent extends AIOutputAdapterBase
Holds
Read Oct 2
All output components inherit from AIOutputAdapterBase:
AI2SpeechComponent extends AIOutputAdapterBase
Holds
Read Oct 2
**Fluent builder** for constructing and mutating AIBody instances
AIBodyBuilder depends on AIBody
Holds
Read Oct 2
Create() — static factory for a new empty builder
AIBodyBuilder has a Create method
Holds
Read Oct 2
FromImmutable(AIBody body) — copy constructor from an existing body;
AIBodyBuilder has a FromImmutable method
Holds
Read Oct 2
WithToolFilter(string filter) — set the tool filter expression (e.g., -* = disable all, +gh_* = enable Grasshopper tools)
AIBodyBuilder has a WithToolFilter method
Holds
Read Oct 2
WithContextFilter(string filter) — set the context filter expression for provider injection
AIBodyBuilder has a WithContextFilter method
Holds
Read Oct 2
WithJsonOutputSchema(string jsonSchema) — set the JSON Schema to instruct providers to produce structured output
AIBodyBuilder has a WithJsonOutputSchema method
Holds
Read Oct 2
WithTurnId(string turnId) — set the default TurnId applied to interactions lacking one;
AIBodyBuilder has a WithTurnId method
Holds
Read Oct 2
WithDefaultNewness(bool markAsNew) — set the default newness flag for subsequent Add/Replace operations
AIBodyBuilder has a WithDefaultNewness method
Holds
Read Oct 2
AsHistory() — convenience method;
AIBodyBuilder has an AsHistory method
Holds
Read Oct 2
AsNew() — convenience method;
AIBodyBuilder has an AsNew method
Holds
Read Oct 2
Build() — produce the immutable AIBody record with all accumulated interactions and settings
AIBodyBuilder has a Build method
Holds
Read Oct 2
SessionId (string, nullable) — filter by session
MetricsFilter has SessionId
Holds
Read Oct 2
RequestId (string, nullable) — filter by request
MetricsFilter has RequestId
Holds
Read Oct 2
ToolInvocationId (string, nullable) — filter by tool invocation
MetricsFilter has ToolInvocationId
Holds
Read Oct 2
EventType (AIMetricsEventType, nullable) — filter by event type
MetricsFilter has EventType
Holds
Read Oct 2
Timestamp (DateTimeOffset) — when the event occurred
AIMetricsEvent has Timestamp
Holds
Read Oct 2
EventType (AIMetricsEventType) — type of event
AIMetricsEvent has EventType
Holds
Read Oct 2
Correlation (MetricsCorrelation) — correlation keys for tracing
AIMetricsEvent has Correlation
Holds
Read Oct 2
Payload (object) — event-specific data (one of the metric records below)
AIMetricsEvent has Payload
Holds
Read Oct 2
filter with AIBody.ToolFilter to avoid unintended tool loading;
AIBody has ToolFilter
Holds
Read Oct 3
The ConversationSession type is the primary orchestrator for multi-turn AI conversations, including automatic tool execution and streaming support. It wraps AIRequestCall.Exec() into a higher-level loop that handles turn limits, tool passes, and observer notifications.
ConversationSession depends on AIRequestCall
Holds
Read Oct 3
It wraps AIRequestCall.Exec() into a higher-level loop that handles turn limits, tool passes, and observer notifications.
AIRequestCall has an Exec method
Holds
Read Oct 3
ConversationSession.Stream(...) gates streaming using request validation rules.
ConversationSession has a Stream method
Holds
Read Oct 3
Both RunToStableResult(...) and Stream(...) delegate to the same internal turn loop;
ConversationSession has a RunToStableResult method
Holds
Read Oct 3
Both public APIs now delegate to the same internal loop TurnLoopAsync(...) for consistent behavior.
ConversationSession has a TurnLoopAsync method
Holds
Read Oct 3
**Automatic greeting**: when the session is constructed with generateGreeting: true, the first RunToStableResult/Stream call is intercepted before validation and routed to GenerateGreetingAsync, which executes the built-in GreetingSpecialTurn (dedicated greeting prompt, provider's default Text2Text model, all tools disabled via OverrideToolFilter = "-*", 30 s timeout, PersistResult).
ConversationSession has GenerateGreetingAsync
Holds
Read Oct 3
The one-shot flag is cleared after emitting, so callers (e.g., WebChatDialog.InitializeNewConversationAsync) trigger the greeting simply by starting a run — they must not invoke it again.
WebChatDialog has InitializeNewConversationAsync
Holds
Read Oct 3
Every provider turn allocates one turnId, and all interactions produced during that turn (text, tool calls, tool results, streaming deltas) are stamped with it via InteractionUtility.EnsureTurnId, which **overwrites** any value already present.
InteractionUtility has EnsureTurnId
Holds
Read Oct 3
This is required because provider results are built through AIReturn.SetBody(...) → AIBodyBuilder.Build(), which assigns a random TurnId to every interaction lacking one; treating that value as authoritative would put each delta in its own turn (observers key UI messages by TurnId, so this manifests as one bubble per streaming chunk).
AIReturn has a SetBody method
Holds
Read Oct 3
This is required because provider results are built through AIReturn.SetBody(...) → AIBodyBuilder.Build(), which assigns a random TurnId to every interaction lacking one; treating that value as authoritative would put each delta in its own turn (observers key UI messages by TurnId, so this manifests as one bubble per streaming chunk).
AIBodyBuilder has a Build method
Holds
Read Oct 3
Each run maintains a usage ledger (_runTokensEffective) that meters every completed provider call exactly once at two choke points — ExecProviderAsync (non-streaming) and ProcessStreamingDeltasAsync (streaming, taking the last delta that carries metrics).
ConversationSession has ExecProviderAsync
Holds
Read Oct 3
Each run maintains a usage ledger (_runTokensEffective) that meters every completed provider call exactly once at two choke points — ExecProviderAsync (non-streaming) and ProcessStreamingDeltasAsync (streaming, taking the last delta that carries metrics).
ConversationSession has ProcessStreamingDeltasAsync
Holds
Read Oct 3
Consumption uses effective tokens (max(actual, estimated) via AIMetrics.EffectiveTotalTokens).
AIMetrics has EffectiveTotalTokens
Holds
Read Oct 2
Fields: Id, Name, Arguments (JObject)
AIInteractionToolCall has an Id field
Holds
Read Oct 2
Fields: Id, Name, Arguments (JObject)
AIInteractionToolCall has a Name field
Holds
Read Oct 2
Fields: Id, Name, Arguments (JObject)
AIInteractionToolCall has an Arguments field
Holds
Read Oct 2
Methods: ToString() pretty prints name, id and JSON args
Response policies run after the provider call to decode raw JSON, standardize fields, and attach diagnostics via AIReturn.AddRuntimeMessage(...).
AIReturn has an AddRuntimeMessage method
Holds
Read Oct 2
Policy SchemaAttachRequestPolicy, File Request/SchemaAttachRequestPolicy.cs, Trigger Request, Description Attaches JSON output schema to the request when AIBody.JsonOutputSchema is set Passes schema to provider encoding layer for structured output inference
AIBody has JsonOutputSchema
Holds
Read Oct 2
Policy SchemaValidateResponsePolicy, File Response/SchemaValidateResponsePolicy.cs, Trigger Response, Description Validates the response against the requested JSON schema (if set) Uses JsonSchemaResponseValidator to check structure Emits validation errors as structured messages via AddRuntimeMessage()
SchemaValidateResponsePolicy depends on JsonSchemaResponseValidator
Holds
Read Oct 2
These types stay host-side in SmartHopper.Infrastructure and the rest of the application: ProviderManager, ProviderHashVerifier, ProviderClassifier, trust dialogs, signature/hash policy, SmartHopperSettings persistence, secret storage.
ProviderManager is in SmartHopper.Infrastructure
Holds
Read Oct 2
These types stay host-side in SmartHopper.Infrastructure and the rest of the application: ProviderManager, ProviderHashVerifier, ProviderClassifier, trust dialogs, signature/hash policy, SmartHopperSettings persistence, secret storage.
ProviderHashVerifier is in SmartHopper.Infrastructure
Holds
Read Oct 2
These types stay host-side in SmartHopper.Infrastructure and the rest of the application: ProviderManager, ProviderHashVerifier, ProviderClassifier, trust dialogs, signature/hash policy, SmartHopperSettings persistence, secret storage.
ProviderClassifier is in SmartHopper.Infrastructure
Holds
Read Oct 2
These types stay host-side in SmartHopper.Infrastructure and the rest of the application: ProviderManager, ProviderHashVerifier, ProviderClassifier, trust dialogs, signature/hash policy, SmartHopperSettings persistence, secret storage.
SmartHopperSettings is in SmartHopper.Infrastructure
AIProvider.Call wrapped by RetryPolicy and RedactionPolicy to ensure no sensitive data.
AIProvider has Call
Holds
Read Oct 3
CanvasButton and AIChatComponent open/reuse the dialog via WebChatUtils.
AIChatComponent depends on WebChatUtils
Holds
Read Oct 3
Supported via HtmlChatRenderer.RenderInteraction(...) and CSS classes:
HtmlChatRenderer has a RenderInteraction method
Holds
Read Oct 3
During streaming, assistant token deltas are surfaced via IConversationObserver.OnDelta(...) and aggregated under a constant stream key computed via GetStreamKey();
IConversationObserver has an OnDelta method
Holds
Read Oct 2
Static utility applied by FileConverterRegistry.ConvertAsync to every successful conversion result, regardless of format
FileConverterRegistry depends on MarkdownListRenumberer
Holds
Read Oct 2
Static utility applied by FileConverterRegistry.ConvertAsync after MarkdownListRenumberer, to every successful conversion result
FileConverterRegistry depends on MarkdownStyleCleanup
Holds
Read Oct 2
All converters implement IFileConverter and are registered in FileConverterRegistry:
PdfConverter implements IFileConverter
Holds
Read Oct 2
All converters implement IFileConverter and are registered in FileConverterRegistry:
DocxConverter implements IFileConverter
Holds
Read Oct 2
All converters implement IFileConverter and are registered in FileConverterRegistry:
XlsxConverter implements IFileConverter
Holds
Read Oct 2
All converters implement IFileConverter and are registered in FileConverterRegistry:
PptxConverter implements IFileConverter
Holds
Read Oct 2
All converters implement IFileConverter and are registered in FileConverterRegistry:
HtmlConverter implements IFileConverter
Holds
Read Oct 2
All converters implement IFileConverter and are registered in FileConverterRegistry:
EmlConverter implements IFileConverter
Holds
Read Oct 2
All converters implement IFileConverter and are registered in FileConverterRegistry:
EpubConverter implements IFileConverter
Holds
Read Oct 2
All converters implement IFileConverter and are registered in FileConverterRegistry:
RtfConverter implements IFileConverter
Holds
Read Oct 2
All converters implement IFileConverter and are registered in FileConverterRegistry:
CsvConverter implements IFileConverter
Holds
Read Oct 2
All converters implement IFileConverter and are registered in FileConverterRegistry:
JsonConverter implements IFileConverter
Holds
Read Oct 2
All converters implement IFileConverter and are registered in FileConverterRegistry:
XmlConverter implements IFileConverter
Holds
Read Oct 2
All converters implement IFileConverter and are registered in FileConverterRegistry:
TxtConverter implements IFileConverter
Holds
Read Oct 2
All converters implement IFileConverter and are registered in FileConverterRegistry:
Converter EmlConverter, File EmlConverter.cs, Extensions .eml, Library MimeKit, Features From/To/Subject/Date, HTML or plain text body, attachment list
EmlConverter imports MimeKit
Holds
Read Oct 2
Converter UrlConverter, File UrlConverter.cs, Extensions (HTTP/HTTPS URLs), Library HtmlAgilityPack, Features Fetches and converts web pages
UrlConverter imports HtmlAgilityPack
Holds
Read Oct 2
FileConversionOptions carries behavior flags (table preservation, header/footer removal, image extraction, hyperlinks, footnotes/endnotes, math, inline formatting) to every converter
PdfConverter depends on FileConversionOptions
Holds
Read Oct 2
FileConversionOptions carries behavior flags (table preservation, header/footer removal, image extraction, hyperlinks, footnotes/endnotes, math, inline formatting) to every converter
DocxConverter depends on FileConversionOptions
Holds
Read Oct 2
FileConversionOptions carries behavior flags (table preservation, header/footer removal, image extraction, hyperlinks, footnotes/endnotes, math, inline formatting) to every converter
XlsxConverter depends on FileConversionOptions
Holds
Read Oct 2
FileConversionOptions carries behavior flags (table preservation, header/footer removal, image extraction, hyperlinks, footnotes/endnotes, math, inline formatting) to every converter
PptxConverter depends on FileConversionOptions
Holds
Read Oct 2
FileConversionOptions carries behavior flags (table preservation, header/footer removal, image extraction, hyperlinks, footnotes/endnotes, math, inline formatting) to every converter
HtmlConverter depends on FileConversionOptions
Holds
Read Oct 2
FileConversionOptions carries behavior flags (table preservation, header/footer removal, image extraction, hyperlinks, footnotes/endnotes, math, inline formatting) to every converter
EmlConverter depends on FileConversionOptions
Holds
Read Oct 2
FileConversionOptions carries behavior flags (table preservation, header/footer removal, image extraction, hyperlinks, footnotes/endnotes, math, inline formatting) to every converter
EpubConverter depends on FileConversionOptions
Holds
Read Oct 2
FileConversionOptions carries behavior flags (table preservation, header/footer removal, image extraction, hyperlinks, footnotes/endnotes, math, inline formatting) to every converter
RtfConverter depends on FileConversionOptions
Holds
Read Oct 2
FileConversionOptions carries behavior flags (table preservation, header/footer removal, image extraction, hyperlinks, footnotes/endnotes, math, inline formatting) to every converter
CsvConverter depends on FileConversionOptions
Holds
Read Oct 2
FileConversionOptions carries behavior flags (table preservation, header/footer removal, image extraction, hyperlinks, footnotes/endnotes, math, inline formatting) to every converter
JsonConverter depends on FileConversionOptions
Holds
Read Oct 2
FileConversionOptions carries behavior flags (table preservation, header/footer removal, image extraction, hyperlinks, footnotes/endnotes, math, inline formatting) to every converter
XmlConverter depends on FileConversionOptions
Holds
Read Oct 2
FileConversionOptions carries behavior flags (table preservation, header/footer removal, image extraction, hyperlinks, footnotes/endnotes, math, inline formatting) to every converter
TxtConverter depends on FileConversionOptions
Holds
Read Oct 2
FileConversionOptions carries behavior flags (table preservation, header/footer removal, image extraction, hyperlinks, footnotes/endnotes, math, inline formatting) to every converter
See these where the change is. The browser extension puts a pull request's doc findings, and a diagram of what it changed, on the GitHub page itself, so the code and what your docs say about it are side by side.