Skip to content

release/1.4.1-alpha#400

Merged
marc-romu merged 1996 commits into
mainfrom
dev
Mar 9, 2026
Merged

release/1.4.1-alpha#400
marc-romu merged 1996 commits into
mainfrom
dev

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented Mar 9, 2026

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 the isTransitioning flag was cleared before event firing, potentially allowing concurrent queue processing on macOS and causing out-of-order event handling.

  • GhJSON Tooling: Fixed script_generate and script_edit tools by setting GhJSON component Id = 1 when InstanceGuid is null to satisfy GhJSON.Core validation, and added SanitizeAndParseJson to 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 in ProviderHashVerifier to skip hash fetch attempts when offline. Implemented 15-minute manifest caching with thread-safe ConcurrentDictionary.

  • Component Naming: Renamed AIScriptGenerator component to AIScriptGenerate for consistent AI script naming.

  • Tooling & Automation: Enhanced Change-SolutionVersion.ps1 with explicit version parsing and help output. Expanded .gitignore to exclude all local libraries. Improved pre-commit hook with selective staging and safer password handling. Added post-commit hook to auto-update InternalsVisibleTo. Added GitHub workflow to anonymize the public key on protected branches.

  • CI/CD Fixes: Skip Update-InternalsVisibleTo step on macOS runners since sn.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.

…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`
…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,
…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
marc-romu and others added 13 commits March 9, 2026 11:33
…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
@github-actions github-actions Bot requested a review from marc-romu as a code owner March 9, 2026 14:24
…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
…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
@marc-romu marc-romu added this to the 1.4.1-alpha milestone Mar 9, 2026
… 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
@marc-romu marc-romu enabled auto-merge March 9, 2026 15:18
@marc-romu marc-romu disabled auto-merge March 9, 2026 15:18
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.
@marc-romu marc-romu enabled auto-merge March 9, 2026 15:21
@marc-romu marc-romu merged commit 7ab487f into main Mar 9, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants