openpencil/apps/web/server/api
Fini 3a6a0b6dcf feat(ai): make advertised batch_design fallback actually executable
ELEMENT_TOOL_OUTPUT_FORMAT tells the AI to emit
`<op_tool>{"name":"batch_design", ...}` when no element-tool fits.
Prior Nitro implementation hard-coded a 501 for any DSL payload,
so the FALLBACK branch advertised to the AI was a lie — any AI
that actually took the guidance would see its generation fail.

Fix extracts pen-mcp's `handleBatchDesign` pure executor
(`runBatchDesignDsl`) from the file-I/O wrapper and exposes it on
the package's main barrel. Nitro's `/api/mcp/exec-tool` now
accepts `{dsl}`, runs the executor against a clone of the
sync-state doc (no file I/O, no post-processing hooks — those
belong to the pen-mcp server process), and calls setSyncDocument
to broadcast the result via SSE. Response shape gains
`insertedNodeIds: string[]` so batch inserts (multiple root
bindings in one DSL) surface all their root nodes to the
orchestrator's progress accounting, not just the first.

Client dispatcher updated to prefer the array form with fallback
to the legacy single-id field. Adds a test asserting the
dispatcher actually calls fetch when taking the DSL fallback
(proves the route wires end-to-end). JSDoc in dispatcher +
endpoint updated so code and docs agree.

handleBatchDesign's external behavior is unchanged — it still
opens / post-processes / saves around the refactored executor;
311/311 pen-mcp tests pass unchanged.
2026-04-21 22:25:10 +08:00
..
ai V0.7.3 (#111) 2026-04-15 22:19:12 +08:00
mcp feat(ai): make advertised batch_design fallback actually executable 2026-04-21 22:25:10 +08:00
local-asset.get.ts V0.7.0 (#95) 2026-04-11 23:25:13 +08:00