R8a: restore the Key Takeaway and Explainer Note agents - #169
Merged
Conversation
Both chat-node menu items rendered as disabled stubs whose tooltip read "AI note generation isn't available yet". That tooltip had been wrong since R4: the agent layer it blamed is the same one Regenerate Response, Generate Image and Generate Chart have used ever since. The real cause was that KeyTakeawayAgent and ExplainerAgent lived in graphlink_agents_core.py and were deleted with graphlink_app/ in the R7.6b cutover, and nobody ported them. Nothing was blocked. graphlink_note_agent.py restores both, carrying over the prompts, the clean_agent_markdown_response post-processor and the one-chat-call shape verbatim so output matches what the Qt app produced. Two divergences, both because the machinery they relied on is gone: - No text bounding. Legacy passed source text through render_context/ source_snapshot, which died with the Qt app and has no successor. Every surviving agent path feeds unbounded text today, so this matches them rather than reintroducing a single bounded path. - No QThread workers. The dispatcher owns concurrency now, so the legacy worker classes have no counterpart. AgentDispatcher.start_note_generation follows start_chart_generation's directly-awaited shape for the same reason: the result is a brand new note node, so the caller needs it in the same round trip and there is no existing node to hang a spinner on. One guard covers both agents - they are the same gesture differing only in prompt, and running them concurrently would race two notes onto overlapping positions. An empty agent response is treated as a failure rather than becoming a blank note. The note is placed 400px to the right of its source node, tinted with the frontend palette's Mid Gray body and Blue header - the closest surviving equivalents to legacy's Mid Gray + status_info pairing, since no status_info token exists in the new stack. Legacy's note width of 400 is not ported: note width is CSS-driven and not a modeled field. Source text is the node's OWN content, not the branch history generateChart uses - widening it would change what the feature summarises. The frontend test that asserted both items were disabled is inverted rather than deleted: it was the guard encoding the stub as correct, so it now encodes the opposite. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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
Restores the two chat-node menu actions that generated a Key Takeaway or an Explainer Note, replacing disabled placeholders with working agents.
Problem
Both menu items rendered as disabled stubs with the tooltip "AI note generation isn't available yet".
That tooltip had been inaccurate since R4. The agent layer it referenced is the same one
Regenerate Response,Generate ImageandGenerate Charthave used ever since. The actual cause was thatKeyTakeawayAgentandExplainerAgentlived ingraphlink_agents_core.py, were deleted alongsidegraphlink_app/in the R7.6b Qt cutover, and were never ported. No dependency was missing.Changes
graphlink_note_agent.pyrestores both agents, carrying over the system prompts, theclean_agent_markdown_responsepost-processor and the single-chat-call shape verbatim so output matches the previous implementation. Two deliberate divergences, both because the supporting machinery no longer exists:render_context/source_snapshot, which were removed with the Qt application and have no successor. Every surviving agent path feeds unbounded text, so this matches existing behaviour rather than reintroducing a single bounded path.QThreadworkers. Concurrency is owned by the dispatcher, so the legacy worker classes have no counterpart.AgentDispatcher.start_note_generationfollowsstart_chart_generation's directly-awaited shape: the result is a new note node, so the caller requires it within the same round trip and there is no pre-existing node to attach progress state to. A single concurrency guard covers both agents, as they represent the same gesture differing only by prompt; concurrent execution would place two notes at overlapping coordinates. An empty agent response is treated as a failure rather than producing a blank note.Placement and styling. The note is positioned 400px right of its source node, tinted with the frontend palette's Mid Gray body and Blue header — the closest surviving equivalents to the previous Mid Gray +
status_infopairing, as nostatus_infotoken exists in the current stack. The previous note width of 400 is not carried over: note width is CSS-driven and not a modeled field.Source text is the node's own content rather than the branch history
generateChartuses; widening it would change what the feature summarises.The frontend test asserting both items were disabled is inverted rather than removed, as it was the assertion encoding the placeholder as correct.
Verification
tsc --noEmit/ ESLint / tests / buildLive click-through reached
api_provider.chatand surfacedKey takeaway generation failed: Failed to connect to Ollama…because no Ollama instance was running on the verification machine. This exercises the full chain — menu → intent → dispatcher → agent → provider — and confirms the failure path surfaces correctly and creates no node. The success path is covered by unit tests but was not observed against a live model.Related
Hide Other BranchesandOpen Document Viewremain disabled. Both were also lost in the Qt cutover and are tracked as separate work.