Development Log
A detailed, reverse-chronological record of all changes, fixes, and architectural decisions made during the development of Graphite Pro.
[Beta v.0.6.9]
2025-11-04
This is a major feature release that introduces the Conversation Node, a powerful new tool for managing complex, linear discussions within the graph. This feature allows users to encapsulate detailed sub-tasks into a single, interactive node, which can both inherit and provide rich context to the main canvas.
Added
- Introduced the Conversation Node Plugin.
- Feature: A new "Conversation Node" can be created from the "Plugins" menu. It provides a self-contained, vertically scrolling chat interface (similar to standard chatbots) directly on the canvas.
- Context Inheritance: When created, the node automatically makes a one-time copy of its parent's entire conversation history and displays it visually. This "snapshots" the context, allowing the new conversation to start with a full understanding of the preceding discussion.
- Focused Interaction: Users can engage in a detailed, multi-step conversation with the AI entirely within the node's UI, preventing clutter on the main graph.
- Context Provision: The entire internal chat log of the Conversation Node (inherited history + new messages) can be used as a rich source of context for any new nodes that branch off from it.
- Architectural Integration for the New Node Type.
- Dedicated UI: The node's internal UI was built using a custom
QGraphicsSceneandQGraphicsView, where each message is a distinctChatMessageBubbleItem. This ensures full integration with application features. - Search and Highlighting: The application's search functionality (
Ctrl+F) now works seamlessly inside Conversation Nodes, correctly highlighting the specific message bubble that contains the search term. - Full Persistence: The
ChatSessionManagerhas been updated to serialize and deserialize Conversation Nodes, including their entire internal chat history and connections, ensuring that sessions are saved and loaded perfectly. - Plugin Interoperability: All other plugin nodes (like
Py-CoderandWebNode) can now be correctly branched from a Conversation Node, allowing for complex, chained workflows.
- Dedicated UI: The node's internal UI was built using a custom
Fixed
- Made the
graphite-WebPlugin Context-Aware.- Problem: The
graphite-Webnode was not using the conversation history. This meant that contextual queries (e.g., "what is its price?") would fail because the search agent lacked the necessary context to understand what "it" referred to. - Solution: The web search workflow has been rebuilt. The agent now uses an LLM to analyze the conversation history and transform the user's input into a self-contained, effective search query. The summarization step also receives the full conversation history, allowing it to generate a final answer that is relevant to the ongoing discussion.
- Result: The
graphite-Webplugin now correctly handles contextual follow-up questions, making it a much more powerful and intuitive tool for research.
- Problem: The
- Refined Chat UI for Conversation Node.
- Problem: The initial design of the internal chat UI used visually jarring colors (bright green and blue) that did not fit the node's aesthetic.
- Solution: The chat bubbles were redesigned with a professional, neutral color scheme (dark grays) to create a more focused and visually pleasing user experience.
[Beta v.0.6.8]
2025-11-04
This is a major stability and user experience release that resolves critical threading crashes, fixes widespread UI inconsistencies, and introduces a new long-hover interaction to visualize conversation flow.
Architectural Refactor
- Corrected Application Threading Model to Eliminate Crashes.
- Problem: The application was unstable and would frequently crash with
QThread: Destroyed while thread is still runningandQObject::killTimer: Timers cannot be stopped from another thread. This was caused by a fundamental architectural flaw where worker thread objects were being prematurely garbage-collected or improperly managed from the main GUI thread. - Solution: The threading architecture was completely rebuilt to adhere to Qt's strict threading and memory management rules.
- Correct Object Ownership: Worker threads are now stored as member variables of the
ChatWindow, creating a persistent reference that prevents them from being destroyed while running. - Safe Self-Destruction: All worker threads now use the
deleteLater()slot connected to theirfinishedanderrorsignals. This is the standard Qt "fire-and-forget" pattern, ensuring threads schedule their own safe cleanup from the main event loop. - Removal of Unsafe Code: All manual thread cleanup methods (
cleanup_..._thread) and the dangerousstop_all_workersprocedure were removed entirely, as they were the root cause of the crashes.
- Correct Object Ownership: Worker threads are now stored as member variables of the
- Result: The application is now architecturally sound and stable, with all critical threading crashes resolved.
- Problem: The application was unstable and would frequently crash with
Added
- Implemented Ancestor Connection Animation on Long Hover.
- Feature: A new
HoverAnimationMixinclass was created to provide shared functionality to all node types. When a user hovers their mouse over any node for a brief period (750ms), the connection lines for all of its ancestors are animated with flowing arrows, tracing the conversational path back to the root. - Benefit: This provides intuitive, real-time visual feedback, making it easy to understand the history and context of any node within a complex graph. The animation stops immediately when the hover ends.
- Feature: A new
Fixed
- Resolved Keyboard Shortcut Interference with Text Input.
- Problem: The keyboard shortcuts for canvas navigation (
W,A,S,D,Q,E) were incorrectly intercepting key presses when the user was trying to type inside aNote,Frametitle,PyCoderNode, orWebNode. - Solution: The
keyPressEventhandler inChatViewwas updated to be context-aware. It now checks if the currently focused item is a text input field or in a custom editing mode. If so, the navigation shortcuts are bypassed, allowing for normal text input.
- Problem: The keyboard shortcuts for canvas navigation (
- Restored Hover Highlight Effect on All Nodes.
- Problem: An architectural mistake in the implementation of the
HoverAnimationMixincaused it to incorrectly override thehoverEnterEventandhoverLeaveEventmethods of all nodes, breaking the standard visual hover highlight effect. - Solution: The mixin was refactored to provide helper methods (
_handle_hover_enter,_handle_hover_leave) instead of overriding the events directly. Each node class now correctly calls both its superclass's event handler and the mixin's helper, restoring the hover highlight while enabling the new animation feature.
- Problem: An architectural mistake in the implementation of the
- Corrected Lost Connections for Plugin Nodes.
- Problem: Connections branching off from
PyCoderNodeandWebNodewere not being saved, causing them to disappear when a chat session was reloaded. - Solution:
- The serialization logic was fixed to save the
children_indicesforPyCoderNodeandWebNode, ensuring these relationships are persisted. - The plugin creation logic was updated to correctly establish the bidirectional parent-child link in the live object graph when these nodes are created.
- The serialization logic was fixed to save the
- Problem: Connections branching off from
[Beta v.0.6.7]
2025-11-03
This release introduces the Web Search Plugin, a major new feature that integrates real-time web information directly into the Graphite canvas. It allows users to perform web-grounded queries with a built-in safety and relevance validation process.
Added
- Introduced the Web Search Plugin (
graphite-Web).- Feature: A new "graphite-Web" node can be created from the "Plugins" menu or the Command Palette (
Ctrl+K). This node provides a dedicated interface to run web queries. - Workflow: The node orchestrates a multi-step process in the background:
- Performs a web search based on the user's query.
- Fetches content from the top search results.
- Validates each piece of content for safety and relevance using a dedicated AI call.
- Summarizes the validated content to provide a concise, direct answer to the original query.
- UI: The
WebNodehas a distinct orange theme and provides real-time status updates as it progresses through the search, fetch, validate, and summarize stages. Final results include a formatted summary and clickable source links.
- Feature: A new "graphite-Web" node can be created from the "Plugins" menu or the Command Palette (
- Expanded System Architecture for Web Functionality.
- New Agents: Implemented a
WebSearchAgentandWebWorkerThreadto handle the complex, multi-step retrieval and validation logic without freezing the UI. - Serialization: The
ChatSessionManagerhas been updated to fully support saving and loading the newWebNodeand its connections, ensuring complete data persistence. - Plugin Integration: The
PluginPortalandChatScenewere extended to manage the lifecycle of the new web components.
- New Agents: Implemented a
Fixed
- Resolved Critical Signal/Slot Initialization Error.
- Problem: The application would crash when creating a
WebNodedue to anAttributeError, as the node's signals were not correctly registered. - Solution: The base class for
WebNodewas corrected fromQGraphicsItemtoQGraphicsObject, which is required for using Qt's signal and slot mechanism in graphics items. This resolved the instability and made the plugin functional.
- Problem: The application would crash when creating a
- Corrected API Routing for Web Validation.
- Problem: The web validation step was incorrectly hard-coded to use a specific API, ignoring the user's selection of "Ollama (Local)" mode and causing errors if an API key was not configured.
- Solution: The API provider logic was refactored to strictly adhere to the globally selected mode (
Ollamavs.API). The validation task now correctly routes to the user's chosen provider, restoring logical consistency.
- Updated Deprecated Dependency.
- Problem: A
RuntimeWarningwas being issued because theduckduckgo-searchlibrary had been renamed. - Solution: The import statement was updated to use the new package name,
ddgs, ensuring future compatibility and silencing the warning.
- Problem: A
- Fixed Painter State Error in Web Connection Animation.
- Problem: A
QPainterwarning (Painter ended with 1 saved states) was triggered when hovering over aWebNodeconnection. This was caused by an argument type mismatch in the animation drawing method, leading to an unbalanced painter state. - Solution: Implemented a local
drawArrowmethod inWebConnectionItemto correctly handle its specific drawing logic, ensuring the painter's state is properly saved and restored. This eliminates the warning and potential rendering artifacts.
- Problem: A
[Beta v.0.6.6]
2025-11-03
This release introduces comprehensive keyboard navigation for the canvas, improving accessibility and workflow speed. It also includes several quality-of-life improvements and a critical bug fix for the cursor state.
Added
- Implemented Full Keyboard Navigation.
- WASD Panning: The canvas can now be panned smoothly using the W, A, S, and D keys. Movement is continuous while keys are held down.
- Q/E Zoom: Users can now zoom in with the 'E' key and zoom out with the 'Q' key, providing a keyboard-centric alternative to mouse-wheel zooming.
- Logical Node Traversal (
Ctrl + Arrow Keys): A new system allows for precise navigation between related nodes:Ctrl+Up: Jumps to the parent of the currently selected node.Ctrl+Down: Jumps to the first child of the currently selected node.Ctrl+Left/Ctrl+Right: Jumps to the previous or next sibling node in the same branch.
- Added Welcome Screen Preference.
- Feature: An option to "Show Welcome Screen on Startup" has been added to the
Settings > Appearancedialog. - Effect: When unchecked, the application will bypass the welcome screen and launch directly into the main interface, loading the most recent chat session. This preference is saved and persists across launches.
- Feature: An option to "Show Welcome Screen on Startup" has been added to the
Fixed
- Resolved Stuck Panning Cursor Bug.
- Problem: The cursor would get stuck in the "closed hand" panning state if the user released the middle mouse button while the cursor was outside the application window.
- Solution: The view's
mouseMoveEventwas enhanced to reliably check the global state of the mouse buttons. It now correctly detects when the middle mouse button is no longer pressed and resets the cursor to its default state, regardless of where the release event occurred.
- Corrected Welcome Screen Behavior.
- Problem: The welcome screen would remain open in the background after a user selected a project or started a new chat.
- Solution: The welcome screen now automatically closes itself upon performing an action that opens the main chat window, streamlining the application startup flow.
[Beta v.0.6.5]
2025-11-03
This release refines the AI's code generation output and resolves critical architectural bugs related to plugin functionality, resulting in a more stable and predictable user experience.
Architectural Refactor
- Standardized AI Code Block Generation.
- Problem: The AI model would often split a single logical code block across multiple markdown fences, causing the application to create a separate
CodeNodefor each fragment. This resulted in a cluttered and disorganized canvas. - Solution:
- The
ChatAgent's system prompt has been updated with a strict new rule: all code, regardless of the number of segments, must be wrapped within a single<code_block>...</code_block>XML tag. - The response parsing logic in
ChatWindowwas re-architected to prioritize this new tag. It now first searches for<code_block>; if found, it extracts the entire content and treats it as a single unit for oneCodeNode. - A fallback mechanism was retained: if the tag is not found, the parser reverts to the old behavior of identifying individual markdown fences.
- The
- Result: This ensures that all code generated in a single AI response is consolidated into one
CodeNode, providing a clean, coherent output. The fallback maintains robustness if the model fails to adhere to the new format.
- Problem: The AI model would often split a single logical code block across multiple markdown fences, causing the application to create a separate
Fixed
- Corrected
PyCoderNodeContextual Attachment Logic.- Problem: The PyCoder plugin could be incorrectly attached to a
CodeNode. When executed, this would cause a fatalAttributeErrorbecauseCodeNodeobjects do not possess aconversation_history, which is essential for providing context to the AI. - Solution:
- The plugin creation logic in
graphite_plugin_portal.pywas updated. It now intelligently determines the correct parent for thePyCoderNode. If the user has aCodeNodeselected, the system automatically traverses up to its parentChatNodeand attaches the PyCoder plugin there instead. - Defensive code was added to
graphite_window.py. The execution logic now verifies the parent node's type before attempting to accessconversation_history, ensuring it always retrieves context from a valid source (ChatNodeor anotherPyCoderNode).
- The plugin creation logic in
- Result: The application no longer crashes when using the PyCoder plugin in this scenario. The plugin's attachment behavior is now architecturally sound and predictable.
- Problem: The PyCoder plugin could be incorrectly attached to a
- Resolved
ImportErroron Startup.- Problem: The application would fail to launch due to a circular or incorrect import statement where
graphite_plugin_portal.pyattempted to importPyCoderNodefromgraphite_node.pyinstead of the correctgraphite_pycoder.pymodule. - Solution: The invalid import path was corrected, resolving the dependency conflict and allowing the application to start normally.
- Problem: The application would fail to launch due to a circular or incorrect import statement where
[Beta v.0.6.4]
2025-11-02
This release introduces a powerful and flexible content export system, allowing users to save the contents of individual nodes to a variety of standard file formats. The architecture for this feature is designed to be modular and easily extensible.
Architectural Refactor
- Created a Centralized
ExporterModule.- Problem: Implementing export logic directly within UI classes would lead to scattered, duplicated code that is difficult to maintain.
- Solution: A new
graphite_exporter.pyfile was created to house a dedicatedExporterclass. This class encapsulates all file conversion and writing logic for each supported format. UI components now simply call theExporterwith the content and desired format, decoupling the user interface from the file generation process. - Result: This modular design makes it simple to add new export formats in the future without modifying any UI code.
Added
- Implemented Multi-Format Node Content Export.
- Feature: A new "Export to Doc" submenu is now available in the right-click context menu for
ChatNode,CodeNode, andDocumentNode. - Formats:
- Text File (.txt): Exports the raw text content.
- Markdown File (.md): Exports the raw content, preserving markdown syntax. For code nodes, it automatically wraps the code in a markdown code block.
- HTML Document (.html): Converts the node's markdown content into a self-contained, styled HTML file.
- Word Document (.docx): Exports the content into a standard
.docxfile. (Requirespython-docx) - PDF Document (.pdf): Renders the content into a PDF file, with special monospace formatting for code. (Requires
reportlab) - Python Script (.py): An additional option exclusive to
CodeNodefor direct script saving.
- Image Export: The "Save Image As..." option for
ImageNodewas renamed to "Export Image" for consistency.
- Feature: A new "Export to Doc" submenu is now available in the right-click context menu for
- Graceful Handling of Optional Dependencies.
- Feature: The application now intelligently handles cases where optional libraries required for certain export formats (
reportlabfor PDF,python-docxfor DOCX) are not installed. - User Experience: If a user attempts to export to a format with a missing dependency, the application will not crash. Instead, a clear and informative message box appears, explaining which library is needed and providing the
pip installcommand to install it.
- Feature: The application now intelligently handles cases where optional libraries required for certain export formats (
Fixed
- Resolved Crash on Export Dialogs.
- Problem: The application would crash with an
AttributeErrorwhen showing the success/failure message box after an export, because the dialog's parent was being set incorrectly. - Solution: The logic for retrieving the main window was corrected. Instead of an unreliable
self.parent()call, the code now correctly traverses the object hierarchy from theQGraphicsItem(the node) to its scene, and then to the scene'swindowproperty, ensuring a validQWidgetparent is always found for the dialogs. This also fixed a bug where the dialogs were missing the application icon.
- Problem: The application would crash with an
[Beta v.0.6.3]
2025-11-02
This update focuses on significant UI refinement and consistency, enhancing the visual language and interactive feedback of the core node-graph system.
Added
- Persistent Node Connection Points.
- Feature: All
ChatNodeandPyCoderNodeitems now feature permanently visible connection points. - Detail: These points are rendered as colored half-circles that seamlessly emerge from the left (input) and right (output) sides of the node. The color of the connection point matches the node's identity color (e.g., green for user nodes, blue for AI nodes, purple for PyCoder), reinforcing the visual flow of information.
- Result: This provides a clear, consistent, and aesthetically pleasing visual language for how nodes are connected, removing ambiguity about where connection lines terminate.
- Feature: All
- Universal Connection Hover Animation.
- Feature: The animated "flowing arrow" effect, previously exclusive to primary chat connections, has been implemented across all directional connection types.
- Effect: Hovering over any connection line (including those for code blocks, documents, images, and the PyCoder plugin) now triggers the animation, providing consistent visual feedback for interactivity and data flow across the entire canvas. The animation color is styled to match the specific connection type.
Fixed
- Resolved Visual Gap in Connection Lines.
- Problem: In a previous implementation, connection lines appeared to stop short of their target nodes because the connection dots they were anchored to were only visible on hover.
- Solution: By making the new half-circle connection points permanently visible, the connection lines now appear to terminate perfectly at the node's edge, creating a visually complete and polished look.
[Beta v.0.6.2]
2025-11-01
This is a rapid-response update focused on critical stability fixes, a quality-of-life improvement for the new Container system, and the introduction of a comprehensive, application-wide themeing architecture. A series of architectural flaws related to object lifecycles, coordinate systems, and import dependencies were identified and resolved, eliminating crashes and addressing visual bugs across the UI.
Architectural Refactor
- Centralized Theme and Color Palette System.
- Problem: Hardcoded colors were scattered across numerous UI components, including both Qt stylesheets and custom
paintmethods withinQGraphicsItems. This made the application rigid and difficult to style. - Solution: A new, scalable themeing architecture was implemented.
- A
ColorPaletteclass was created ingraphite_styles.pyto act as a single source of truth for all custom-drawn UI elements (nodes, connections, highlights, etc.). - A central
THEMESdictionary now maps theme names ("dark", "mono") to both a full application stylesheet and a correspondingColorPaletteobject. - A global
apply_themefunction was established ingraphite_config.py. This function updates the application's stylesheet and signals all open windows to repaint themselves using the new palette, ensuring a consistent, application-wide theme change.
- A
- Result: This decouples visual presentation from component logic, resolves numerous visual bugs at their source, and enables the rapid development of future themes.
- Problem: Hardcoded colors were scattered across numerous UI components, including both Qt stylesheets and custom
Added
- Introduced Dual-Mode "PyCoder" Plugin.
- Feature: The PyCoder plugin has been re-architected to support two distinct operational modes, providing both intelligent automation and direct user control.
- AI-Driven Mode (Default): The AI now functions as a "tool-using" agent. It receives a high-level user prompt and independently determines whether to write and execute Python code to find the answer. The entire workflow—code generation, execution, output capture, and final analysis—is fully automated. This allows users to ask complex computational questions in natural language.
- Manual Mode: The original functionality is preserved as a "Manual" mode. Users can switch to this mode to write, run, and debug their own Python code in a dedicated scratchpad, optionally receiving AI analysis on their code and its output.
- Result: This transforms PyCoder from a simple code executor into a versatile and intelligent problem-solving tool, greatly expanding the application's capabilities.
- Upgraded PyCoder to be Context-Aware.
- Feature: The AI-Driven mode of the
Py-Coderplugin now receives the full conversation history from its parent node. - Effect: The agent can now use the preceding conversation as context when generating code. This allows for more intuitive and powerful requests, such as referring to data or concepts mentioned in previous messages (e.g., "Take that list of names from before and sort it alphabetically").
- Implementation: The
PyCoderExecutionWorkerwas updated to accept the parent'sconversation_history, and thePyCoderExecutionAgent's system prompt was enhanced to instruct it on how to leverage this contextual information.
- Feature: The AI-Driven mode of the
- Implemented Automated Error Correction for PyCoder.
- Feature: The AI-Driven
Py-Coderagent is now capable of self-correction. If the code it generates results in an error, it will automatically attempt to debug and fix it. - Workflow:
- The agent generates and executes code.
- If an error is detected in the output, the error log is fed back to a specialized
PyCoderRepairAgent. - The repair agent returns a corrected version of the code, which is then re-executed.
- This process repeats up to a maximum of four attempts. On the final attempt, the agent is prompted to try a completely different approach.
- Result: This significantly increases the reliability and success rate of the PyCoder feature, allowing it to overcome common coding mistakes without user intervention.
- Feature: The AI-Driven
- Added a Real-Time Status Tracker to the PyCoder Node.
- Feature: The verbose "Execution Log" text area has been replaced with a clean, intuitive checklist UI (
StatusTrackerWidget). - Effect: This new component provides at-a-glance feedback on the agent's progress, showing the status (Pending, Running, Success, Failure) of each stage in the workflow: Analyzing Prompt, Generating Code, Executing & Repairing, and Final Analysis. The "Running" state features a smooth, custom-drawn vector animation.
- Implementation: This was achieved by creating a new
StatusIconWidgetthat usesQPainterfor crisp vector rendering, eliminating the pixelation issues of the previous icon-based approach. The worker thread now communicates with the UI using a structured system ofEnumsfor stages and statuses, making the architecture more robust.
- Feature: The verbose "Execution Log" text area has been replaced with a clean, intuitive checklist UI (
- Implemented Monochromatic Theme.
- Feature: A new "Monochromatic Mode" option is now available in
Settings > Appearance. The user's choice is persisted across application sessions. - Effect: When enabled, it applies a grayscale color palette across the entire application, affecting everything from window backgrounds and buttons to custom-drawn node outlines and connection lines. This provides a lower-contrast, less colorful user experience.
- Feature: A new "Monochromatic Mode" option is now available in
- Implemented "Ghost Frame" Preview for Collapsed Containers.
- Feature: Hovering the cursor over a collapsed
Containerfor 2 seconds now displays a semi-transparent "ghost" preview. This preview is centered on the cursor and shows the full size and shape the container will occupy when expanded. - Purpose: This provides essential spatial context, allowing users to plan their canvas layout and organize items around a collapsed group without needing to expand it first. The feature uses a
QTimerto manage the hover delay and anotherQTimerto automatically dismiss the preview after 3 seconds.
- Feature: Hovering the cursor over a collapsed
Fixed
- Resolved Critical Infinite Loop When Replying to PyCoder Nodes.
- Problem: Responding to a
PyCoderNodewould cause the application to hang with an infinite loading animation. - Solution (Architectural): The issue was traced to a critical flaw in the chat deserialization logic (
graphite_core.py). A node was being incorrectly set as its own parent (child_node.parent_node = child_node), creating a self-referential loop in the graph's data structure. When theChatWorkerattempted to traverse this branch to build the conversation history, it entered an unbreakablewhileloop, causing the thread to hang indefinitely. The fix involved correcting the parent assignment tochild_node.parent_node = node, restoring the integrity of the graph structure and eliminating the infinite loop.
- Problem: Responding to a
- Integrated PyCoder Node into the Conversational Flow.
- Problem: The
PyCoderNodewas architecturally treated as a terminal "tool" node, not a conversational participant. This prevented users from branching new replies from it, causing new messages to start a disconnected conversation instead. - Solution: The
PyCoderNodewas structurally upgraded to act as a proper conversational node.- It was given
children,conversation_history, andis_userattributes, making it compatible with the scene's branching logic. - The scene's node creation and connection logic was updated to recognize
PyCoderNodeas a valid parent. - The application's state management now correctly sets the
PyCoderNodeas the active context after execution, ensuring subsequent user messages correctly attach to it. - A secondary bug was fixed where
ConnectionItems would crash when trying to connect to aPyCoderNodedue to missingwidthandheightattributes; these were added to standardize the node's interface.
- It was given
- Result: This change ensures that the PyCoder tool is no longer a "dead end" in the conversation, allowing for a seamless and logical flow between text-based chat and code execution.
- Problem: The
- Resolved Critical
AttributeErroron Chat Loading and Rendering.- Problem: A crash occurred when loading a chat or rendering the
PyCoderNode's status tracker, caused by anAttributeError: unsupported keyword 'cap'. - Solution: The
QPenconstructor in theStatusIconWidget'spaintEventwas being called with unsupported keyword arguments. The code was refactored to first instantiate theQPenobject and then use its setter methods (setCapStyle,setJoinStyle) to configure it correctly, aligning with the PySide6 API and resolving the rendering crash. A similar error related topreviousSibling()was also fixed by using direct widget references.
- Problem: A crash occurred when loading a chat or rendering the
- Resolved Critical Circular Import Error on Launch.
- Problem: A circular dependency was introduced between high-level UI modules (
graphite_app.py,graphite_window.py) and lower-level modules (graphite_dialogs.py), preventing the application from launching. - Solution: Theme utility functions (
apply_theme,get_current_palette) were correctly moved from the high-levelgraphite_app.pymodule to the low-levelgraphite_config.pymodule, breaking the import cycle and restoring proper architectural layering.
- Problem: A circular dependency was introduced between high-level UI modules (
- Ensured PyCoder Node Conforms to All Graph Rules.
- Problem: The
PyCoderNodeand its connection did not respect scene-wide layout rules like "Snap to Grid," "Smart Guides," and "Orthogonal Connections." - Solution: The node's event handling was properly integrated with the scene's drag-and-drop lifecycle. It now correctly signals the start and end of a drag, allowing the scene to apply snapping and alignment logic. The
PyCoderConnectionItemwas also updated to check for and render in an orthogonal style when the mode is active.
- Problem: The
- Ensured UI Consistency Across All Components in Monochromatic Mode.
- Problem: Several UI elements retained their original colors when the monochromatic theme was enabled, creating a visually inconsistent experience. This included the send/attach buttons, minimap indicators, dialog windows, context menus, and the System Prompt note header.
- Solution: All custom
paintmethods and stylesheet definitions throughout the application were refactored to source their colors from the new centralColorPalette, making them fully theme-aware. Contrast-detection logic was also added to ensure icon and text colors remain legible on dynamic backgrounds.
- Resolved Critical
RuntimeErroron Scene Clearing and Chat Loading.- Problem: The application would crash with an
Internal C++ object already deletederror when clearing the scene to load a new chat. This was caused byQVariantAnimationobjects (used for pulsing effects onContainers andFrames) continuing to run after their parentQGraphicsItemwas destroyed. - Solution (Architectural): The root cause was twofold: animations were instantiated incorrectly, and their lifecycles were not managed during scene cleanup.
- The
QVariantAnimations were correctly re-instantiated without being parented to theQGraphicsItems (which are notQObjects). - The
itemChangemethod in bothContainerandFramewas corrected to reliably detect when an item is being removed from a scene (change == QGraphicsItem.ItemSceneHasChanged and value is None). - In this cleanup path, all active animations and timers (
pulse_animation,outline_animation,ghost_frame_timer,cursor_timer) are now explicitly stopped, preventing them from accessing deleted objects.
- The
- Problem: The application would crash with an
- Corrected "Ghost Frame" Positioning Logic.
- Problem: The initial implementation of the ghost frame appeared at an incorrect offset, as it was mixing the container's local coordinates with the scene's global coordinates.
- Solution: The positioning logic in the
_show_ghost_framemethod was rewritten. It now correctly uses the current global cursor position, maps it to scene coordinates, and then calculates the top-left corner of the preview to ensure it always appears perfectly centered on the user's cursor.
- Fixed Recursive Connection Bug with Nested Containers.
- Problem: If a
Framewas placed inside aContainer, moving the outerContainerwould not update the connections for the nodes inside the nestedFrame. - Solution: The
Container's_update_child_connectionsmethod was made recursive. It now uses a new helper method,_get_all_descendant_nodes, to traverse the entire hierarchy of nested items (including other Containers and Frames) to build a complete list of all nodes that require a connection update.
- Problem: If a
[Beta v.0.6.1] - 2025-11-01 (Container System & Connection Logic Overhaul)
This update introduces the Container, a powerful new organizational tool, alongside a critical overhaul of the scene's connection rendering logic. The new Container system allows for complex nesting of any canvas item, while the connection fixes ensure that all visual links behave predictably and consistently, especially when interacting with grouped or collapsed items. This lays a more robust architectural foundation for future layout and interaction features.
Added
- Introduced the "Container" Grouping System.
- Feature: A new, versatile grouping item that can contain any combination of other items on the canvas, including Chat Nodes, Notes, Charts, Frames, and even other Containers for deep nesting.
- Interaction:
- Creation: Select any items and press
Ctrl+Shift+Gor use the Command Palette. - Collapsible State: Containers can be collapsed into a compact, node-like object to hide their contents and simplify the graph view. A pulsing glow indicates that a container is collapsed and holds hidden items.
- Management: A dedicated header provides access to a collapse/expand button, a color picker for customization, and an editable title.
- Creation: Select any items and press
Fixed
- Resolved Critical Bug in Container Movement.
- Problem: When a
Containerwas moved, the connection lines for the items inside it did not update their positions, appearing visually "stuck" on the canvas. - Solution: The
itemChangemethod in theContainerclass was updated to correctly propagate position changes through the scene by callingscene.nodeMoved(). Its logic was aligned with the existingFrameclass to ensure consistent, predictable behavior across all grouping items.
- Problem: When a
- Overhauled Connection Logic for Collapsed Containers.
- Problem: Connections to or from items within a collapsed
Containerwould remain attached to the last known position of the invisible items, resulting in visually broken lines stretching across the canvas. Connections between two items inside the same collapsed container remained visible but disconnected. - Solution: The
update_pathmethod for all connection types (ConnectionItem,ContentConnectionItem, etc.) was overhauled. Connections now intelligently detect if their start or end node is within a collapsedContainer.- If an endpoint is hidden, the connection line now dynamically retargets its visual endpoint to the boundary of the
Containeritself. - If both endpoints of a connection are within the same collapsed container, the connection is now correctly hidden to reduce visual clutter.
- If an endpoint is hidden, the connection line now dynamically retargets its visual endpoint to the boundary of the
- Problem: Connections to or from items within a collapsed
- Corrected Connection Anchor Point Misalignment.
- Problem: A visual regression caused a small gap to appear between the start of a connection line and the edge of its source node or container.
- Solution: The issue was traced to an incorrect calculation that used the item's
boundingRect()(which can include padding) instead of its precise visual geometry. The connection logic was refined to calculate attachment points based on the item's core visual dimensions, ensuring a pixel-perfect alignment.
[Beta v.0.6.0] - 2025-11-01 (Navigational Minimap & Context-Aware Highlighting)
This release introduces a major new UI feature: the Navigational Minimap. This component provides a high-level, interactive "timeline" of the entire chat graph, enabling users to quickly assess the conversation's structure and jump to any point with a single click. To complement this, a new context-aware highlighting system has been implemented to help users maintain their orientation after navigating.
Architectural Refactor
- Decoupled the Minimap into a Standalone Module (
graphite_minimap.py).- Problem: The initial implementation of the
MinimapWidgetwas placed withingraphite_widgets.py, a general-purpose file. This made the code less modular and harder to maintain. - Solution: All code related to the
MinimapWidgethas been moved to a new, dedicatedgraphite_minimap.pyfile. This enforces a clear separation of concerns, improves project organization, and simplifies future development of the minimap feature. Thegraphite_view.pyfile was updated to import the widget from its new location.
- Problem: The initial implementation of the
- Introduced a
scene_changedSignal for Decoupled UI Updates.- Problem: UI components that depend on the scene's state (like the new minimap) previously had no efficient way to know when to refresh their content.
- Solution: A new
scene_changedsignal was added to theChatSceneclass. This signal is now emitted whenever a node is added, removed, moved, or when the layout is reorganized. TheMinimapWidgetconnects to this signal, allowing it to automatically and efficiently stay in sync with the canvas state without being tightly coupled to the scene's internal logic.
Added
- Implemented the Navigational Minimap Widget.
- Feature: A new, floating UI element now appears on the right side of the main view. It renders a compact, scrollable list of colored notches (green for user, blue for AI) representing every chat node in the conversation.
- Interaction:
- Hover-to-Preview: A 500ms hover delay on any notch reveals a tooltip with a preview of the corresponding node's text.
- Click-to-Navigate: Clicking a notch instantly centers the main view on that node.
- Scroll Navigation: Using the mouse wheel while hovering over the minimap scrolls through the list of nodes, with the widget displaying a "viewport" of up to 25 nodes at a time.
- Proximity Awareness: The minimap fades to a lower opacity when the cursor is far away and becomes fully opaque when the cursor is near, keeping it unobtrusive.
- Created a "Last Visited" Node Highlighter.
- Feature: When navigating via the minimap, the previously selected node is now highlighted with a distinct yellow dashed outline.
- Purpose: This provides an immediate visual anchor, allowing users to easily jump back to their previous point of focus after exploring another part of the chat graph. A new
is_last_navigatedflag was added to theChatNodeto manage this state.
Changed
- Optimized Minimap Rendering for Large Graphs.
- Problem: The initial minimap design mapped each notch's position directly to the node's scene coordinates, creating large gaps for spatially distant nodes.
- Solution: The rendering logic was completely redesigned. The minimap now treats the node list as a compact, ordered sequence. Notches are rendered with even spacing based on their index in the list, ensuring a neat, stacked appearance regardless of the actual node layout on the canvas.
[Beta v.0.5.9] - 2025-10-31 (Interactive Welcome Screen & Revamped Startup Experience)
This release fundamentally redesigns the application's startup sequence by introducing a dynamic Welcome Screen. This new dashboard serves as a central hub, providing immediate access to recent projects and an animated carousel of conversation starters to inspire users. The application flow has been re-architected to present this screen alongside the main ChatWindow, creating a more intuitive and powerful initial user experience.
Architectural Refactor
- Decoupled the Welcome Screen into a Dedicated Module.
- Problem: The
WelcomeScreenwas a high-level application component residing withingraphite_widgets.py, a file intended for low-level, reusable UI elements. This created tight coupling and circular import errors. - Solution: The
WelcomeScreenand its relatedStarterNodeWidgethave been moved to a new, dedicatedgraphite_welcome_screen.pyfile. This refactoring breaks the circular dependencies, improves modularity, and clarifies the architectural separation between foundational widgets and feature-specific windows.
- Problem: The
- Re-architected the Application Startup Flow.
- Problem: The previous startup sequence was linear: the
WelcomeScreenacted as a gatekeeper that would close before opening the main window. The desired behavior was for both windows to co-exist. - Solution: The logic in
graphite_app.pyhas been rewritten. It now instantiates both theChatWindowand theWelcomeScreenand passes them to theSplashScreen. After its timeout, theSplashScreenis now responsible for showing both windows, establishing the correct co-existing application state. TheWelcomeScreen's methods were updated to operate on the existingChatWindowinstance rather than creating a new one.
- Problem: The previous startup sequence was linear: the
Added
- Implemented an Infinitely Cycling "Conversation Starters" Carousel.
- Feature: The list of conversation starters on the Welcome Screen now scrolls automatically and infinitely from right to left.
- Implementation: To create a seamless loop, the list of starter nodes is duplicated within the
QHBoxLayout. AQTimeris used to incrementally advance the scrollbar's position at a regular interval. When the scroll position reaches the halfway point (the end of the original content), it is silently reset to the beginning, giving the illusion of an endless, continuous animation. The animation also intelligently pauses on mouse hover.
Changed
- Redesigned "Conversation Starter" Nodes for Visual Consistency and Readability.
- Problem: The starter prompts were implemented as standard
QPushButtons, which did not wrap text and were stylistically inconsistent with the application's core node-based UI. - Solution: The
QPushButtonwas replaced with a new customStarterNodeWidget. ThisQFrame-based widget is styled to visually mimic theChatNodefound in the main application, featuring a gradient background and a colored border. It contains aQLabelwithsetWordWrap(True)enabled, ensuring that all prompt text is fully visible and correctly formatted.
- Problem: The starter prompts were implemented as standard
- Expanded and Curated the List of Conversation Starters.
- Problem: The initial list of starter prompts was minimal.
- Solution: The number of prompts has been significantly increased to provide users with a much wider and more inspiring range of ideas to explore, from creative writing and technical questions to productivity and planning tasks.
- Simplified the Welcome Screen UI.
- Problem: The action buttons at the bottom of the
WelcomeScreen(New Chat,Open Library) were redundant, as these functions are readily available in the mainChatWindow. - Solution: The entire bottom button bar has been removed, resulting in a cleaner, more focused UI that prioritizes recent projects and conversation starters.
- Problem: The action buttons at the bottom of the
[Beta v.0.5.8] - 2025-10-31 (Professional Markdown Rendering & Font Customization)
This release introduces a complete overhaul of the text rendering system, replacing the limited custom parser with a professional, standards-compliant Markdown engine. A new Font Control panel has been added, giving users granular control over the typography of the entire canvas for the first time.
Architectural Refactor
- Replaced Custom Text Parsing with a Standard Markdown-to-HTML Pipeline.
- Problem: The previous system used a rudimentary parser for a few custom tags (e.g.,
[h1]), which was inflexible and did not support common Markdown syntax like multiple heading levels, blockquotes, or lists. - Solution: The rendering logic in
ChatNodehas been completely refactored. TheTextBlockand custom parsing functions have been removed. The node now utilizes the standardmarkdownlibrary to convert raw text into HTML, which is then rendered by aQTextDocument. A default CSS stylesheet is applied to the document, ensuring all HTML elements (<h1>,<p>,<ul>, etc.) are styled professionally and consistently.
- Problem: The previous system used a rudimentary parser for a few custom tags (e.g.,
Added
- Implemented a Global Font Control System.
- Feature: A new "Font" panel is now available under the "Controls" menu. This UI provides real-time control over the font family, base font size, and text color for all
ChatNodeandDocumentNodeitems on the canvas. - Implementation: A
FontControlwidget was created with signals for each setting. TheChatScenenow manages the global font state and contains new setter methods (setFontFamily,setFontSize,setFontColor). These methods, when triggered by the UI, call a new_update_all_node_fontsfunction that iterates through all relevant nodes and instructs them to re-render with the new styles.
- Feature: A new "Font" panel is now available under the "Controls" menu. This UI provides real-time control over the font family, base font size, and text color for all
Changed
- Node Architecture Updated to Support Dynamic Styling.
- Problem: Nodes were previously unaware of global style changes and would not update after being created.
- Solution: The
ChatNodeandDocumentNodeclasses now feature anupdate_font_settingsmethod, which rebuilds the node's stylesheet and recalculates its geometry. Furthermore, theitemChangemethod was overridden to detect when a node is added to the scene, immediately applying the scene's current font settings and ensuring style consistency for newly created nodes.
Fixed
- Resolved Critical Rendering Bugs Related to Recent Changes.
- Problem: A regression caused user-sent messages to appear as blank nodes. Additionally, a
QPainterstate error was logged due to improper rendering in the newDocumentNode. - Solution: The logic in
graphite_app.pywas corrected to ensure that simple text messages are passed to theChatNodeconstructor as a raw string, fixing the blank node issue. TheDocumentNode.paintmethod was corrected to usedocument.drawContents(), which properly manages the painter's state and resolves the rendering warning.
- Problem: A regression caused user-sent messages to appear as blank nodes. Additionally, a
[Beta v.0.5.7] - 2025-10-31 (Ollama Multimodal Support)
This release extends multimodal (text and image) input support to the local Ollama provider, enabling models like qwen3-vl:8b to process visual information. This brings feature parity with the Gemini API provider for a core interaction capability.
Architectural Refactor
- Decoupled Message Formatting from API Calls for Ollama.
- Problem: The
api_provider.chatfunction directly passed itsmessagesargument to theollama.chatcall, which only worked for text-based messages. It lacked the logic to handle the application's internal format for multimodal content (a list of dictionaries for text and image parts). - Solution: A new message preparation layer has been introduced specifically for the Ollama provider. Before making the API call, the
chatfunction now passes themessageslist to a new_prepare_ollama_messageshelper function. This function is responsible for transforming the internal message structure into the{'content': '...', 'images': [...]}format required by theollama-pythonlibrary, cleanly separating data transformation from the API interaction logic.
- Problem: The
Added
- Implemented a Dedicated Message Formatter for Ollama Multimodal Payloads.
- Feature: The new
_prepare_ollama_messagesfunction inapi_provider.pynow correctly processes mixed-content messages. It iterates through the content parts, aggregates all text into a single string for thecontentkey, and compiles all image byte data into a list for theimageskey. - Benefit: This enables seamless support for any multimodal Ollama model (e.g.,
llava,qwen3-vl:8b) without requiring model-specific logic. The system now automatically handles image data whenever it's present in a user's message, regardless of the selected Ollama model.
- Feature: The new
[Beta v.0.5.6] - 2025-10-30
This release delivers the first fully functional plugin, "System Prompt," which allows for dynamic, per-conversation customization of the AI agent's behavior. This milestone validates the new plugin architecture and introduces a powerful new layer of user control.
Architectural Refactor
- Integrated Node Context into AI Agent Logic for Dynamic System Prompts.
- Problem: The core
ChatWorkerwas stateless and unaware of the canvas, using a single, hard-coded system prompt for all interactions. - Solution: The
ChatWorkerandChatWorkerThreadhave been refactored to accept thecurrent_nodeas context. Before generating a response, the worker now traverses the node's hierarchy to find its root and checks for a connectedSystemPromptConnectionItem. If found, it uses the content of the attachedNoteas the system prompt for that specific API call, effectively overriding the default behavior for that entire conversation branch.
- Problem: The core
Added
- Implemented the "System Prompt" Plugin.
- Feature: Users can now add a special "System Prompt" node to any conversation branch via the "Plugins" menu. This node, a specially styled
Noteitem, allows the user to write custom instructions that override the default AI persona for that specific branch. - Implementation: A new
SystemPromptConnectionItemclass was created to visually and logically link aNoteto aChatNode. The plugin logic inPluginPortalhandles the creation of these items. The core AI agent logic ingraphite_agents.pywas then updated to detect and utilize these connections, creating a fully integrated and context-aware system.
- Feature: Users can now add a special "System Prompt" node to any conversation branch via the "Plugins" menu. This node, a specially styled
Changed
- Redesigned the System Prompt Connector for Professional Visual Feedback.
- Problem: The initial version of the
SystemPromptConnectionItemwas a visually jarring, static dashed line that did not update when nodes were moved. - Solution: The connector has been completely redesigned. It is now a smooth, S-shaped Bezier curve that dynamically updates its path when connected nodes are moved. A
QVariantAnimationwas added to create a subtle, continuous pulsing glow effect, visually signifying the flow of instructions from the prompt to the conversation, providing an elegant and intuitive user experience.
- Problem: The initial version of the
Fixed
- Resolved Multiple Critical Crashes Related to the New Plugin System.
- Problem: A
TypeErroroccurred becauseQVariantAnimationwas incorrectly parented to aQGraphicsItem. After fixing this, aRuntimeErrorwould occur because the animation was not being stopped when the connection item was deleted, leading it to call methods on a destroyed object. - Solution: The animation's constructor was corrected to be parentless. More importantly, the
itemChangemethod inSystemPromptConnectionItemwas overridden to detect when the item is being removed from the scene. It now explicitly calls.stop()on the animation, properly managing its lifecycle and preventing any further memory-related crashes.
- Problem: A
- Fixed a Bug Where System Prompt Connectors Would Not Update When Nodes Moved.
- Problem: The scene's update logic was not aware of the new
SystemPromptConnectionItemtype, causing the connectors to remain static when their attached nodes were moved. - Solution: The
ChatScene.update_connectionsmethod was updated to iterate over and updatesystem_prompt_connections. Additionally, theNote.itemChangemethod was modified to notify the scene of position changes, ensuring all attached connection types are correctly redrawn.
- Problem: The scene's update logic was not aware of the new
[Beta v.0.5.6] - 2025-10-30 (Canvas Interactivity and Alignment Overhaul)
This update introduces a suite of powerful canvas manipulation features, including grid snapping, smart alignment guides, and orthogonal connection routing. These tools provide users with granular control over node layout and improve the organization of complex graphs.
Architectural Refactor
- Centralized Snapping and Alignment Logic into
ChatScene.- Problem: Snapping behavior was previously implemented inconsistently within individual
QGraphicsItemclasses (Note,ChartItem), leading to code duplication and making it impossible to toggle globally. - Solution: All snapping and alignment logic has been removed from individual items and consolidated into a single, authoritative
snap_positionmethod withinChatScene. Movable items now delegate their position changes to this method, which intelligently applies grid snapping and smart guide alignment based on the user's settings.
- Problem: Snapping behavior was previously implemented inconsistently within individual
Added
- Implemented "Snap to Grid" Functionality.
- Feature: A new "Snap to Grid" checkbox in the "Controls" panel allows users to toggle grid snapping for all movable items. When enabled, dragging an item will cause it to snap to the nearest grid intersection.
- Introduced "Smart Guides" for Dynamic Alignment.
- Feature: When the "Smart Guides" checkbox is enabled, moving an item will now display temporary alignment lines. These guides appear when the item's edges or center align with other items on the canvas, enabling precise and intuitive layout adjustments.
- Added "Orthogonal Connections" Routing Option.
- Feature: A new "Orthogonal Connections" checkbox in the "Controls" panel switches the main
ConnectionItemrendering style. When enabled, connections are drawn as right-angled lines instead of curves, offering a more structured, schematic-like visual appearance.
- Feature: A new "Orthogonal Connections" checkbox in the "Controls" panel switches the main
Changed
- Expanded the "Controls" Panel with New Options.
- UI: The
GridControlwidget has been redesigned to include a new "Alignment & Routing" section, which houses the checkboxes for Snap to Grid, Smart Guides, and Orthogonal Connections. - Behavior: The "Controls" panel is now hidden by default on application startup to provide a cleaner initial workspace. The corresponding toolbar button's state is correctly set to
Falseon launch.
- UI: The
Fixed
- Resolved a Long-Standing Bug Causing a "Stuck" Panning Cursor.
- Problem: The panning cursor (a closed hand) would occasionally fail to revert to the default arrow cursor if the middle mouse button was released outside the application window.
- Solution: The
mouseMoveEventinChatViewnow includes a state-correction check. It verifies the actual mouse button state against the application's internal panning flag and forcibly resets the cursor if a discrepancy is detected, ensuring the UI state remains synchronized with user actions.
[Beta v.0.5.6] - 2025-10-30 (Axiom Demo Mode and Rate Limiting)
This update introduces "Axiom" mode, a pre-configured, rate-limited demonstration of the Gemini API. It allows all users, regardless of license status, to immediately test the application's cloud-based AI capabilities without needing their own API key.
Architectural Refactor
- Expanded the Licensing System to Manage Usage-Based Rate Limits.
- Problem: The
LicenseManagerwas only designed to track perpetual states like trial periods and license validity. It had no mechanism for tracking transient, usage-based metrics. - Solution: The
LicenseManager's persistent state file (session.dat) has been updated to include anaxiom_usageobject. This object tracks the number of API calls (count) and the start of a rolling 4-hour window (window_start). New methods (can_use_axiom,record_axiom_usage,get_axiom_reset_time_str) were added to manage this data, ensuring that rate limits are correctly enforced and reset.
- Problem: The
Added
- Introduced "Axiom" Mode for Instant API Access.
- Feature: A new "Axiom" option has been added to the mode selection dropdown. This mode utilizes a hard-coded developer API key for Gemini's
gemini-flash-latestmodel. - Implementation: The core
api_providerwas modified to recognize the "Axiom" provider type. When selected, it initializes the Gemini client with the developer key and routes all chat requests to the pre-configured model, bypassing the need for user-provided settings.
- Feature: A new "Axiom" option has been added to the mode selection dropdown. This mode utilizes a hard-coded developer API key for Gemini's
- Implemented a Non-Modal Notification Banner for UI Feedback.
- Feature: A custom
NotificationBannerwidget now provides unobtrusive feedback, such as rate-limit warnings. It animates up from the bottom of the window and automatically dismisses after a set duration. - Implementation: The
send_messageandregenerate_nodemethods inChatWindownow checklicense_manager.can_use_axiom()before proceeding. If the limit is reached, the new banner is displayed with a message indicating when the limit will reset, preventing a disruptiveQMessageBoxfrom appearing.
- Feature: A custom
Changed
- Separated User License Status from API Mode Functionality.
- Clarification: The Axiom mode's rate limit of 3 messages per 4 hours applies universally to all users. A user with a paid license who requires unlimited API access is expected to use the "API Endpoint" mode and provide their own key.
- Behavior: The "Settings" button in the toolbar is now disabled when Axiom mode is active, reinforcing that it is a pre-configured demo with no user-editable options.
[Beta v.0.5.5] - 2025-10-30
This release introduces a foundational plugin system and refines the main toolbar's visual design for a cleaner, more professional user experience. These changes create a scalable architecture for future features while improving the application's overall aesthetic.
Architectural Refactor
- Established a Decoupled Plugin Architecture with a Central
PluginPortal.- Problem: The application lacked a dedicated, scalable system for adding new tools or features, which would lead to code coupling and maintenance issues.
- Solution: A new
graphite_plugin_portal.pymodule was created, housing aPluginPortalclass. This class is responsible for discovering, managing, and executing all plugins. It acts as a clean architectural boundary, allowing new features to be added as self-contained "plugins" without modifying the core application logic. The main window instantiates the portal, providing a controlled context for plugins to interact with the application.
Added
- Added a "Plugins" Dropdown Menu to the Main Toolbar.
- Feature: A new "Plugins" menu now appears on the main toolbar, providing a centralized and user-accessible entry point for all integrated tools and extensions.
- Implementation: The
setup_toolbarmethod ingraphite_app.pywas updated to include aQComboBoxfor plugins. This dropdown is dynamically populated with a list of available plugins retrieved from thePluginPortal. Selecting an item triggers the execution of the corresponding plugin and resets the menu, creating an intuitive action-oriented experience.
Changed
- Refined Toolbar UI for a Cleaner, More Professional Aesthetic.
- Problem: The main toolbar buttons used solid background colors, which appeared dated and visually busy. Furthermore, the newly added "Plugins" menu was initially implemented as a
QToolButton, creating a visual inconsistency with the adjacentQComboBoxused for mode selection. - Solution: The stylesheets in
graphite_app.pyandgraphite_styles.pywere updated to give toolbar buttons a transparent background by default. Color is now used exclusively to provide feedback on hover, creating a minimalist and modern appearance. The "Plugins" menu was re-implemented as aQComboBoxto perfectly match the "Mode" selector, ensuring a visually cohesive and professional toolbar design.
- Problem: The main toolbar buttons used solid background colors, which appeared dated and visually busy. Furthermore, the newly added "Plugins" menu was initially implemented as a
[Beta v.0.5.4] - 2025-10-30
This release overhauls the canvas grid system, transforming it from a static background pattern into a dynamic, professional, and fully customizable visual tool. The new grid adapts to the user's zoom level and offers multiple styles for a personalized workspace.
Added
- Added Comprehensive Grid Customization Options.
- Feature: Users can now fully personalize the canvas grid. The
GridControlwidget has been expanded to include new options for changing the grid's visual style (Dots, Lines, or Cross) and its color, in addition to the existing size and opacity controls. - Implementation: The
GridControlwidget ingraphite_widgets.pywas updated with new UI buttons and state variables (grid_style,grid_color). ThedrawBackgroundmethod inChatViewnow reads these properties to render the grid accordingly.
- Feature: Users can now fully personalize the canvas grid. The
Changed
- Overhauled Grid Rendering to be Dynamic and Zoom-Aware.
- Problem: The previous grid was a simple, static dotted line pattern that did not adapt to the user's zoom level. This resulted in visual clutter when zoomed out and a lack of detail when zoomed in, creating an unprofessional appearance.
- Solution: The
drawBackgroundmethod inChatViewhas been completely rewritten. It now renders a multi-level grid with distinct "major" and "minor" lines. These lines intelligently appear and disappear at different zoom thresholds (LOD_MAJOR,LOD_MINOR), and their thickness scales appropriately. This provides a clean, professional-grade drafting experience that is always visually suitable for the current level of detail.
[Beta v.0.5.3] - 2025-10-30
This is a major stability and usability release that restores critical functionality, overhauls key UI components, and refactors core systems for improved modularity. The "Navigation Pins" panel has been completely re-architected into a true floating overlay, and the "Create Frame" feature has been robustly re-implemented.
Architectural Refactor
- Re-architected the "Navigation Pins" Panel as a True Floating Overlay.
- Problem: The
PinOverlaywas previously embedded directly into the main window's layout, permanently consuming screen real estate and creating an intrusive user experience. Its internal collapse logic was flawed and buggy. - Solution: The
PinOverlayhas been completely re-architected. It is now a child of theChatView, making it a true floating overlay that sits on top of the canvas. Its visibility is now controlled by a dedicated "Pins" button in the main toolbar, providing a global and reliable toggle. All internal collapse/expand logic has been removed in favor of this superior architecture.
- Problem: The
- Centralized Command Palette Functionality into a Dedicated Module.
- Problem: The logic for the command system was split between
graphite_core.py(forCommandManager) andgraphite_dialogs.py(forCommandPaletteDialog), hindering maintainability. - Solution: Both classes have been moved into a new, dedicated
graphite_command_palette.pymodule. This encapsulation improves modularity and simplifies future development of the command system.
- Problem: The logic for the command system was split between
Added
- Re-enabled "Create Frame" with a New Shortcut (
Ctrl+G) and Command Palette Integration.- Feature: Users can now once again create frames around selected nodes. This core organizational feature is accessible via the new
Ctrl+Gshortcut and is discoverable in the Command Palette (Ctrl+K) as "Create Frame From Selection." - Implementation: The feature was re-implemented using a global
QShortcut, which bypasses any potential event conflicts. The command was also registered with theCommandManager, with a corrected condition that makes it available whenever one or more nodes are selected.
- Feature: Users can now once again create frames around selected nodes. This core organizational feature is accessible via the new
Changed
- Redesigned and Resized the "Navigation Pins" Panel for Professionalism and Usability.
- Problem: The panel's visual design was inconsistent, too small to be functional, and lacked a conventional close button.
- Solution: The panel's styling has been meticulously updated to match the elegant, floating design of the
CommandPalette. Its default size has been significantly increased, and a dedicated "Close" button has been added to its header. This button correctly interacts with the main toolbar toggle via a signal-and-slot mechanism, ensuring a conventional and intuitive user experience.
Fixed
- Fixed a series of critical bugs that made the "Navigation Pins" panel unusable.
- Problem: The panel's internal collapse button would disappear, making it impossible to re-expand. After being re-architected, the new external close button would then cause a fatal
AttributeErrorcrash. - Solution: The entire flawed collapse mechanism was removed. The crash was resolved by implementing a proper signal-and-slot connection between the panel's "Close" button and the main window, fully decoupling the components and ensuring robust operation.
- Problem: The panel's internal collapse button would disappear, making it impossible to re-expand. After being re-architected, the new external close button would then cause a fatal
- Fixed a critical regression where the "Create Frame" feature was completely inaccessible.
- Problem: A shortcut conflict (
Ctrl+Fbeing reassigned to "Find") and an incorrect command palette condition made it impossible to create frames. - Solution: The conflicting event handler was removed, a new, unambiguous shortcut (
Ctrl+G) was assigned viaQShortcut, and the command's availability condition was corrected, fully restoring the feature.
- Problem: A shortcut conflict (
- Fixed a visual bug where
CodeNodeconnections would not update when moving a parentFrame.- Problem: When a
Framewas moved or resized, the dashed lines connectingCodeNodes would remain frozen in their original positions. - Solution: The
Frame.mouseMoveEventmethod was updated to correctly iterate through and update all connection types (connectionsandcontent_connections), ensuring all lines are redrawn properly during transformations.
- Problem: When a
- Fixed a fatal
ImportErrorcrash on startup.- Problem: The refactoring of the Command Palette into its own module was incomplete, as the main application was still trying to import classes from their old locations.
- Solution: All import statements in
graphite_app.pywere updated to correctly reference the newgraphite_command_palette.pymodule, resolving the crash.
[Beta v.0.5.1] - 2025-10-30
This release improves the user's ability to customize their workspace by adding a feature to toggle the visibility of on-canvas controls. It also resolves a critical UI layout bug that affected the application's initial appearance.
Added
- Added the Ability to Show/Hide On-Canvas View Controls.
- Feature: Users can now hide or show the on-canvas widgets for adjusting grid settings and drag sensitivity. This allows for a cleaner, less cluttered workspace when these controls are not needed.
- Implementation: A new checkable "Controls" button has been added to the main toolbar. This button is connected to a new
toggle_overlays_visibility()method in theChatViewclass, which manages the visibility of theGridControland drag sensitivity widgets. The layout logic was also updated to ensure other overlays (like the search bar) correctly reposition themselves when the controls are hidden.
Fixed
- Fixed a critical UI bug where view control widgets were incorrectly positioned at the top-left on startup.
- Problem: On initial application launch, the
GridControland drag sensitivity widgets would appear stacked at the(0,0)coordinate of the view instead of their correct top-right position. The layout would only correct itself after user interaction. - Solution: The root cause was identified as a layout timing issue. The initial positioning logic was being called before the
ChatViewhad received its final geometry from the main window. The fix involved overriding theshowEventmethod inChatView. This ensures that the initial positioning of the overlays is now performed only once, at the moment the view is first displayed and guaranteed to have a valid, stable size, resolving the visual bug completely.
- Problem: On initial application launch, the
[Beta v.0.5.0] - 2025-10-30
This release introduces a centralized "New Chat" command, improving accessibility and standardizing session management. This update also adds dynamic window titles for better user context and completes a robust refactoring of the session clearing logic.
Added
- Added a Universal "New Chat" Command and Shortcut (Ctrl+T).
- Feature: Users can now start a new chat session instantly from anywhere in the application, either by pressing the
Ctrl+Tkeyboard shortcut or by searching for "New Chat" in the command palette (Ctrl+K). - Implementation: The logic for creating a new chat has been centralized into a new
new_chat()method within the mainChatWindowclass. This method is now registered with theCommandManagerand linked to a newQShortcut, making it a globally accessible action.
- Feature: Users can now start a new chat session instantly from anywhere in the application, either by pressing the
Changed
- The Main Window Title is now Dynamic and Displays the Current Chat Name.
- Problem: The window title was static and did not provide context about the currently loaded chat session.
- Solution: A new
update_title_bar()method has been implemented inChatWindow. This method dynamically constructs the window title by combining the application name with the title of the current chat session (if one is loaded) and the license status. This method is now called whenever a new chat is created or an existing one is loaded, providing immediate and clear context to the user.
Architectural Refactor
- Centralized and Hardened the "New Chat" Session Clearing Logic.
- Problem: The original logic for starting a new chat was located within the
ChatLibraryDialogand was incomplete. It would clear the mainChatScenebut failed to reset other critical state variables and UI elements, such as thecurrent_nodereference, message input placeholder, and various lists within the scene (code_nodes,pins, etc.). - Solution: All session clearing logic has been consolidated into the new
ChatWindow.new_chat()method. This method now performs a comprehensive reset of the application state, including explicitly clearing all item lists within theChatScene, resetting thecurrent_nodereference in the main window, and updating the UI to its default state, ensuring a clean and reliable transition between sessions.
- Problem: The original logic for starting a new chat was located within the
[Beta v.0.4.9] - 2025-10-29
This release addresses critical bugs in the "Regenerate Response" feature and introduces a new, context-aware loading animation that significantly improves the user experience during AI operations.
Added
- Added a Contextual, Node-Specific Loading Animation.
- Feature: The previous full-screen, text-based loading overlay has been replaced with a visually appealing, animated spinner that appears directly next to the node awaiting a response. This provides clear, non-disruptive feedback, indicating exactly which part of the conversation is being processed.
- Implementation: A new
LoadingAnimationclass, inheriting fromQGraphicsObject, was created ingraphite_widgets.py. This class usesQPropertyAnimationto render a smooth, multi-arc spinning animation. The mainChatWindowlogic was refactored to instantiate this item on theChatSceneand position it adjacent to the source node whenever a background AI task (e.g., sending a message, regenerating, creating a chart) is initiated.
Fixed
- Fixed a critical logic error where "Regenerate Response" would fail due to missing context.
- Problem: The regeneration feature was incorrectly providing the model with the conversation history of the node being replaced, which lacked the essential preceding user query. This caused the model to have zero context, resulting in irrelevant or nonsensical regenerated responses.
- Solution: The logic in
ChatWindow.regenerate_node()has been corrected. It now correctly and robustly fetches theconversation_historyfrom the parent node of the node being regenerated. This ensures the model always receives the full and accurate conversational context, including the original query it needs to answer again.
- Fixed a fundamental architectural bug where regenerating a response would break its connection to the conversation branch.
- Problem: The previous implementation would delete the original node and create a new one, visually and contextually severing it from its place in the conversation graph.
- Solution: The regeneration logic has been completely re-architected. Instead of deleting and recreating the node, the
handle_regenerated_responsemethod now updates the existingChatNodein-place. A newupdate_contentmethod was added to theChatNodeclass to handle the replacement of its text, history, and associatedCodeNodes, fully preserving its position and connections within the graph.
- Fixed a fatal
TypeErrorcrash caused by an incorrect class inheritance in the newLoadingAnimation.- Problem: The
LoadingAnimationwas initially created by inheriting fromQGraphicsItem, which is not aQObjectsubclass and therefore cannot be animated withQPropertyAnimation, causing the application to crash. - Solution: The
LoadingAnimationclass was corrected to inherit fromQGraphicsObject, which is the proper Qt class for graphics items that require support for signals, slots, and properties, resolving the crash.
- Problem: The
- Fixed a
NameErrorcrash ingraphite_widgets.pydue to a missing import.- Problem: The
LoadingAnimationclass usedQRectFwithout importing it, causing a crash whenever it was instantiated. - Solution: The missing
QRectFclass has been added to the import statement fromPySide6.QtCore, resolving the error.
- Problem: The
[Beta v.0.4.8] - 2025-10-29
This release introduces a major new feature for handling and displaying code, significantly improving the user experience for developers and technical users. AI-generated responses containing code blocks are now automatically parsed and rendered in a dedicated, syntax-highlighted CodeNode, visually separating them from conversational text.
Added
- Added Automatic Code Block Detection and Syntax Highlighting.
- Feature: The application can now automatically detect markdown-style code blocks (e.g.,
```python...```) in AI responses. Each detected block is rendered in a new, specializedCodeNodewith full syntax highlighting, powered by thepygmentslibrary. This makes code significantly easier to read, understand, and copy. - Implementation:
- A new
CodeNodeclass was created ingraphite_node.py, which uses aQTextDocumentto render HTML generated bypygments, providing rich, styled text. - The
handle_responsemethod ingraphite_app.pywas updated with a regex-based parser to intelligently split incoming AI responses into separate text and code segments. - A new
ContentConnectionItemwas added tographite_items.pyto create a distinct visual link (a dashed line) between a parentChatNodeand its childCodeNode, clarifying their relationship. - The
ChatSessionManagerwas enhanced to serialize and deserialize the newCodeNodes and their connections, ensuring they are saved and loaded correctly with the chat graph.
- A new
- Feature: The application can now automatically detect markdown-style code blocks (e.g.,
Architectural Refactor
- Integrated
pygmentsfor Robust Syntax Highlighting.- Problem: Displaying code as plain text is difficult to read and unprofessional. A robust, extensible solution for code rendering was needed.
- Solution: The
pygmentslibrary has been integrated as a core dependency. A newCodeHighlighterutility class was added tographite_node.pyto abstract the highlighting logic. This class dynamically generates CSS and HTML from Python code, supporting a wide range of languages and providing a high-quality, professional rendering experience within the newCodeNode. The system is designed to fall back gracefully to plain text if a language is not specified or recognized.
[Beta v.0.4.7] - 2025-10-29
This release introduces the Command Palette, a major new usability feature that provides fast, keyboard-driven access to nearly all application functions. This update also includes a key architectural refactoring of item deletion logic, centralizing it to support the new command system and improve maintainability.
Added
- Added the Command Palette for Quick, Keyboard-Driven Actions (Ctrl+K).
- Feature: Users can now press
Ctrl+Kto open a searchable command palette, similar to those found in modern code editors. This provides instant, text-based access to a wide range of actions, such as "Collapse All Nodes," "Delete Selected Items," "Generate Bar Chart," and "Fit All to View," dramatically speeding up user workflow. - Implementation: The feature is powered by a new
CommandManagerclass (graphite_core.py) responsible for registering commands, their aliases, and context-sensitive availability (e.g., "Delete Selected" is only available when items are selected). A newCommandPaletteDialog(graphite_dialogs.py) provides the search UI, and the mainChatWindownow registers all core application functions as commands.
- Feature: Users can now press
Architectural Refactor
- Refactored and Centralized Item Deletion Logic.
- Problem: Previously, the logic for deleting different item types was fragmented across the codebase. The complex logic for deleting a
ChatNode(which involves re-parenting its children) was located exclusively within its context menu, making it non-reusable for a global "Delete Selected" command. - Solution: All deletion logic has been centralized within the
ChatSceneclass. TheChatNodedeletion algorithm was moved into a newdelete_chat_nodemethod. The primarydeleteSelectedItemsmethod was enhanced to iterate through all selected items and call the correct deletion function for each type (ChatNode,Frame,Note, etc.). This refactoring was essential for implementing the unified "Delete Selected Items" command in the new Command Palette.
- Problem: Previously, the logic for deleting different item types was fragmented across the codebase. The complex logic for deleting a
[Beta v.0.4.6] - 2025-10-29
This release introduces a powerful new usability feature for focusing on specific conversation paths and completes a significant architectural refactoring to improve modularity and resolve critical import errors.
Added
- Added "Hide Other Branches" Feature to Focus on Specific Conversations.
- Feature: Users can now right-click any node and select "Hide Other Branches" from the context menu. This action visually dims and de-emphasizes all nodes that are not part of the selected node's direct lineage (i.e., its ancestors and descendants). This allows users to instantly focus on a single, coherent line of thought within a complex, branching graph.
- Implementation: The feature is managed by a new state variable and a
toggle_branch_visibility()method within theChatSceneclass. When activated, the method traces the full path of the selected branch and sets anis_dimmedflag on all other nodes. The rendering logic inChatNodewas updated to draw a semi-transparent overlay when this flag is active. The context menu dynamically updates to "Show All Branches," allowing the user to easily restore the view.
Architectural Refactor
- Decomposed the monolithic
graphite_items.pymodule for improved modularity.- Problem: The
graphite_items.pyfile was responsible for both general-purpose canvas items (likeFrame,Note,Pin) and the highly complex, multi-componentChatNode. This violated the Single Responsibility Principle and made the codebase harder to navigate and maintain. - Solution: All classes directly related to the chat node functionality have been extracted into a new, dedicated
graphite_node.pyfile. This includesChatNode,TextBlock,ImageBlock,ScrollBar, andChatNodeContextMenu. This refactoring clarifies the separation of concerns, withgraphite_items.pynow serving as a library for generic canvas elements andgraphite_node.pyencapsulating all chat node logic.
- Problem: The
Fixed
- Fixed a fatal application crash (
ImportError) caused by a circular dependency.- Problem: The architectural refactoring inadvertently created a circular import loop where
graphite_node.pyimportedgraphite_items.py, which in turn importedgraphite_node.py, causing the application to crash on startup. - Solution: The unnecessary import of
ChatNodefromgraphite_items.pywas identified and removed. The classes withingraphite_items.pydo not need compile-time knowledge ofChatNode, as they operate on instances passed at runtime. Removing this import successfully broke the dependency cycle and restored application stability.
- Problem: The architectural refactoring inadvertently created a circular import loop where
[Beta v.0.4.5] - 2025-10-29
This release addresses several significant visual and architectural flaws within the ChatNode component that were introduced in the previous version. The primary focus was on creating a robust and permanent solution to the layout conflicts between the text content, the scrollbar, and the collapse/expand button, ensuring a clean and professional UI under all conditions.
Fixed
- Fixed a critical UI rendering bug where the collapse/expand button would overlap the text content.
- Problem: Previous attempts to fix the layout resulted in a state where, if a node's content was not long enough to require a scrollbar, the collapse button would be drawn directly on top of the text field.
- Solution: The rendering and layout architecture of the
ChatNodehas been fundamentally corrected. A permanent, reserved space ("gutter") is now established on the right side of every node. The text layout logic was updated to never enter this gutter, guaranteeing that its content can never overlap with UI controls. The button's positioning logic was then simplified to reliably place it within this safe, reserved area, resolving the conflict in all states.
- Fixed a major regression where the scrollbar would overlap the collapse button.
- Problem: An incorrect fix for the text overlap issue reintroduced the original bug where the scrollbar and collapse button would render on top of each other, making both components difficult to use.
- Solution: The
paintmethod was corrected to implement a strict, state-dependent positioning rule. It now explicitly checks if the scrollbar is visible. If it is, the button is placed to the left of the scrollbar; otherwise, it is placed at the far-right edge of the node. This dual-state logic ensures the two components can never occupy the same space.
- Fixed a fatal application crash (
QPainter::end: Painter ended with 2 saved states) and disappearing nodes.- Problem: An incorrect attempt to fix the rendering order led to a critical painter state imbalance, where
painter.save()was called without a correspondingpainter.restore(). This corrupted the Qt rendering pipeline, causing the application to crash andChatNodeitems to fail to render entirely. - Solution: The
paintmethod has been corrected to use a properly balancedpainter.save()/painter.restore()block. This block now safely encapsulates the clipping and drawing of the text content, ensuring the painter state is always correctly managed and preventing any rendering crashes or visual corruption.
- Problem: An incorrect attempt to fix the rendering order led to a critical painter state imbalance, where
[Beta v.0.4.4] - 2025-10-28
This release enhances canvas usability by introducing a node collapse feature, allowing users to manage complex conversation graphs more effectively. It also includes fixes for visual artifacts that appeared as a result of the new functionality.
Added
- Added Node Collapse/Expand Functionality.
- Feature: Users can now minimize nodes to a compact state, reducing visual clutter and making it easier to navigate large, branching conversations. This is a crucial tool for focusing on specific thought threads while hiding less relevant ones.
- Implementation: The
ChatNodeclass now manages ais_collapsedstate. The feature is accessible via two intuitive methods: a new "Collapse/Expand" option in the right-click context menu, and a hover-activated icon that appears in the top-right corner of the node for quick, direct interaction. When a node's state is changed, all associated connections and parent frames automatically adjust to the new geometry.
- Added Persistence for Node Collapse State.
- Feature: The collapsed or expanded state of every node is now saved with the chat session and is fully restored when the session is loaded.
- Implementation: The
ChatSessionManagerhas been updated to serialize theis_collapsedboolean for each node into the database and deserialize it upon loading, ensuring a consistent and predictable layout across sessions.
Fixed
- Fixed a critical UI bug where the scrollbar remained visible on collapsed nodes.
- Problem: When a node with scrollable content was collapsed, its scrollbar was not being hidden, leaving a detached and visually disruptive UI element on the canvas.
- Solution: The logic in the
ChatNode._update_geometry_for_state()method has been corrected to explicitly set theScrollBar's visibility toFalsewhenever the node enters a collapsed state, completely resolving the visual artifact.
[Beta v.0.4.3] - 2025-10-28
This is a minor release focused on improving the core visual aesthetic of the application's chat canvas, moving from a flat design to one with more perceived depth and professionalism.
Changed
- Enhanced the visual design of
ChatNodeitems for a more professional aesthetic.- Problem: The previous design used solid, flat colors (green and blue) for the node backgrounds. While functional, this created a visually simplistic and less polished look.
- Solution: The node's rendering logic in the
ChatNode.paint()method has been updated. The solid color fill has been replaced with a subtle gray gradient, giving the nodes a sense of depth. The node's origin (user or AI) is now indicated by a colored outline (green for user, blue for AI) rather than the entire background, resulting in a cleaner and more professional appearance.
[Beta v.0.4.2] - 2025-10-27
This release completes the major UI overhaul by standardizing all window frames across the application, resulting in a more professional and cohesive user experience. The focus was on eliminating custom, non-native windowing solutions in favor of robust, OS-level implementations.
Changed
- Unified the Main Window and all Dialogs to use Native OS Window Frames.
- Problem: The main application window and several key dialogs (
Library,Help,About,Activation) were using a custom, frameless implementation that required significant boilerplate code to replicate basic window functions. This created a visual and functional disconnect from standard dialogs and lacked the robustness of native window management. - Solution: All custom frameless window implementations have been removed and replaced with standard, native window frames. The
CustomTitleBarclass is now obsolete, and all windows now leverage the host operating system's window manager for a consistent look, feel, and behavior (including features like window snapping and native shadows).
- Problem: The main application window and several key dialogs (
- Improved User Help Dialog Content.
- Problem: The descriptions in the "Help" dialog were overly brief and often failed to explain how or why a feature should be used, limiting their value for new users.
- Solution: All help text has been rewritten to be more detailed, descriptive, and action-oriented. The new content provides clear, step-by-step instructions, explains core application concepts (like "Contextual Replies"), and includes keyboard shortcuts to improve feature discovery and user onboarding.
Fixed
- Fixed a critical bug where the native close ("x") button was disabled on all refactored windows.
- Details: The process of removing the custom frameless hints inadvertently dropped the
WindowCloseButtonHintflag, causing the window manager to disable the close button. This flag has been explicitly re-added to the main window and all refactored dialogs, restoring essential functionality.
- Details: The process of removing the custom frameless hints inadvertently dropped the
- Fixed an architectural flaw by relocating the main window icon logic.
- Details: The application's primary icon was being incorrectly set from within the now-obsolete
CustomTitleBarclass. This logic has been moved to the mainChatWindow's__init__method, where it properly belongs.
- Details: The application's primary icon was being incorrectly set from within the now-obsolete
[Beta v.0.4.1] - 2025-10-27
This release is a continuation of the major architectural refactoring initiated in the previous version. The focus was to dismantle the large graphite_graphics.py file, further improving modularity and clarifying the separation between UI components.
Architectural Refactor
- Decomposed the monolithic
graphite_graphics.pymodule.- Problem: Following the initial UI refactor, the
graphite_graphics.pymodule remained overly large, containing both the individual graphical items (ChatNode,Frame,Note) and the container classes that manage them (ChatScene,ChatView). This co-location of distinct responsibilities hindered clarity and maintainability. - Solution: The single file has been broken down into two new, more focused modules, establishing a clearer hierarchy between the view and its contents:
graphite_items.py: This module now exclusively contains allQGraphicsItemsubclasses. These classes represent the individual, interactive elements on the canvas (ChatNode,ConnectionItem,Frame,Note,ChartItem,NavigationPin, etc.).graphite_view.py: This module houses the container classes (ChatSceneandChatView), which are responsible for managing, displaying, and orchestrating interactions with the graphical items.
- Problem: Following the initial UI refactor, the
Fixed
- Fixed a critical
ImportErrorcrash caused by a circular dependency.- Details: The refactoring process inadvertently created a circular import loop:
graphite_widgetsimportedgraphite_items, which importedgraphite_dialogs, which in turn importedgraphite_widgets, causing the application to crash on startup. The issue was resolved by restoring a "dummy class" forward declaration forNavigationPinwithingraphite_widgets.py, successfully breaking the import cycle.
- Details: The refactoring process inadvertently created a circular import loop:
[Beta v.0.4.0] - 2025-10-27
This release introduces a major architectural refactoring of the user interface layer. The primary goal was to dismantle the monolithic graphite_ui.py file to improve modularity, resolve circular dependency issues, and enhance long-term maintainability.
Architectural Refactor
- Decomposed the monolithic UI module.
- Problem: The
graphite_ui.pyfile had grown to include over 25 distinct classes, mixing responsibilities such as styling, core widgets, dialogs, and complex graphics scene items. This made the code difficult to navigate, debug, and maintain. - Solution: The single file has been broken down into four new, single-responsibility modules:
graphite_styles.py: Centralizes theStyleSheetclass and color constants.graphite_widgets.py: Contains reusableQWidgetsubclasses likeCustomTitleBar,LoadingOverlay, andPinOverlay.graphite_dialogs.py: Consolidates allQDialog-based classes.graphite_graphics.py: Contains all coreQGraphics...components, including custom items, theChatScene, and theChatView.
- Problem: The
Fixed
- Fixed multiple critical
ImportErrorcrashes that arose during the refactoring process.- Details: Resolved errors caused by incorrect import paths for Qt classes.
QActionwas moved fromQtWidgetsto its correct module,QtGui. The classQGraphicsPathStrokerwas corrected to its proper name,QPainterPathStroker, fixing both the import and its usage within theConnectionItemclass.
- Details: Resolved errors caused by incorrect import paths for Qt classes.
- Fixed a
TypeErrorcrash related to the Frame animation.- Details: The
valueChangedsignal of theQVariantAnimationused for the frame's selection outline was incorrectly connected to theQGraphicsItem.updatemethod, passing an unexpected argument. This was resolved by using alambdafunction to ensure the method is called without arguments, stopping the crash loop.
- Details: The
[Beta v.0.3.0] - 2025-10-27
This release transitions the application from a purely functional prototype to a distributable product by introducing a robust licensing and user agreement framework. The primary focus is on ensuring a professional first-run experience, protecting the software with a trial period, and providing clear developer attribution.
Added
- Added a 5-Day Trial and Licensing System.
- Feature: The application now operates in a fully-featured demo mode for 5 days from the first launch. After the trial period expires, the user must enter a valid license key to continue using the software.
- Implementation: A new
graphite_licensing.pymodule has been created to manage all licensing logic. It creates a persistent state file (~/.graphite/session.dat) to securely track the first launch date, EULA acceptance, and activation status. The main application startup sequence ingraphite_app.pyhas been modified to enforce these checks before the main window is launched.
- Added a Mandatory End-User License Agreement (EULA).
- Feature: On the very first launch, users are now presented with a modal EULA dialog. The application will not run unless the user scrolls to the bottom and explicitly agrees to the terms, which include a disclaimer of warranty and a liability clause for generated content.
- Implementation: A new
EULADialogwas created ingraphite_ui.pywith logic to ensure full review of the text. TheLicenseManagertracks the acceptance state, preventing the app from running until the EULA is accepted.
- Added an "About" Dialog and Developer Credits.
- Feature: A new "About" dialog is now accessible from the main toolbar, providing users with application version info, developer credits (name, contact), and a direct link to the project's GitHub repository. It also clearly displays the current license status (Trial, Licensed, or Expired).
- Implementation: An
AboutDialogclass was added tographite_ui.pyand integrated into theChatWindowtoolbar.
- Added an In-App Activation Dialog.
- Feature: Users can now activate their software from within the application using a dedicated "Activate" dialog, which appears automatically when the trial expires or can be accessed from the toolbar.
- Implementation: The
ActivationDialogclass ingraphite_ui.pyprovides an interface for key entry and validation against the logic ingraphite_licensing.py.
Changed
- The Main Window Title is now dynamic and reflects the license status. The title bar will display "Graphite (Trial - X days remaining)" during the trial period and "Graphite (Licensed)" after successful activation, providing clear and persistent feedback to the user.
- The main toolbar has been updated to include buttons for the new "About" and "Activate" dialogs, making these features easily accessible.
Fixed
- Fixed a bug in the EULA dialog where the "Agree" button would remain disabled if the agreement text was too short to require scrolling. The logic was corrected to enable the button immediately if the content is fully visible upon opening, ensuring a smooth user experience regardless of screen resolution or content length.
[Beta v.0.2.2] - 2024-05-25
This release introduces support for any OpenAI-compatible API endpoint as an alternative to a local Ollama instance. It also includes a significant user experience overhaul for model and provider selection, resolving critical design flaws and improving usability.
Added
- Added support for OpenAI-Compatible API Endpoints.
- Feature: Users can now switch from using a local Ollama instance to any remote API service that is compatible with the OpenAI API specification (e.g., OpenAI, Groq, OpenRouter, or self-hosted solutions like LiteLLM). (Credits for first conceptual buildout/iteration of implimentations - https://github.com/1818TusculumSt)
- Implementation: A new
api_provider.pymodule was created to act as a router, abstracting all LLM calls and directing them to either Ollama or the configured API endpoint based on the user's selection. All agent classes (ChatAgent,KeyTakeawayAgent, etc.) were refactored to use this new provider instead of callingollamadirectly.
- Added Per-Task Model Configuration for API Mode.
- Feature: When using an API provider, users can configure different models for different tasks (Title Generation, Chat/Analysis, and Chart Data Extraction) to optimize for cost, speed, and capability.
- Implementation: An
APISettingsDialogwas created, allowing users to enter their API credentials, load a list of available models from the endpoint, and assign a specific model to each task category.
Changed
- Overhauled the Model and Provider Selection UX.
- Problem: The previous UI design for model selection was confusing, with separate and sometimes hidden buttons for different providers. This created a frustrating and non-discoverable user experience.
- Solution: The toolbar has been redesigned with a clear, two-part system:
- A "Mode" dropdown to explicitly select the provider (
Ollama (Local)orAPI Endpoint). - A single, consistently visible "Settings" button. This button is now context-aware and will open the appropriate configuration dialog (
ModelSelectionDialogfor Ollama orAPISettingsDialogfor an API) based on the currently selected mode. This resolves all ambiguity and makes the feature intuitive to use.
- A "Mode" dropdown to explicitly select the provider (
Fixed
- Fixed a critical UI bug where the API settings button was permanently invisible.
- Problem: A logic error in the toolbar setup (
self.api_settings_btn.setVisible(False)) caused the button to configure the API to be hidden, making the entire feature inaccessible. - Solution: The erroneous line was removed, and the toolbar was refactored to use the new unified "Settings" button, ensuring the correct dialog is always accessible.
- Problem: A logic error in the toolbar setup (
- Fixed an architectural violation where UI components were defined outside of
graphite_ui.py.- Problem: The
APISettingsDialogwas incorrectly defined within the main application file (graphite_app.py), breaking the project's modular structure. - Solution: The
APISettingsDialogclass has been moved to its proper location withingraphite_ui.py, restoring the architectural integrity and separation of concerns.
- Problem: The
[Beta v.0.2.1] - 2024-05-25
This release focuses on critical stability and functionality fixes, primarily addressing issues within the API provider integration and the core UI rendering system.
Fixed
- Fixed a critical application crash when loading models from the Google Gemini API.
- Problem: The application would crash with a
TypeErrorwhen fetching the model list from Gemini. A deep-dive analysis revealed this was due to a fundamental incompatibility between the installedgoogle-generativeailibrary and the current data structure of the API's response. The previous design, which relied on dynamic model discovery, proved to be too brittle for this provider. - Solution: The architecture for the Gemini provider has been completely refactored. The brittle dynamic discovery process has been removed and replaced with a static, hard-coded list of known-stable Gemini models. The API Settings UI now intelligently adapts, hiding non-functional controls (e.g., "Load Models") for the Gemini provider and populating the model list instantly and reliably.
- Problem: The application would crash with a
- Fixed a critical logic error preventing chat messages from being sent to Gemini models.
- Problem: After successfully configuring a Gemini model, all chat attempts would fail with an "Error: message cannot be blank."
- Solution: The root cause was identified in the
api_provider.chat()function, where apop()operation was incorrectly removing the user's current message from the conversation history before the payload was sent to the API. This line has been removed, ensuring the complete and correct conversation context is now sent with every request.
- Fixed a fatal application crash on startup due to incorrect UI class definition order.
- Problem: A regression from a previous refactor caused the application to crash on launch with an
ImportErrorand underlyingNameErrorexceptions. Classes withingraphite_ui.py(e.g.,ColorPickerDialog,ConnectionItem) were being referenced before they were defined, halting the module loading process. - Solution: The class definitions within
graphite_ui.pyhave been meticulously reordered to ensure a correct, top-to-bottom dependency resolution. All classes are now defined before they are instantiated or referenced, resolving the startup crash.
- Problem: A regression from a previous refactor caused the application to crash on launch with an
- Fixed a fatal UI rendering crash related to the
ChartItemclass.- Problem: The application would enter a crash loop during the UI paint event, raising an
AttributeErrorfor a non-existentQPainter.RenderHint(HighQualityAntialiasing). - Solution: The erroneous line has been removed from the
ChartItem.paint()method. Rendering quality is preserved by other existing and correct render hints (SmoothPixmapTransform), and the crash is fully resolved.
- Problem: The application would enter a crash loop during the UI paint event, raising an
Changed
- Updated the static model list for the Google Gemini provider.
- The hard-coded list of Gemini models was updated to include the latest stable releases available through the public API, including the
gemini-2.5-proandgemini-2.5-flashseries, ensuring users have access to current and powerful models.
- The hard-coded list of Gemini models was updated to include the latest stable releases available through the public API, including the
[Beta v.0.2.0] - 2024-05-23
Architectural Refactor
- This update introduces a major architectural refactoring to improve the project's structure, maintainability, and scalability. The application has been transitioned from a single, monolithic script into a modular, multi-file structure with a clear separation of concerns. The primary goal of this refactor was to decouple the User Interface, Core Logic, and AI Agent services from one another.
- The new project structure is as follows:
graphite_app.py: Serves as the main application entry point. It contains the primaryChatWindowclass and is responsible for initializing and launching the application.graphite_ui.py: Consolidates all classes related to the User Interface layer. This includes all Qt widgets, dialogs, custom graphics items for the scene (ChatNode,ConnectionItem,Frame, etc.), and view components (ChatView,ChatScene).graphite_core.py: Manages the application's core logic and data persistence. It contains theChatDatabaseclass for all SQLite operations and theChatSessionManagerfor handling the serialization and deserialization of chat sessions.graphite_agents.py: Isolates all logic related to AI model interaction. This module contains the baseChatAgentas well as specialized tool agents (KeyTakeawayAgent,ExplainerAgent,ChartDataAgent) and their correspondingQThreadworkers for asynchronous processing.graphite_config.py: A centralized location for application-wide configuration constants, such as task identifiers and default model names.api_provider.py: A dedicated module to abstract away the differences between various AI providers (Ollama, OpenAI-compatible, Google Gemini), presenting a unified interface to the rest of the application.