Living navigation document for the Graphite / Graphlink codebase.
Primary goal: give future work a reliable, current map of where behavior actually lives so we do not need to re-discover the repo from scratch every session.
Last refreshed: 2026-04-07
- Product name in the UI:
Graphlink - Repo / module naming in code:
Graphite - Code root:
graphite_app/ - Startup project:
graphite_app/graphite_app.pyproj - Solution file:
graphite_app.sln - Python files under
graphite_app/excluding__pycache__:107 - Top-level Python modules under
graphite_app/:55 - Real package directories with
__init__.py:6graphite_canvas/(8Python files)graphite_nodes/(11Python files)graphite_plugins/(10Python files)graphite_session/(9Python files)graphite_ui_dialogs/(4Python files)graphite_widgets/(10Python files)
- Runtime modes exposed in the shell:
Ollama (Local)Llama.cpp (Local)API Endpoint
- Runtime persistence outside the repo:
- chats database:
~/.graphlink/chats.db - settings/session state:
~/.graphlink/session.dat
- chats database:
- Hardcoded repo-local asset paths still exist in UI code:
C:\Users\Admin\source\repos\graphite_app\assets\graphite.icoC:\Users\Admin\source\repos\graphite_app\assets\check.pngC:\Users\Admin\source\repos\graphite_app\assets\down_arrow.png
If you need to rebuild the mental model quickly, open files in this order:
graphite_app/graphite_app.pygraphite_app/graphite_window.pygraphite_app/graphite_window_actions.pygraphite_app/api_provider.pygraphite_app/graphite_ui_dialogs/graphite_settings_dialogs.pygraphite_app/graphite_scene.pygraphite_app/graphite_session/manager.pygraphite_app/graphite_session/serializers.pygraphite_app/graphite_session/deserializers.pygraphite_app/graphite_session/scene_index.pygraphite_app/graphite_plugins/graphite_plugin_portal.pygraphite_app/graphite_memory.pygraphite_app/graphite_lod.py
That path shows boot, shell ownership, provider/mode initialization, live settings UI, scene authority, persistence, schema indexing, plugin registration, branch-memory rules, and the shared zoom-based render fallback system.
- Root modules still import each other by top-level names such as
from graphite_window import ChatWindow. - The split packages are real, but the running app is not yet a clean package-first namespaced design.
- Compatibility wrappers still matter because much of the repo enters package code through those top-level modules.
- Concrete implementations increasingly live in
graphite_nodes/,graphite_canvas/,graphite_plugins/,graphite_session/,graphite_ui_dialogs/, andgraphite_widgets/. - Top-level wrappers still preserve import stability.
- When both a wrapper and a concrete package module exist, edit the concrete package module unless you are intentionally changing the import surface.
graphite_config.pydefines task keys and user-facing mode labels.graphite_licensing.pypersists per-mode settings, scan caches, update-check state, and current mode.graphite_ui_dialogs/graphite_settings_dialogs.pyis the live configuration surface for Ollama, Llama.cpp, API providers, integrations, and update controls.graphite_window.pyowns startup mode initialization and toolbar mode switching.api_provider.pyis the real execution authority for:- Ollama local runtime
- direct
llama-cpp-pythonGGUF runtime - OpenAI-compatible endpoints
- Gemini endpoints
- The app scans for
.gguffiles directly. - Settings persist:
- chat model path
- optional title model path
- chat format override
n_ctxn_gpu_layersn_threads
- Ollama manifests/blobs are not valid
Llama.cppmodel files in this mode. - Graphlink intentionally defers GGUF loading until the first request instead of blocking mode switching or Save Settings.
graphite_window.pystages image, document, and audio attachments.graphite_window_actions.pyturns:- image attachments into
ImageNode - document attachments into
DocumentNode - audio attachments into
DocumentNodewithattachment_kind='audio'
- image attachments into
graphite_audio.pyvalidates audio files, MIME types, duration limits, and preview labels.graphite_nodes/graphite_node_document.pyis now the live UI for both document and audio attachment nodes.- Graphlink-level limitation:
Llama.cpplocal mode is text-only inside the app right now- Ollama and Gemini are the multimodal paths for audio or image-backed requests
graphite_scene.pystill owns the live runtime lists and creation/deletion behavior.graphite_session/serializers.pyandgraphite_session/deserializers.pystill decide save/load compatibility.graphite_session/scene_index.pynow centralizes:- node list names
- save-guard node list names
- child-link-capable node types
- serializer/deserializer item indexing helpers
- If you add a new persisted node family, update all three places:
graphite_scene.pygraphite_session/scene_index.py- session serializer/deserializer code
graphite_lod.pyowns zoom thresholds, summary/glyph fallback rendering, preview text helpers, and proxy visibility rules.- Many node UIs now rely on it for readable zoomed-out behavior instead of each node hand-rolling its own fallback.
- If a node looks wrong when zoomed out,
graphite_lod.pyis usually as important as the node class itself.
graphite_widgets/loading_visuals.pynow owns the shared orbital spinner painting used by both the splash and loading overlays.graphite_update.pyplusgraphite_version.pyown the update-check signal and local version metadata.
graphite_dialogs.pyduplicates canvas dialog classes but does not appear to be the live authority.graphite_widgets/pins.pydefines overlay-sideNavigationPin;graphite_canvas/graphite_canvas_navigation_pin.pydefines the persisted scene item with the same name.graphite_widgets/*.pystill use UTF-8 BOM in places; direct parsing tools should be BOM-aware.
graphite_app/graphite_app.pymain()- Creates
QApplication, loads persisted settings, applies theme/model, createsChatWindow,WelcomeScreen, andSplashScreen.
graphite_app/graphite_window.pyChatWindow- Main shell, toolbar, document viewer panel, pin overlay, mode switching, update checks, plugin picker, attachment staging, shortcuts, and session lifecycle.
graphite_app/graphite_window_actions.pyWindowActionsMixin- Core prompt send flow, attachment packing, response parsing, regeneration, charts, images, and all plugin execution entry points.
graphite_app/graphite_window_navigation.pyWindowNavigationMixin- Command registration, collapse/expand/delete/focus commands, note creation, directional navigation, command palette.
graphite_app/graphite_command_palette.pyCommandManager,CommandPaletteDialog- Searchable command palette.
graphite_app/graphite_update.pyUpdateCheckWorker, version comparison helpers, update-signal fetch.
graphite_app/graphite_version.pyAPP_VERSION
graphite_app/graphite_view.pyChatViewQGraphicsViewwrapper, panning/zooming, drag-and-drop attachments, overlay widgets, minimap mounting, background grid, keyboard pan.
graphite_app/graphite_scene.pyChatScene- Node registries, connection registries, node creation helpers, search, frame/container/note/chart creation, delete logic, branch visibility, font propagation.
graphite_app/graphite_connections.py- Core connection families and shared pin/path behavior.
graphite_app/graphite_minimap.pyMinimapWidget- Graph overview and jump navigation.
graphite_app/graphite_lod.py- Shared level-of-detail thresholds, preview text helpers, zoom-aware proxy visibility, and fallback card painting.
graphite_app/graphite_session/- Concrete persistence package.
- Key files:
content_codec.py,database.py,deserializers.py,manager.py,scene_index.py,serializers.py,title_generator.py,workers.py
graphite_app/graphite_core.py- Compatibility facade for session persistence.
graphite_app/graphite_memory.py- Branch-memory utilities; do not hand-roll history mutation when these helpers already exist.
graphite_app/graphite_file_handler.py- Attachment readability checks and text extraction for plain text, code, PDF, and DOCX.
graphite_app/graphite_audio.py- Audio validation, duration probing, MIME inference, and duration formatting.
graphite_app/graphite_exporter.py- Export helpers used by node context menus.
graphite_app/api_provider.py- Provider/runtime abstraction for Ollama, direct Llama.cpp, OpenAI-compatible APIs, and Gemini.
- Also owns local model scanning:
- Ollama manifest scanning
- GGUF scanning for
Llama.cpp
- Also owns modality handling rules and local runtime initialization.
graphite_app/graphite_prompts.py- Global prompt text and token-safe JSON encoding helpers.
graphite_app/graphite_config.py- Task keys, mode labels, local provider constants, theme palette getters, semantic colors, current model assignment.
graphite_app/graphite_licensing.pySettingsManager- Persisted user settings:
- theme
- welcome screen
- token counter
- system prompt toggle
- current runtime mode
- Ollama model settings and scan cache
- Llama.cpp GGUF settings and scan cache
- API endpoint/provider settings
- GitHub token
- update-check state
graphite_app/graphite_styles.py- QSS themes and shared palette definitions.
graphite_app/graphite_ui_components.pyNotificationBanner,DocumentViewerPanel,CustomTitleBar
graphite_app/graphite_welcome_screen.pyWelcomeScreen, starter templates, recent chats.
graphite_app/graphite_ui_dialogs/graphite_library_dialog.pyChatLibraryDialog
graphite_app/graphite_ui_dialogs/graphite_settings_dialogs.py- Real settings surface.
- Key sections:
AppearanceSettingsWidgetOllamaSettingsWidgetLlamaCppSettingsWidgetApiSettingsWidgetIntegrationsSettingsWidgetSettingsDialog
graphite_app/graphite_ui_dialogs/graphite_system_dialogs.pyHelpDialog,AboutDialog
graphite_app/graphite_widgets/loading_visuals.py- Shared spinner painter for splash and overlay loading states.
graphite_app/graphite_agents.py- Broad facade used by shell and settings code.
graphite_app/graphite_agents_core.py- Standard chat, explainer, takeaway, and group-summary agents plus worker threads.
graphite_app/graphite_agents_tools.py- Chart data extraction/repair, image generation, model pull workers.
graphite_app/graphite_agents_pycoder.py- Python REPL, execution/repair/analysis agents, Py-Coder workers.
graphite_app/graphite_agents_code_sandbox.py- Virtualenv sandbox, generation/repair agents, isolated execution worker.
graphite_app/graphite_agents_web.py- Search/fetch/validate/summarize worker for the web node.
graphite_app/graphite_agents_reasoning.py- Multi-step reasoning workflow and worker thread.
chatcodedocumentimagethinkingpycodercode_sandboxwebconversationreasoninghtmlartifactworkflowgraph_diffquality_gatecode_reviewgitlink
documentnodes now carry both normal file attachments and audio attachments.- Audio-backed
documentnodes persist extra fields such as:attachment_kindfile_pathmime_typeduration_secondsbyte_sizepreview_label
- frames
- containers
- notes
- charts
- navigation pins
connectionscontent_connectionsdocument_connectionsimage_connectionsthinking_connectionssystem_prompt_connectionspycoder_connectionscode_sandbox_connectionsweb_connectionsconversation_connectionsreasoning_connectionsgroup_summary_connectionshtml_connectionsartifact_connectionsworkflow_connectionsgraph_diff_connectionsquality_gate_connectionscode_review_connectionsgitlink_connections
graphite_app/graphite_app.py:main()graphite_licensing.SettingsManager()graphite_config.apply_theme()graphite_config.set_current_model()graphite_window.ChatWindowChatWindow._initialize_saved_mode_on_startup()- Mode-specific initialization goes through
api_provider.initialize_local_provider()orapi_provider.initialize_api() graphite_welcome_screen.WelcomeScreengraphite_widgets.SplashScreen
graphite_window.ChatWindow._initialize_mode()- If
Ollama (Local):api_provider.initialize_local_provider(config.LOCAL_PROVIDER_OLLAMA)
- If
Llama.cpp (Local):- settings come from
SettingsManager.get_llama_cpp_settings() api_provider.initialize_local_provider(config.LOCAL_PROVIDER_LLAMACPP, ..., preload_model=False)
- settings come from
- If
API Endpoint:- provider/model settings come from
SettingsManager api_provider.initialize_api(...)
- provider/model settings come from
- The settings flyout mirrors these same seams in
graphite_ui_dialogs/graphite_settings_dialogs.py
WindowActionsMixin.send_message()graphite_memory.resolve_branch_parent()andget_node_history()ChatScene.add_chat_node()creates the user node- Pending attachments are expanded:
- images become
ImageNode - documents become
DocumentNode - audio becomes
DocumentNodewith audio metadata
- images become
trim_history()bounds the context windowChatWorkerThreadruns the agent requestapi_provider.chat()executes the chosen runtime pathWindowActionsMixin.handle_response()parses plain text, code blocks, and thinking blocksChatScene.add_chat_node(),add_code_node(), andadd_thinking_node()create result structureChatWindow.save_chat()persists the updated graph
ChatWindow.save_chat()ChatSessionManager.save_current_chat()SceneSerializer.serialize_chat_data()graphite_session.scene_indexsupplies node list and indexing helpersChatDatabase.save_chat()orupdate_chat()- Notes and pins are stored in dedicated SQLite tables
SceneDeserializer.restore_chat()recreates nodes first, then notes/charts/frames/containers, then connections, then pins
PluginPortalregisters plugin metadata and categories- The plugin picker surfaces that catalog
_create_*_node()methods add plugin nodes and specialized connections toChatSceneWindowActionsMixin.execute_*_node()starts the relevant worker thread- Worker thread updates the node UI
ChatSessionManagerserializes the node and its specialized connections- Delete logic in
ChatSceneand plugindispose()methods performs cleanup
ChatSessionManagerdelegates naming toTitleGenerator- If runtime is API mode or local Llama.cpp mode:
TitleGenerator.generate_title()routes throughapi_provider.chat(task=config.TASK_TITLE, ...)
- If runtime is local Ollama mode:
TitleGeneratorprefers configured/local Ollama naming models and falls back across installed candidates
graphite_window.ChatWindow.check_for_updates()graphite_update.UpdateCheckWorker- Remote version signal fetched from GitHub
graphite_licensing.SettingsManager.record_update_check_result()AppearanceSettingsWidgetsurfaces the saved status and manual re-check action
This is the live registration order in graphite_plugins/graphite_plugin_portal.py.
System PromptConversation Node
Graphlink-ReasoningGraphlink-Web
Branch LensQuality GateCode Review Agent
GitlinkPy-CoderExecution SandboxHTML Renderer
Workflow ArchitectArtifact / Drafter
These top-level files are import-stability shims, not the main implementation.
graphite_app/graphite_node.py->graphite_app/graphite_nodes/*
graphite_app/graphite_canvas_items.py->graphite_app/graphite_canvas/__init__.pygraphite_app/graphite_canvas_groups.py->graphite_app/graphite_canvas/__init__.pygraphite_app/graphite_canvas_note_items.py->graphite_app/graphite_canvas/__init__.pygraphite_app/graphite_canvas_dialogs.py->graphite_app/graphite_canvas/graphite_canvas_dialogs.py
graphite_app/graphite_library_dialog.py->graphite_app/graphite_ui_dialogs/graphite_library_dialog.pygraphite_app/graphite_settings_dialogs.py->graphite_app/graphite_ui_dialogs/graphite_settings_dialogs.pygraphite_app/graphite_system_dialogs.py->graphite_app/graphite_ui_dialogs/graphite_system_dialogs.py
graphite_app/graphite_plugin_artifact.py->graphite_app/graphite_plugins/graphite_plugin_artifact.pygraphite_app/graphite_plugin_code_review.py->graphite_app/graphite_plugins/graphite_plugin_code_review.pygraphite_app/graphite_plugin_code_sandbox.py->graphite_app/graphite_plugins/graphite_plugin_code_sandbox.pygraphite_app/graphite_plugin_gitlink.py->graphite_app/graphite_plugins/graphite_plugin_gitlink.pygraphite_app/graphite_plugin_graph_diff.py->graphite_app/graphite_plugins/graphite_plugin_graph_diff.pygraphite_app/graphite_plugin_picker.py->graphite_app/graphite_plugins/graphite_plugin_picker.pygraphite_app/graphite_plugin_portal.py->graphite_app/graphite_plugins/graphite_plugin_portal.pygraphite_app/graphite_plugin_quality_gate.py->graphite_app/graphite_plugins/graphite_plugin_quality_gate.pygraphite_app/graphite_plugin_workflow.py->graphite_app/graphite_plugins/graphite_plugin_workflow.py
graphite_app/graphite_agents.pyre-exports the splitgraphite_agents_*modules
This is the practical lookup map for where code actually lives today.
api_provider.py- Provider abstraction for Ollama, direct
Llama.cpp, OpenAI-compatible chat/image APIs, and Gemini. - Key responsibilities:
- local/runtime initialization
- GGUF scanning
- Ollama model scanning
- modality preparation
chat()generate_image()
- Provider abstraction for Ollama, direct
graphite_audio.py- Audio attachment validation and duration probing.
- Key functions/classes:
AudioValidationError,is_supported_audio_file(),guess_audio_mime_type(),inspect_audio_file(),format_duration()
graphite_lod.py- Shared zoom-dependent render helpers.
- Key helpers:
lod_mode_for_item(),preview_text(),sync_proxy_render_state(),draw_lod_card()
graphite_update.py- Update signal fetch and comparison logic.
- Key symbols:
UPDATE_SIGNAL_URL,UPDATE_REPOSITORY_URL,UpdateCheckWorker,build_update_result()
graphite_version.py- Current local app version constant.
graphite_window.py- Main shell, mode switching, toolbar, update checks, settings flyout, attachment staging.
graphite_window_actions.py- Prompt dispatch, attachment packaging, response parsing, plugin execution.
graphite_scene.py- Scene/controller authority.
graphite_memory.py- Branch/history helpers.
graphite_plugin_context_menu.py- Shared context menu for plugin nodes.
content_codec.py- Serialization helpers for history and binary image content.
database.py- SQLite persistence.
deserializers.py- Concrete load compatibility and graph restoration.
manager.pyChatSessionManager- Coordinates save/load/title generation and delegates runtime helpers.
scene_index.py- Centralized node-list/index helpers used by persistence code.
serializers.py- Concrete save payload authority.
title_generator.py- Chat naming strategy across Ollama, Llama.cpp, and API modes.
workers.py- Background save worker.
graphite_library_dialog.py- Recent chat browser.
graphite_settings_dialogs.py- Live settings flyout.
- This is the real place to edit:
- Ollama scans
- GGUF scans
- API provider/model settings
- GitHub token settings
- update-check controls
graphite_system_dialogs.py- About/help UI.
loading_visuals.py- Shared spinner painter.
overlays.pyLoadingAnimation,SearchOverlay
pins.py- Overlay-side pin helper plus
PinOverlay
- Overlay-side pin helper plus
splash.py- Splash screen and animation
text_inputs.py- Composer surface and attachment pills
tokens.py- Token estimator and token counter widget
graphite_app/graphite_window.pygraphite_app/graphite_config.pygraphite_app/graphite_licensing.pygraphite_app/api_provider.pygraphite_app/graphite_ui_dialogs/graphite_settings_dialogs.py
graphite_app/api_provider.pygraphite_app/graphite_config.pygraphite_app/graphite_licensing.pygraphite_app/graphite_ui_dialogs/graphite_settings_dialogs.py
graphite_app/api_provider.pygraphite_app/graphite_licensing.pygraphite_app/graphite_ui_dialogs/graphite_settings_dialogs.pygraphite_app/graphite_window.pygraphite_app/graphite_session/title_generator.py
graphite_app/graphite_window_actions.pygraphite_app/graphite_memory.pygraphite_app/graphite_file_handler.pygraphite_app/graphite_audio.pygraphite_app/api_provider.py
graphite_app/graphite_window.pygraphite_app/graphite_window_actions.pygraphite_app/graphite_audio.pygraphite_app/graphite_nodes/graphite_node_document.pygraphite_app/graphite_session/serializers.pygraphite_app/graphite_session/deserializers.py
graphite_app/graphite_view.pygraphite_app/graphite_scene.pygraphite_app/graphite_connections.pygraphite_app/graphite_minimap.pygraphite_app/graphite_lod.pygraphite_app/graphite_canvas/*
- Core chat/code/doc/image/thinking nodes:
graphite_app/graphite_nodes/*
- Specialized nodes:
graphite_app/graphite_pycoder.pygraphite_app/graphite_web.pygraphite_app/graphite_conversation_node.pygraphite_app/graphite_reasoning.pygraphite_app/graphite_html_view.py
- Then update:
graphite_app/graphite_scene.pygraphite_app/graphite_session/scene_index.pygraphite_app/graphite_session/serializers.pygraphite_app/graphite_session/deserializers.pygraphite_app/graphite_window.pygraphite_app/graphite_window_actions.py
- Registration and category metadata:
graphite_app/graphite_plugins/graphite_plugin_portal.py
- Picker UI:
graphite_app/graphite_plugins/graphite_plugin_picker.py
- Shared plugin context menu:
graphite_app/graphite_plugin_context_menu.py
- Concrete plugin logic:
graphite_app/graphite_plugins/graphite_plugin_*.py
- Then verify:
graphite_app/graphite_scene.pygraphite_app/graphite_session/scene_index.pygraphite_app/graphite_session/serializers.pygraphite_app/graphite_session/deserializers.pygraphite_app/graphite_window_actions.py
graphite_app/graphite_session/scene_index.pygraphite_app/graphite_session/serializers.pygraphite_app/graphite_session/deserializers.pygraphite_app/graphite_session/manager.pygraphite_app/graphite_core.pygraphite_app/graphite_scene.py
graphite_app/graphite_update.pygraphite_app/graphite_version.pygraphite_app/graphite_licensing.pygraphite_app/graphite_window.pygraphite_app/graphite_ui_dialogs/graphite_settings_dialogs.py
graphite_app/graphite_widgets/*graphite_app/graphite_ui_components.py
- Open the concrete package file before touching a compatibility wrapper.
- Treat
api_provider.pyas the runtime execution authority for every model mode. - Treat
ChatSceneplus session serializer/deserializer code as the graph schema. - Treat
graphite_session/scene_index.pyas the central list/index helper whenever you add a new persisted node family. - Treat
WindowActionsMixinas the execution dispatcher. - Treat
PluginPortalas the plugin catalog authority. - Treat
graphite_memory.pyas the only safe place to define branch-history semantics. - Treat
graphite_lod.pyas shared render infrastructure, not optional polish. - Remember that
Llama.cppmode expects direct.gguffiles, not Ollama blobs/manifests. - Remember that audio attachments persist through
DocumentNode, not a separate audio node type. - Be careful with duplicate names:
- scene
NavigationPinlives ingraphite_canvas - overlay
NavigationPinlives ingraphite_widgets
- scene
- Be careful with legacy files:
graphite_dialogs.pyis not the live canvas dialog authority
- Be careful with machine-specific paths:
- several asset paths are still hardcoded to one local repo location