-
Notifications
You must be signed in to change notification settings - Fork 0
feat(tools): add runtime data getters and script canvas placement wrappers #359
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…on workflow - Updated version in Solution.props and README badges to 1.2.1-dev.251207 - Added `script_generate_and_place_on_canvas` wrapper tool that combines `script_generate` and `gh_put` in a single call to reduce token consumption - Added `script_edit_and_replace_on_canvas` wrapper tool documentation in DEV.md - Moved `script_generate` and `script_edit` tools to Hidden category (only wrapper tools visible to chat agents)
…indow - Override OnShown to center dialog on the screen containing the owner window or Rhino main window - Use Screen.FromRectangle to detect the target screen from reference window bounds - Fall back to PrimaryScreen if no reference window is available - Calculate center position based on screen's WorkingArea to respect taskbar and system UI
…pt_generate_and_place_on_canvas instanceGuid - Added `gh_get_selected_with_data`, `gh_get_by_guid_with_data`, and `gh_get_errors_with_data` tools that return components with their runtime/volatile data (actual values flowing through outputs) - Added `includeRuntimeData` parameter to base `gh_get` tool for optional runtime data extraction - Runtime data includes total item count, branch structure, and sample values for each parameter
…ds from ToolCalls to ToolResults - Fixed critical bug where identical user messages were collapsed in UI by assigning unique TurnId via `InteractionUtility.GenerateTurnId()` to each user message - Fixed TurnId inconsistency by unconditionally inheriting TurnId from ToolCall to ToolResult instead of conditional check that was never true due to `AIBodyBuilder.EnsureTurnId()` pre-assignment - Updated CHANGELOG.md
|
🏷️ This PR has been automatically assigned to milestone 1.2.1-alpha based on the version in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR enhances SmartHopper's AI tool ecosystem by adding wrapper tools that combine script generation/editing with canvas placement, implementing runtime data extraction for debugging, and fixing critical chat UI deduplication issues.
Key changes:
- Added
script_generate_and_place_on_canvasand enhancedgh_gettools with runtime data support to reduce token usage and improve debugging capabilities - Fixed chat UI bug where identical user messages collapsed into one due to missing unique TurnIds
- Corrected TurnId inheritance for tool results to ensure proper metrics aggregation
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/SmartHopper.Core.Grasshopper/AITools/script_generate.cs | Added script_generate_and_place_on_canvas wrapper tool; removed instanceGuid from base tool result; proper GUID extraction from gh_put result |
| src/SmartHopper.Core.Grasshopper/AITools/gh_get.cs | Added includeRuntimeData parameter and new wrapper tools (gh_get_selected_with_data, gh_get_by_guid_with_data, gh_get_errors_with_data) for runtime data inspection |
| src/SmartHopper.Core.Grasshopper/AITools/gh_put.cs | Enhanced result to include instanceGuids array with actual GUIDs of placed components |
| src/SmartHopper.Core.Grasshopper/Serialization/GhJson/GhJsonSerializer.cs | Implemented ExtractRuntimeData and ExtractParameterVolatileData methods to capture component output values, counts, and branch structure with sample limiting |
| src/SmartHopper.Core/UI/Chat/WebChatDialog.cs | Fixed deduplication bug by assigning unique TurnId to each user message via InteractionUtility.GenerateTurnId() |
| src/SmartHopper.Infrastructure/AICall/Sessions/ConversationSessionHelpers.cs | Changed TurnId assignment for tool results from conditional to unconditional to ensure consistency with originating tool calls |
| src/SmartHopper.Core/Models/Serialization/GHJsonAnalyzer.cs | Relaxed validation to treat missing/null connections as valid empty array instead of error |
| src/SmartHopper.Infrastructure/Dialogs/StyledMessageDialog.cs | Added OnShown override to center dialogs on active window's working area for better UX |
| Solution.props | Bumped version to 1.2.1-dev.251207 |
| README.md | Updated version badge to 1.2.1-dev.251207 and status to "Unstable Development" |
| DEV.md | Documented new script wrapper tools and gh_get* variants including runtime data tools |
| CHANGELOG.md | Added comprehensive entries for new tools, bug fixes, and breaking changes under [Unreleased] |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| (int)(center.X - (this.Width / 2)), | ||
| (int)(center.Y - (this.Height / 2))); |
Copilot
AI
Dec 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible loss of precision: any fraction will be lost.
| (int)(center.X - (this.Width / 2)), | |
| (int)(center.Y - (this.Height / 2))); | |
| (int)(center.X - (this.Width / 2.0)), | |
| (int)(center.Y - (this.Height / 2.0))); |
| (int)(center.X - (this.Width / 2)), | ||
| (int)(center.Y - (this.Height / 2))); |
Copilot
AI
Dec 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible loss of precision: any fraction will be lost.
| (int)(center.X - (this.Width / 2)), | |
| (int)(center.Y - (this.Height / 2))); | |
| (int)Math.Round(center.X - (this.Width / 2.0)), | |
| (int)Math.Round(center.Y - (this.Height / 2.0))); |
Description
Script tools
script_generate_and_place_on_canvaswrapper tool that callsscript_generateandgh_putin a single operation to generate a script component and place it on the canvas, reducing token usage and tool orchestration complexity.script_generateandscript_editfrom chat (kept available viaAIScriptGeneratorcomponent) and added explicitscript_edit_and_replace_on_canvaswrapper for GUID-based edit-and-replace flows.script_generateno longer exposes a pre-placementinstanceGuid; real instance GUIDs now come fromscript_generate_and_place_on_canvas/script_edit_and_replace_on_canvasviagh_put.script_generate_and_place_on_canvasto return the actual GrasshopperinstanceGuidassigned on placement instead of the in-memory GUID fromscript_generate.gh_putfails.GhJSON /
gh_gettools and runtime datagh_getto support optional runtime/volatile data extraction via a newincludeRuntimeDataparameter.GhJsonSerializer.ExtractRuntimeDataandExtractParameterVolatileData:hasMoremarkers.InstanceGuidfor downstream analysis.gh_get:gh_get_selected_with_data,gh_get_by_guid_with_data,gh_get_errors_with_datafor targeted snapshots that include runtime data.gh_get_selected,gh_get_by_guid,gh_get_errors,gh_get_locked,gh_get_hidden,gh_get_visiblefor more focused structural queries.gh_get.cs(filters, connection depth,includeRuntimeData,guidFilter) and wired them throughGhGetToolAsync, including aforceIncludeRuntimeDataflag for the*_with_datawrappers.GHJsonAnalyzerso missingconnectionsis treated as an empty array (no connections) while still erroring whenconnectionsexists but is not an array.gh_puttoolgh_putresult to include aninstanceGuidsarray containing the actualInstanceGuids of all placed components.Chat UI and conversation session
WebChatDialognow assigns a uniqueTurnIdto every outgoing user interaction viaInteractionUtility.GenerateTurnId(), ensuring dedup keys remain distinct even for identical content.ConversationSessionTurnId consistency:TurnIdfrom their originating tool calls (no conditional assignment), ensuring correct per-turn metrics aggregation.TurnId.Dialogs and UX
StyledMessageDialogpositioning by centering dialogs on the active Rhino/Eto window’s working area onOnShown, for more predictable and user-friendly placement.Docs and versioning
1.2.1-dev.251207inSolution.propsand updated README badges to reflect the new dev version and unstable development status.DEV.md(script wrappers andgh_get*variants, including*_with_datatools).[Unreleased]to record:script_generateno longer exposes a pre-placementinstanceGuid.Breaking Changes
script_generateno longer returns a pre-placementinstanceGuid; instance GUIDs should be obtained viascript_generate_and_place_on_canvas/script_edit_and_replace_on_canvas(or directly fromgh_put), which aligns with the intended usage pattern.connectionsas valid (empty) instead of an error, which is a relaxation rather than a breaking change.Testing Done
script_generate_and_place_on_canvas:instanceGuidmatches the component actually placed in Grasshopper.script_edit_and_replace_on_canvas:instanceGuid.gh_get*tools:gh_get_selected_with_data/gh_get_by_guid_with_data/gh_get_errors_with_dataon small and moderate definitions and verify:runtimeDataincludes correct total counts, branch structure, and sample values.Dialog UX:
StyledMessageDialogand confirm dialogs are centered on the active Rhino window.Automated tests:
Checklist
Solution.propswas updated, if necessary, and follows semantic versioning