Conversation
…TurnId propagation - Fixed chat UI to display total token consumption per turn (from user message to next user message) instead of just the last message's metrics - Added `GetTurnMetrics(turnId)` method to `ConversationSession` to aggregate metrics from all interactions in a turn (assistant messages, tool calls, and tool results) - Fixed tool results not inheriting TurnId from their corresponding tool calls in `ToolManager.ExecuteTool`
… to reduce token consumption Added a convenience wrapper tool that combines script_edit and gh_put in a single call: - Created script_edit_and_replace_on_canvas tool that internally executes script_edit followed by gh_put with editMode=true - Changed script_edit category from "Scripting" to "Hidden" since the wrapper is now the preferred interface - Updated CanvasButton system prompt to document the new workflow using the wrapper tool
…cript_generate and script_edit Enhanced script_generate and script_edit tools to support all parameter modifiers for both inputs and outputs: - Added support for dataMapping (Flatten/Graft), reverse, simplify, invert, isPrincipal, required, and expression modifiers for input parameters - Added support for dataMapping, reverse, simplify, and invert modifiers for output parameters - Updated tool schemas to document all available
…Rhino focus and stays on top - Set WebChatDialog as an owned window of Rhino's main Eto window and hide it from the taskbar - Dialog now follows Rhino/Grasshopper focus and stays on top of Rhino while the application is active - Fixed issue where confirmation dialogs (e.g., from gh_put in edit mode) would leave the chat window hidden behind other windows after closing
…se instanceGuid and make parameter schemas more explicit - Changed script_edit_and_replace_on_canvas wrapper to accept instanceGuid instead of ghjson, automatically calling gh_get_by_guid internally before script_edit and gh_put - Made all optional parameter modifier fields required in JSON schemas for script_generate and script_edit to force explicit specification - Added guidance text to parameter descriptions
…nnecessary code blocks and external testing patterns - Added guidance that all scripting happens inside Grasshopper script components, not standalone environments - Instructed to avoid proposing unit tests or external test projects since validation happens directly in Grasshopper - Added instruction to tell users to double-click script components instead of pasting full scripts in chat - Discouraged copying full scripts into the conversation
- Replaced foreach loops with LINQ expressions (Where, Select, ToHashSet, etc.) across multiple files for more concise code - Added explicit assembly allowlist to Sign-Authenticode.ps1 to prevent signing unintended/malicious assemblies - Added validation to reject non-SmartHopper assemblies when signing explicit DLLs - Changed floating point comparison in script_edit.cs to use tolerance instead of direct equality check
…nd message-boxes to canvas linking (#354) # feat(script-tools): add GhJSON-based script tools, merge workflows, and dialog-canvas linking ## Description This PR prepares the 1.2.0 “script tools” feature set, focusing on GhJSON‑based scripting workflows, GhJSON merge utilities, and improved in-canvas UX: - **GhJSON-based script tools** - Introduce `script_generate` and `script_edit` AI tools that operate purely on GhJSON for Grasshopper script components. - All script tools now validate GhJSON via `GHJsonAnalyzer.Validate` and use `ScriptComponentFactory` for component construction. - Add `script_edit_and_replace_on_canvas` wrapper tool that chains `script_edit` and `gh_put` in one call, reducing token usage and simplifying AI-driven script editing. - Extend script tools to support the full set of parameter modifiers: - Inputs: `dataMapping` (Flatten/Graft), `reverse`, `simplify`, `invert`, `isPrincipal`, `required`, `expression` - Outputs: `dataMapping`, `reverse`, `simplify`, `invert` - **GhJSON helpers and merge workflows** - Add `GhJsonHelpers` utility to apply pivots and restore `InstanceGuid`s on deserialized components. - Introduce `GhJsonMerger` to merge two GhJSON `GrasshopperDocument` instances with: - Target‑document priority on GUID conflicts - Automatic ID remapping for connections and groups - Add `gh_merge` AI tool and `GhMergeComponents` Grasshopper component for merging GhJSON documents, exposing merged GhJSON and basic merge statistics. - **Component replacement mode and canvas-linked messabe boxes** - Extend `GhPutComponents` with an “Edit Mode” input to support component replacement based on existing `InstanceGuid`s. - Update `gh_put` to accept an `editMode` parameter, preserving original `InstanceGuid` and exact canvas positions when replacing components, with undo support. - Add `DialogCanvasLink` utility and extend `StyledMessageDialog` APIs with optional `linkedInstanceGuid` and `linkLineColor` so dialogs can visually link to Grasshopper components via a bezier line and anchor dot on the canvas. - **`gh_get` improvements** - Add `categoryFilter` support to `gh_get`, extending category-based filtering from components to all document objects. - **Component and UI updates** - Update AI‑selecting stateful components to use combined attributes: “Select” button above provider badges, with connector line and hover highlights that match the dialog link color. - Improve default SmartHopper assistant prompt used by `CanvasButton` to guide users toward in‑viewport scripting workflows and avoid unnecessary external code blocks or testing patterns. - Refresh component icons (McNeel forum, script, new `ghmerge`, updated `ghget` / `ghput`) for better visual consistency. - **Provider and metrics improvements** - Register new Claude Opus 4.5 model in the Anthropic provider registry. - Enhance OpenRouter provider with structured output via `response_format: json_schema` / `structured_outputs` and improved metrics (`finish_reason`, `model`). - Fix chat UI metrics to aggregate per turn (from user message to next user message) using `ConversationSession.GetTurnMetrics`, and ensure tool results inherit the correct `TurnId`. - **Stability and UX fixes** - Fix `gh_put` infinite loop and “object expired during solution” errors when using replacement mode by removing problematic document enable/disable logic and relying on `IsolateObject()` during cleanup. - Ensure `WebChatDialog` is an owned Rhino tool window (no taskbar entry, stays with Rhino/Grasshopper focus) and plays nicely with confirmation dialogs. - Require all properties in `script_generate` and `script_edit` schemas to avoid OpenAI structured-output crashes. ## Breaking Changes - Files that had previous versions of the `Get Components` or `Place Components` components might have to replace them with the new ones. - All new behaviors (GhJSON merge, component replacement mode, script edit‑and‑replace tooling, dialog-canvas linking) are opt‑in and preserve existing workflows by default. ## Testing Done - [x] Manual: Generate new C# and Python script components via `AIScriptGeneratorComponent` using `script_generate` and validate GhJSON round‑trip with `gh_put`. - [x] Manual: Edit an existing script component via `AIScriptGeneratorComponent` + `script_edit_and_replace_on_canvas` and confirm the component is replaced in place with preserved position and stable behavior. - [x] Manual: Use `GhMergeComponents` (and `gh_merge`) to merge two GhJSON documents and verify: - Components, connections, and groups are merged as expected - Merge statistics match the visual result - [x] Manual: Enable `GhPutComponents` Edit Mode to replace existing components and confirm: - Prompt behavior via `StyledMessageDialog` is correct - Undo restores the previous state - [x] Manual: Open message boxes linked to canvas components (e.g., `GhPutComponents` confirmations) and visually verify dialog-canvas link lines and hover behavior. - [x] Manual: Verify `gh_get` with `categoryFilter` returns only the expected objects. - [x] Manual: Confirm chat UI shows aggregated per‑turn metrics and that tool calls/results appear under the same turn. - [x] Automated: Run the solution build and existing test suites (including `SmartHopper.Core.Grasshopper.Tests`) and ensure they pass. ## Checklist - [x] This PR is focused on a single feature or bug fix - [x] Version in Solution.props was updated, if necessary, and follows semantic versioning - [x] CHANGELOG.md has been updated - [x] PR title follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.1.0/) format - [x] PR description follows [Pull Request Description Template](https://github.com/architects-toolkit/SmartHopper/blob/main/CONTRIBUTING.md#pull-request-description-template)
…rrection for non-RhinoCommon geometry libraries - Added `ScriptCodeValidator` utility to detect non-RhinoCommon geometry libraries in AI-generated scripts (System.Numerics, UnityEngine, numpy, shapely, scipy, trimesh, open3d, pyvista, MathNet.Numerics, custom Vector3 classes) - Enhanced `script_generate` and `script_edit` system prompts with explicit RhinoCommon geometry requirements and comprehensive language-specific guidance
…nd centralize language normalization - Added language-specific Grasshopper scripting guidance to `script_review` system prompt via `ScriptCodeValidator.GetLanguageGuidance`, based on detected script language - Added C# script shape guidance to `ScriptCodeValidator` explaining that Grasshopper C# components wrap code inside a class/method and should not include namespaces, classes, methods, or access modifiers at the top level
…couraged for specific AI tools - Added "Not Recommended" badge (orange octagon with exclamation mark) displayed when the selected model is discouraged for the AI tools used by a component - Added `DiscouragedForTools` property to `AIModelCapabilities` to specify tool names for which a model is not recommended - Added `UsingAiTools` property to `AIStatefulAsyncComponentBase` allowing components to declare which AI tools they use
… discouragement for Anthropic Haiku and MistralAI Small models - Marked multiple older model versions as deprecated across OpenAI, Anthropic, and MistralAI providers - Added `DiscouragedForTools` for `script_generate` and `script_edit` to all Anthropic Haiku variants (claude-haiku-4-5, claude-3-5-haiku, claude-3-haiku) and MistralAI Small models (mistral-small-latest, mistral-small) - Verified claude-sonnet-4-5
…and add missing ImageInput/FunctionCalling capabilities
…ves and consolidate output parameter guidance - Added validation in `ScriptCodeValidator` to detect and reject `#!` shebang/language headers in non-Python scripts (e.g., `#! c#`, `#! vb`) - Updated language guidance to clarify that `#!` directives are Python-only and must never appear in C#, VB.NET, or other non-Python scripts - Moved output parameter collection guidance from `script_generate` and `script_edit` system prompts to centrized ScriptCodeValidator
…g, and mark Anthropic Haiku models as verified - Removed "Grasshopper" prefix from component names in roadmap table for brevity - Added backtick code formatting to all AI tool names in tools table - Split `script_generator` tool into separate `script_generate` and `script_edit` entries to reflect actual implementation - Added new MistralAI models (mistral-medium, mistral-large-latest, magistral-medium-latest) and OpenAI gpt-5.
…l development setup and update strong-name key - Added step 4 to run Update-InternalsVisibleTo.ps1 after generating or changing signing.snk - Renumbered subsequent setup steps (5-7) and updated note to include step 4 - Added optional SnkPath parameter to Sign-StrongNames.ps1 with default fallback to signing.snk - Updated SmartHopperPublicKey in SmartHopper.Infrastructure.csproj to match new strong-name key
…adge system and capability-aware selection details - Added capability-aware model selection and fallback logic to Architecture.md, explaining how `ModelManager.SelectBestModel` uses `Verified`/`Deprecated`/`Rank` metadata - Documented `AICall` policy pipeline, conversation sessions, and per-turn metrics aggregation in concurrency section - Expanded AIStatefulAsyncComponentBase.md to describe `RequiredCapability` and `UsingAiTools`
…/architects-toolkit/SmartHopper into feat/1.2.0-scripting-improvments
…fied Build-Solution.ps1 - Moved Sign-Authenticode.ps1 and Sign-StrongNames.ps1 from solution root to tools/ directory - Updated all script references in GitHub Actions workflows, tests, and documentation to use tools/ path - Added Build-Solution.ps1 helper script to automate signing setup, InternalsVisibleTo updates, solution build, and Authenticode signing - Changed Sign-Authenticode.ps1 -Password parameter from string to SecureString
…ng.pfx with fallback to tools/ directory - Changed Sign-Authenticode.ps1 and Sign-StrongNames.ps1 to default to ..\signing.pfx and ..\signing.snk (solution root) instead of tools/ directory - Added fallback logic to check tools/signing.pfx and tools/signing.snk when solution root files are not found and no explicit path is provided - Enhanced Sign-Authenticode.ps1 -Sign to default to bin/<SolutionVersion>/Debug when no target path is specified,
… branch preparation
…atures, and add script generator video
…umentation, and style fixes - Removed using-directives-check job from pr-validation.yml workflow - Removed "Using Directives Check" from validation lists in HOTFIX_WORKFLOW.md and RELEASE_WORKFLOW.md - Fixed trailing whitespace in AIModelCapabilities.md documentation
…d test assembly signing support - Changed Sign-Authenticode.ps1 -Password parameter from string to SecureString in dotnet-build action - Added validation to ensure signing_pfx_password is provided when signing_pfx_base64 is set - Added conditional logic to skip PFX decoding when no Base64 secret is provided - Updated ProviderManagerSignatureTests to use -Command with ConvertTo-SecureString expressions instead of -File for password handling
…code signing process
…t and restrict macOS tests to Infrastructure.Tests only - Write base64-encoded PFX to temp file instead of passing as CLI argument to avoid parsing issues with long/special-character strings - Trim PFX password before passing to Sign-Authenticode.ps1 to prevent whitespace-related failures - Update macOS test execution to run only SmartHopper.Infrastructure.Tests (net7.0) since Core.Tests and Core.Grasshopper.Tests depend on Windows
… Authenticode signing process - Pass base64-encoded PFX directly to Sign-Authenticode.ps1 instead of writing to temp file - Remove -File parameter from Sign-Authenticode.ps1 (no longer needed) - Remove verbose password validation and debug logging from signing script - Clean up conditional formatting in target path resolution
…read-safe provider tracking and fix version script base version handling - Replace HashSet<string> with ConcurrentDictionary<string, bool> for _mismatchedProviders, _unavailableProviders, and _unknownProviders to ensure thread-safe access - Update provider tracking to use dictionary indexer instead of Add() method - Update integrity check queries to use ContainsKey() instead of Contains()
…mprove password handling warnings - Add comprehensive security documentation for Sign-Authenticode.ps1 covering dual-mode password handling, CI/CD vs interactive use, and security best practices - Add security warnings to -Password parameter help text about plain-text exposure risks - Implement context-aware security warnings that only display in interactive sessions (suppressed in CI/CD environments)
…S compatibility (#397) ## Description This PR implements significant improvements to provider security verification and cross-platform compatibility, particularly for macOS. The changes include: **Provider Security & Verification:** - Enhanced SHA-256 hash verification covering Windows and macOS with dual-runner CI hashes - New three-tier mode (Soft/Hard/Strict) for different Integrity Check modes selectable in Providers settings - Added DEBUG auto-switch to Soft Check for smoother local development - Implemented 15-minute manifest caching with thread-safe operations using ConcurrentDictionary - Reduced verification timeout from 10s to 5s for faster offline detection - Added network availability checks to skip hash fetch attempts when offline **macOS Compatibility & Stability:** - Fixed race condition in ComponentStateManager.ProcessTransitionQueue() to prevent concurrent queue processing - Enhanced error handling for non-JSON API responses (e.g., HTML error pages from proxies) - Improved GhJSON validation and JSON parsing edge cases - Addressed multiple stability and compatibility issues tracked in #389, #393, and #395 **UX & Component Improvements:** - Renamed AIScriptGenerator component to AIScriptGenerate for consistent naming - Tuned dialog sizing, text wrapping, and integrity-check descriptions - Added comprehensive integrity check failure documentation **Tooling & Automation:** - Enhanced Change-SolutionVersion.ps1 with explicit version parsing and help output - Expanded .gitignore to exclude all local libraries beyond Rhino - Improved pre-commit hook with selective staging and safer password handling - Added post-commit hook to auto-update InternalsVisibleTo - Added automated GitHub workflow for contributors maintenance ## Breaking Changes - Saved files with the AIScriptGenerator component will have to replace them with the new AIScriptGenerate - I could not test on macOS ## Testing Done - Tested three-tier verification mode switching in Settings dialog - Tested UI improvements ## Checklist - [x] This PR is focused on multiple related improvements in provider security and compatibility - [x] Version in Solution.props was updated appropriately - [x] CHANGELOG.md has been updated with comprehensive details - [x] PR title follows Conventional Commits format - [x] PR description follows Pull Request Description Template
This PR updates the contributors section in CHANGELOG.md under [Unreleased] to acknowledge new contributors since the last release. This is an automated PR created by the Update Contributors workflow.
…ion, and smart sorting - Add commit count tracking per contributor in release notes - Implement deduplication logic to prevent duplicate GitHub usernames - Add bot account filtering (github-actions, actions-user) - Improve first-time contributor detection by checking historical commits with name matching - Sort contributors by: first-time status (first), commit count (descending), then alphabetically - Update contributor data format
… fixes (#399) This PR prepares the release for version 1.4.1-alpha with version update and code style fixes: - Updated version in Solution.props - Updated changelog with closed-solved issues - Updated README badges
…e exit code handling in anonymization workflow - Add explicit bash shell directive to identify-contributors step to ensure consistent shell behavior across runners - Improve exit code handling in anonymization workflow by capturing LASTEXITCODE to variable and handling null/undefined cases before evaluation
…d fix sorting logic - Add check to skip contributor updates when [Unreleased] section is empty (dev->main merge scenario) - Fix sorting logic by wrapping it in else block to only execute when contributors are found - Count non-empty lines in [Unreleased] section to detect effectively empty sections
…ix contributor history detection - Skip date updates for non-dev versions in Change-SolutionVersion.ps1 script - Fix git range syntax in contributors workflow to correctly identify historical contributors (use "$LAST_TAG" instead of "..$LAST_TAG") - Improve change detection in version-date workflow by checking git status before staging files - Update commit message comments to clarify contributor history detection logic
…n workflows
- Fix commit count increment syntax in contributors workflow to handle uninitialized array elements properly (use `${COMMIT_COUNTS["$email"]:-0}` instead of `++` operator)
- Add explicit ref specification to checkout action in version-date workflow to ensure correct branch is checked out
marc-romu
approved these changes
Mar 9, 2026
…nd standardizing environment variable usage - Fix SIGPIPE (exit 141) errors in contributors workflow by redirecting grep output to /dev/null instead of using -q flag - Standardize environment variable usage in version-date workflow by using GITHUB_ENV instead of GITHUB_OUTPUT for branch names - Update all references to use env context instead of steps.outputs for TARGET_BRANCH and DATE_BRANCH
…l-request action and improve grep reliability - Replace manual git branch creation and PR creation logic with peter-evans/create-pull-request action in version-badge and version-date workflows - Remove redundant branch deletion and PR cleanup steps (handled automatically by the action) - Simplify change detection by moving git status checks to dedicated steps - Fix SIGPIPE errors in contributors workflow by piping grep output through
… version-main-release workflow - Replace git log parsing with GitHub API for contributor identification to avoid email/name alias issues - Use GitHub login as canonical identity for deduplication instead of name/email combinations - Add efficient first-time contributor detection using GitHub API with until parameter - Improve bot detection to handle [bot] suffix pattern - Simplify sorting logic by removing intermediate file operations
This PR removes the date suffix from the version in Solution.props to prepare for a main release. This is an automated PR created by the Remove Release Version Date workflow.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SmartHopper 1.4.1-alpha: Provider Security, Stability, and macOS compatibility improvments [Patch]
This patch release enhances provider security with a flexible three-tier verification system, improves macOS compatibility, and fixes critical stability issues in component state management and GhJSON tooling.
Detailed list of changes:
Provider Security Enhancement: Replaced boolean "hard integrity check" with three selectable modes (Soft/Hard/Strict) in Providers settings with automatic migration for existing installations. SHA-256 hash verification now covers both Windows and macOS with dual-runner CI hashes and DEBUG auto-switch to Soft Check for smoother local development.
Component Stability: Fixed race condition in
ComponentStateManager.ProcessTransitionQueue()where theisTransitioningflag was cleared before event firing, potentially allowing concurrent queue processing on macOS and causing out-of-order event handling.GhJSON Tooling: Fixed
script_generateandscript_edittools by setting GhJSON componentId = 1whenInstanceGuidis null to satisfy GhJSON.Core validation, and addedSanitizeAndParseJsonto handle AI responses wrapped in markdown code blocks or non-JSON formatting.Provider Infrastructure: Improved
AIProvider.CallApi()error messages for non-JSON API responses (e.g., HTML error pages from proxies). Reduced provider hash verification timeout from 10s to 5s for faster offline detection and improved Settings dialog responsiveness. Added network availability check inProviderHashVerifierto skip hash fetch attempts when offline. Implemented 15-minute manifest caching with thread-safeConcurrentDictionary.Component Naming: Renamed
AIScriptGeneratorcomponent toAIScriptGeneratefor consistent AI script naming.Tooling & Automation: Enhanced
Change-SolutionVersion.ps1with explicit version parsing and help output. Expanded.gitignoreto exclude all local libraries. Improved pre-commit hook with selective staging and safer password handling. Added post-commit hook to auto-updateInternalsVisibleTo. Added GitHub workflow to anonymize the public key on protected branches.CI/CD Fixes: Skip
Update-InternalsVisibleTostep on macOS runners sincesn.exe(Strong Name tool) is Windows-only; assemblies still strong-name signed with SNK file.macOS Compatibility: Addressed deadlock risk, GhJSON validation issues, and JSON parsing edge cases tracked in #389.
Additional Stability: Fixed stability and compatibility issues tracked in #395 and #393.
Contributors Workflow: Added automated GitHub workflow (
chore-update-contributors.yml) to maintain the contributors section in CHANGELOG.md.