mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
* fix(mcp): route object-typed params to JSON editor, keep invalid drafts out of tool args
Two follow-up gaps from the earlier MCP schema fix:
- getInputType only routed array-typed and non-primitive-enum params to
the long-input JSON editor; a plain object-typed param (no enum) fell
through to the default short-input, which stores raw text via
toString() and never round-trips a real object.
- The long-input onChange fell back to storing the raw typed text
whenever JSON.parse failed (needed to keep the controlled textarea
responsive mid-edit), but that meant an incomplete/invalid edit
(e.g. `{"a":1` before the closing brace) could persist into the
actual tool arguments. If executed in that state, the MCP execute
route's array-coercion step would silently wrap the malformed string
into a corrupted array instead of failing validation.
Invalid-edit text now lives in local `invalidJsonDrafts` state, keyed
by param name, instead of the real argument store — the textarea still
reflects every keystroke, but the persisted tool argument is always
either the last successfully parsed value or untouched. Drafts reset
when the selected tool changes.
* fix(mcp): reset invalid JSON drafts on schema change, not just tool change
The draft reset only fired when the selected tool id changed, so a
same-tool schema refresh (e.g. re-discovering tools from the live MCP
server) could leave a stale invalid draft displayed under a param name
whose shape had since changed. Key the reset off both the tool id and
a signature of the effective schema's properties, so any change to
what's actually being edited clears stale drafts.
* fix(mcp): key draft reset off both schema sources, not the resolved toolSchema
toolSchema resolves to cachedSchema || selectedToolConfig?.inputSchema,
so a live-only schema refresh (the discovered tool's inputSchema
changes but the cached _toolSchema snapshot doesn't) left the reset
key unchanged and could keep a stale invalid draft on screen. Track a
signature of each schema source independently so a change in either
one clears drafts, regardless of which source toolSchema resolves to.
* fix(mcp): sign whole schema for draft reset; invalidate drafts on external value changes
Two more follow-up gaps:
- schemaSignature only serialized schema.properties, so a same-tool
refresh that changed only top-level fields like `required` (properties
byte-identical) left the reset key unchanged. Sign the entire schema
instead of cherry-picking fields, so nothing schema-level can be missed.
- A draft only reset on tool/schema change, so if the persisted argument
changed for any other reason (undo/redo, a diff baseline switch, a
collaborator's concurrent edit), the draft could keep shadowing the
now-current value in the editor while execution used the real one.
Drafts now carry a baseline signature of the value they were typed
against; a draft only displays while that baseline still matches the
live persisted value, so any external change makes it fall back to
showing the real value instead of stale text.
* fix(mcp): restore comma-separated array input; stop spurious draft reset on tool load
Two more follow-up gaps:
- Holding every JSON.parse failure in a local draft blocked the
documented comma-separated array shorthand (see the placeholder text)
from ever reaching toolArgs, since plain comma-separated text is
never valid JSON. Only an in-progress JSON array/object literal
(starting with `[` or `{`) needs to stay in the draft until valid;
plain array-typed text that isn't attempting JSON persists
immediately as before, letting the execute route's existing
comma-split/wrap coercion handle it as designed.
- draftResetKey always included the live selectedToolConfig schema
signature, even when cachedSchema wins the `toolSchema` resolution.
That segment flips from empty to populated the moment mcpTools
finishes an unrelated async load, wiping in-progress drafts though
neither the rendered schema nor the stored args changed. The live
signature now only factors into the key when there's no cached
snapshot for toolSchema to prefer.
* fix(mcp): reset drafts on genuine live schema refresh, not just its first load
Excluding the live schema signature whenever a cached snapshot exists
(the prior fix for a Cursor finding about mcpTools' initial load
spuriously wiping drafts) went too far the other way: a genuine
same-tool live schema refresh while a cached snapshot is still present
would no longer reset drafts either.
Track the live schema signature unconditionally, but only treat a
change as a real reset trigger when it goes from one non-empty
signature to a *different* non-empty one. The bare empty → non-empty
transition (mcpTools completing its initial fetch) is excluded, since
that's not a schema change; a populated → differently-populated
transition (an actual re-discovery) still resets drafts regardless of
whether a cached snapshot is present.
* fix(mcp): compare live schema against last-known-non-empty, not prior render
Comparing the live schema signature only against the immediately
preceding render's value meant a schema that dropped to empty and then
reappeared with different content was invisible to the reset check —
both the drop (X → '') and the reappearance ('' → Y) look like a bare
empty/non-empty transition, which was deliberately excluded to avoid
resetting on mcpTools' initial load. Track the last non-empty value
actually observed instead, so a transient empty gap no longer erases
the baseline: the schema reset now fires correctly when the tool
reappears with a genuinely different schema, while a real first-ever
load (no prior non-empty value at all) still doesn't spuriously reset.
* fix(mcp): re-baseline live schema tracker fresh on every tool switch
lastNonEmptyLiveSchemaSignature carried over across a tool switch
whenever the newly-selected tool's live schema hadn't loaded yet in
that same render (still empty). When it loaded a moment later, the
comparison was against the *previous* tool's signature, so the new
tool's first schema load could be misread as a "genuine refresh" and
wipe drafts the user had already started typing against the new tool.
A tool/cached-schema change now always re-baselines the live-schema
tracker to the new tool's current signature (even if still empty), so
the "same tool" refresh comparison never bleeds across tool switches.