Skip to content

Conversation

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented Dec 6, 2025

This PR prepares the release for version 1.2.0-alpha with version update and code style fixes:

  • Updated version in Solution.props
  • Updated changelog with closed-solved issues
  • Updated README badges

- Added programming language keywords (Python, C#, VB, IronPython)
- Added code-related terms (programming, code, codex) to improve search visibility
Updated manifest description to be more concise and improved formatting with separators. Changed project URL from GitHub repository to smarthopper.xyz website.
…mponents

Changed AI-selecting stateful components to use AISelectingComponentAttributes instead of SelectingComponentAttributes, rendering both the Select button and provider badges together. The button appears above the provider strip with proper layout spacing and includes hover/click states with a 5-second auto-hide timer for selected object highlights.
…s when not specified in GhJSON

Changed deserialization logic to default the UsingStandardOutputParam property to true when ShowStandardOutput is not present in the GhJSON ComponentState, ensuring script components show the "out" parameter by default rather than hiding it.
…g in script generator

Updated AIScriptGeneratorComponent to output summary for both generate and edit modes, consolidating summary/changesSummary handling. Changed all error messages to use "Information" output parameter for consistency. Updated tool descriptions to clarify that summary should include design decisions, and made summary a required field in script_generate tool schema.
…or and Review components

Updated AIScriptGeneratorComponent and AIScriptReviewComponent to support processing multiple inputs in parallel:

- Changed all outputs from item/list to tree access with one branch per input
- In create mode: processes each prompt as a separate branch
- In edit mode: matches prompts/questions to selected components using DataTreeProcessor.NormalizeBranchLengths for first-first, second-second matching
Added Edit Mode functionality to GhPutComponents component and gh_put AI tool:

- Added "Edit Mode" boolean input parameter to GhPutComponents that defaults to false
- When enabled and GhJSON contains valid instanceGuids matching canvas components, users are prompted via StyledMessageDialog to choose between replacing existing components or creating new ones
- The gh_put AI tool now accepts optional editMode parameter in its schema
Added DialogCanvasLink utility that draws visual connection lines from dialogs to linked Grasshopper components:

- Created DialogCanvasLink class that manages visual connections between dialogs and canvas components using bezier curves with anchor dots, similar to script editor anchors
- StyledMessageDialog methods now accept optional linkedInstanceGuid and linkLineColor parameters to enable canvas linking
- Registered canvas link callback in
…sual jitter

Added bounds caching in SelectingComponentAttributes and AISelectingComponentAttributes to fix visual instability when highlighting selected objects:

- Introduced cachedSelectedBounds dictionary that stores component bounds when hover starts
- Bounds are computed once via CacheSelectedBounds() method and reused during entire hover session
- Cache is cleared when hover ends to ensure fresh positions on next hover
…for dialogs

Enhanced component replacement workflow and dialog positioning:

- gh_put tool now prompts user individually for each component replacement instead of batch confirmation, allowing selective replacement
- Added CenterViewOnComponent method to CanvasAccess that pans canvas to position components at specified horizontal location (0=left, 0.5=center, 1=right), skipping pan if component already in central 2/3 of viewport
…t with document merging

Enhanced gh_put tool to preserve connections when replacing components:

- Capture components with depth=1 connections before replacement using ConnectionGraphUtils.ExpandByDepth
- Merge captured document into incoming document via new GhJsonMerger utility that handles component/connection/group merging with ID remapping and deduplication
- Disable GH_Document during replacement to prevent solution recalculation
…rge component

Added comprehensive GhJSON document merging functionality:

- Created GhJsonMerger utility to merge two GrasshopperDocument instances with target document taking priority on component GUID conflicts and automatic ID remapping for connections and groups
- Introduced gh_merge AI tool that merges two GhJSON strings and returns merged GhJSON with detailed merge statistics (components/connections/groups added and deduplicated)
…omponent replacement

Fixed two critical issues in gh_put tool's replacement mode:

- Removed NewSolution call that caused infinite loop when GhPutComponents blocked with GetAwaiter().GetResult(), which pumps Windows messages and allows re-entrant solution execution
- Added connection cleanup before component removal by calling RemoveAllSources on inputs and RemoveSource on all output recipients,
…ExecuteTool

Enhanced AIToolManager.ExecuteTool with caller assembly signature verification to prevent unauthorized tool execution:

- Added VerifyCallerAssembly method that validates both Authenticode certificate thumbprint and strong-name public key token match between caller and host assembly
- Cached host assembly's certificate thumbprint and public key token in lazy-initialized static fields for performance
…ure verification

Hardened AIToolManager.VerifyCallerAssembly to require proper signing in all scenarios:

- Removed development mode bypasses that allowed unsigned assemblies when host was unsigned
- Now throws SecurityException if host assembly lacks either Authenticode signature or strong-name signature
- Updated Sign-Authenticode.ps1 to sign all SmartHopper*.dll assemblies instead of only specific provider assemblies
Changed Sign-Authenticode.ps1 to sign all SmartHopper*.dll files instead of only provider and infrastructure assemblies. Simplified filtering logic from explicit name matching to wildcard pattern matching.
…ExecuteTool

Enhanced AIToolManager.ExecuteTool with caller assembly signature verification to prevent unauthorized tool execution:

- Added VerifyCallerAssembly method that validates both Authenticode certificate thumbprint and strong-name public key token match between caller and host assembly
- Cached host assembly's certificate thumbprint and public key token in lazy-initialized static fields for performance
…nentBase and improve connection capture logic

Refactored GhPutComponents to use StatefulAsyncComponentBase for proper async execution and state management:

- Changed GhPutComponents from GH_Component to StatefulAsyncComponentBase with GhPutWorker to prevent re-entrancy issues
- Set RunOnlyOnInputChanges to false to allow re-placing same JSON multiple times
- Improved deprecated badge appearance
…in selecting components

Enhanced SelectingComponentBase and CombinedSelectingComponentAttributes to draw a visual connector line from the combined selection center to the Select button during hover:

- Changed highlight color from DodgerBlue to DialogCanvasLink.DefaultLineColor for consistency
- Calculate union of all selected object bounds and draw connector line from center to button center
- Added anchor dots at both ends of connector
marc-romu and others added 24 commits December 3, 2025 19:43
- 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
…355)

## Description

- **Script tools & GhJSON scripting workflows**
- Add `ScriptCodeValidator` to detect non-RhinoCommon geometry libraries
and prompt the AI to self-correct scripts.
- Improve `script_generate`, `script_edit`, and `script_review` prompts
with language-specific guidance (Python/IronPython/C#/VB.NET) and
clarify output parameter handling.
- Normalize script language keys (e.g., `python3`, `csharp`) via
`ScriptComponentFactory` for consistent tool behaviour.
- Refine script-related components (`AIScriptGeneratorComponent`,
`AIScriptReviewComponent`) and associated AI tools for more reliable
GhJSON round-trips.

- **Model capabilities and compatibility badges**
- Extend `AIModelCapabilities` with metadata to mark deprecated models
and discourage models for specific tools (e.g., script tools).
- Update provider registries (Anthropic, MistralAI, OpenRouter) and set
better defaults (such as `openai/gpt-5-mini` for Text2Json).
- Add a “Not Recommended” badge to surface discouraged models directly
on AI components and update badge documentation.

- **Docs, CI, and build tooling**
- Update `README.md`, `Architecture.md`, `AIModelCapabilities.md`,
[CONTRIBUTING.md](cci:7://file:///c:/Users/Marc%20Roca/source/repos/architects-toolkit/SmartHopper/CONTRIBUTING.md:0:0-0:0),
and `DEV.md` to document the new scripting workflows, model badges, and
local signing setup.
- Move signing scripts into `tools/`, add a unified
`Build-Solution.ps1`, and simplify key locations for `signing.snk` /
`signing.pfx`.
- Adjust `release-1-milestone` workflow and `dotnet-build` composite
action to use the new signing layout and placeholder
`SmartHopperPublicKey`.
- Add a scripting walkthrough video asset (`img/video-scripting.jpg`)
and link it from the docs/README.

## Breaking Changes

- None expected for end users; changes are additive to existing
scripting workflows and model capabilities.
- Internal CI/build and signing scripts have been reorganized;
contributors using custom scripts may need to update paths to
`tools/Build-Solution.ps1`, `tools/Sign-Authenticode.ps1`, and
`tools/Sign-StrongNames.ps1`.

## Testing Done

- Build solution via `tools/Build-Solution.ps1 -Configuration Release`.
- Run unit tests for core and infrastructure projects.
- Manually validate `script_generate`, `script_edit`, and
`script_review` on sample Grasshopper definitions across supported
providers.

## 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)
… fixes (#356)

This PR prepares the release for version 1.2.0-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 December 6, 2025 20:47
@marc-romu marc-romu enabled auto-merge December 6, 2025 20:52
@marc-romu marc-romu disabled auto-merge December 6, 2025 20:53
@marc-romu marc-romu merged commit d4b3cc1 into main Dec 6, 2025
15 of 16 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