Repository navigation
AI Assistant: fix Save to Macros in worker mode, propose macros without running them - #77
Merged
Merged
Conversation
"Save to Macros" showed "Saved ✓" but the macro never appeared in the Macros panel. DataLabRuntime.saveMacro created the macro, then notified the panel through a "dlw:macros-changed" event on `window`, guarded by `typeof window !== "undefined"`. Since 0.10.0 the runtime runs by default in a Dedicated Web Worker, where there is no `window`: the event was never dispatched, and each click added another hidden macro to the workspace. The AI Assistant panel now saves through the Macros panel (`onSaveMacro` -> `MacroPanel.importMacro`), which works in both runtime modes and brings the Macros tab to the front; saveMacro and the event are removed. Same boundary: get_macro_console_output read the public `lastMacroOutput` field, which the worker façade turns into a forwarding function (the model received an empty result). It is now read through getLastMacroOutput(). The model could also answer "write a macro" requests with plain code that cannot be saved: the system prompt sent super-Gaussian, Lorentzian and polynomial curves to create_synthetic_signal, which cannot produce them, while forbidding macros. The prompt now follows the kinds the creation tools support, and create_and_run_macro gets an `autorun` parameter (as in DataLab desktop): with `autorun: false`, the macro is only linted and offered for saving. The approval dialog states it, and remembering such an approval never auto-approves a macro that runs. As a fallback, a "Save to Macros" button is offered under each Python code block of the replies. Tests: unit tests (tools, prompt, code blocks, panel incl. a conversation restored from IndexedDB), an audit of the worker boundary (public runtime members must be methods; no `window` events from the runtime), which fails on the previous runtime, and an E2E test in worker mode with the mock provider. Closes #76 Assisted-by: Claude Opus 5.5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Found during a demo: in a conversation reopened from the history, 💾 Save to Macros turned into Saved ✓, but no macro appeared in the Macros panel; asking the same question again, the assistant answered with plain code and no Save to Macros button.
Closes #76 — companion desktop fix: DataLab-Platform/DataLab#448 (DataLab-Platform/DataLab#447).
Root causes and fixes
DataLabRuntime.saveMacrocreated the macro, then notified the Macros panel through adlw:macros-changedevent onwindow. Since 0.10.0 the runtime runs by default in a Dedicated Web Worker, wherewindowdoes not exist: the event was never dispatched (and each click added another hidden macro). The AI Assistant panel now saves through the Macros panel (onSaveMacro→MacroPanel.importMacro), which works in both runtime modes and brings the Macros tab to the front (a floating Macros panel is left as is).saveMacroand the event are removed.get_macro_console_output: read the publiclastMacroOutputfield, which the worker façade turns into a forwarding function: the model received an empty result. Now read throughgetLastMacroOutput().create_synthetic_signal(which only supports sine, cosine, gauss and noise) while forbidding macros. The prompt now follows the kinds the creation tools actually support, and routes "write a macro" requests tocreate_and_run_macrowith the newautorun: falseparameter (as in DataLab desktop): the macro is only linted and offered for saving. The approval dialog states that it will not be executed, and remembering such an approval never auto-approves a macro that runs (separate approval key).extractMacroCodeBlocks, viamarked.lexer), named after the user request. The sanitized Markdown HTML is untouched.Tests
tools.test.ts(autorun,getLastMacroOutput, approval key),macroCodeBlocks.test.ts,systemPrompt.test.ts,panel.test.tsx(save throughonSaveMacro, conversation restored from IndexedDB, retry after a failed save, code-block buttons, approval scoping). The panel tests now reset the conversation store between tests.workerBoundaryAudit.test.ts— publicDataLabRuntimemembers must be methods, and the runtime must not dispatch DOM events. Both checks fail on the previousruntime.ts.ai_assistant_macro.spec.ts, in worker mode with the mock provider: save a proposed macro, save it again after a reload from the restored conversation (the demo scenario), save a code block.format:check,lint,tsc -b,vitest run(969 passed), Playwrightai_assistant_macro,worker_modeandmacrospecs.Not covered: the actual choice of a real LLM (the prompt makes plain-code answers less likely; the code-block button covers the remaining cases).