Workspace Graph
Force-directed D3 graph of every document, memory, decision, milestone, and artifact in a workspace, wired together by explicit links and semantic similarity. Hover for context, drag to pin, filter by node type.
Overview
The graph is built from three layers of edges:
- Explicit edges, relationship links that were explicitly recorded between items (e.g., a decision that supersedes another, or an artifact that implements a milestone). These appear as solid colored lines with directional arrow markers.
- Similarity edges, automatically computed semantic similarity links between nodes based on their embedding vectors. These appear as faint dashed lines and require an embeddings endpoint to be configured for the project.
- Provenance edges, dotted lines tracing which chat session or message produced a given item.
The layout uses a force simulation. Nodes are initially seeded near their cluster's centroid hint (when the server emits one) and otherwise take the simulation's default position. A D3 force simulation then refines positions with cluster gravity, charge repulsion, link forces, and collision avoidance.
Note: Similarity edges require an embeddings model to be provisioned for the project. Without embeddings, only explicit and provenance edges are rendered.
Accessing the Graph
The Workspace Graph is accessible from the Document Workspace view. Open any chat that has a document workspace enabled and navigate to the workspace tab. The graph renders automatically when the workspace contains at least one node.
When the workspace is empty, a placeholder state is shown in place of the graph. Add documents, create memories, or record decisions to populate the graph.
Dashboard endpoint (session auth)
The chat dashboard fetches graph data from a session-gated route. Requests must carry a valid frontend session cookie and the caller must be a member of the project that owns the workspace. Bearer API keys cannot call this route; use the router-public endpoint described below for programmatic access.
GET /chat/api/workspaces/{workspaceId}/graph
Optional query parameters:
meta=1, short-circuit response that returns only the embedding-state header chip; used by the client to poll while a workspace is mid-backfill.origin_chat=<uuid>, biases data-gravity scoring toward content produced in the given chat.full=1, raises the leaf streaming ceiling from 2000 to 8000 nodes for very large workspaces.
Response shapes
The endpoint negotiates two response shapes by Accept header.
Server-sent events (default for the chat client,
Accept: text/event-stream): the server streams the
graph as it is computed. The event family is:
x_graph.meta, workspace and embedding-state header.x_graph.nodes, incremental node batches.x_graph.edges, incremental edge batches (explicit, similarity, provenance).x_graph.clusters, cluster descriptors with optional centroid hints.x_graph.done, terminal success event with aggregate stats.x_graph.error, terminal failure event carrying the failed stage and a detail string.
JSON envelope (for non-SSE callers): the response is
{ "nodes": [...], "edges": [...], "clusters": [...], "stats": {...} }.
The JSON shape is capped at 1000 nodes by default; set the request
header X-Graph-Full: 1 to lift the cap.
Router-public endpoint (bearer auth)
Programmatic callers (project API key) can read graph data via the
router-public route. This endpoint exposes only decision and
milestone kind nodes; documents, memories, and
artifacts are dashboard-only.
GET /{project_id}/v1/workspaces/{workspaceId}/graph
Dashboard JavaScript hook
Dashboard authors embedding the graph component can trigger a refresh via the page-scoped helper. This API is intended for in-page integration only and is not part of the public API contract.
WorkspaceGraph.refresh();
Node Types
Five node types are rendered in the graph. Each type has a distinct shape and color to make identification fast at a glance.
| Type | Shape | Description |
|---|---|---|
document |
Rounded rectangle | An uploaded file in the workspace. Node size scales with chunk count, documents with more text content appear larger. The popover shows the chunk count and a preview excerpt. |
memory |
Circle | A saved memory associated with the workspace. Memories are facts, preferences, or instructions that the model has recorded. The popover shows the memory category and source type (model or user). |
decision |
Diamond (rotated square) | An architectural or design decision captured in the workspace. Decisions record the chosen outcome, the reasoning, and any alternatives that were considered. The diamond shape visually signals a decision point. |
milestone |
Hexagon | A project milestone or goal tracked in the workspace. Milestones represent significant progress markers or deliverables. |
artifact |
Wide rectangle | A generated artifact, typically a code file, report, or other produced output. Node size scales with file byte size. The popover shows the formatted file size. |
Node radius is computed from two components: a base content size (scaled
from chunk count or byte size) and a degree boost that makes highly
connected nodes appear larger (up to 20 px additional radius from
connections). The minimum radius is 20 px for every node type.
The maximum radius is 65 px for document and
artifact nodes (which scale with chunk count and byte
size), and 45 px for decision, milestone,
and memory nodes (whose base size is fixed at 25 px).
Edge / Relationship Types
Explicit edges between nodes carry a typed relationship. The relationship is displayed as a label near the midpoint of the edge on hover.
Persisted relationship types
Six relationship types may be written to a workspace via the
relationship write surface (the x_relate MCP tool,
backed by the project intelligence storage service). These are
the only values accepted on edge creation.
| Relationship | Color | Meaning |
|---|---|---|
supports |
Green | The source node provides evidence or reasoning in favor of the target. |
supersedes |
Orange | The source node replaces or overrides the target (e.g., a newer decision superseding an older one). Both endpoints must be decisions. |
blocks |
Red | The source node prevents or blocks progress on the target. |
implements |
Blue | The source node is a concrete implementation of the target (e.g., an artifact implementing a milestone). |
contradicts |
Red (dashed) | The source node is in conflict with the target. Rendered with a dashed stroke to visually distinguish it from blocks. |
refines |
Teal | The source node extends or clarifies the target without replacing it. |
Persisted relationships are written through the
x_relate MCP tool. See
Server-Side Tools and
MCP for the tool surface that
records these edges.
Synthetic similarity edges
The graph also renders two synthetic edge classes that are not persisted relationships and cannot be created through the relationship write surface:
similar, minted by the graph pipeline from pairwise embedding similarity when an embeddings endpoint is configured for the project. Faint dotted, slate gray.provenance, traced from the chat session or message that produced a node. Dotted, sandy orange. Always emitted, regardless of embeddings configuration.
Edge Visual Styles
| Edge Class | Style | Arrow |
|---|---|---|
| Explicit relationship | Solid, 1.5 px, relationship-colored (except contradicts which is dashed) |
Colored arrowhead matching the edge |
| Similarity (auto) | Faint dotted, 0.75 px, slate gray (#7a8a9a), 35% opacity |
None |
| Provenance | Dotted, 1 px, sandy orange (#d4a96f), tuned to be visually distinct from similarity edges |
Sandy-orange arrowhead matching the stroke |
When multiple edges exist between the same pair of nodes, each edge is rendered as a curved arc with increasing curvature and alternating sweep direction so the edges do not overlap.
Filtering and Search
Type Filter Chips
The filter bar displays a chip button for each node type (Document, Memory, Decision, Milestone, Artifact). Each chip shows a colored dot matching the node color. Clicking a chip toggles that type on or off. When a type is disabled, its nodes are hidden and the force simulation reheats so remaining nodes redistribute.
All types are enabled by default. Disabling a type also hides any edges that connect exclusively to hidden nodes.
Text Search
The search input filters nodes by name and preview text. Matching nodes remain fully opaque; non-matching nodes fade to 10% opacity. Matching nodes briefly scale up (1.3x) and back as a pulse animation to draw attention. Search is debounced at 200 ms to avoid thrashing the layout on every keystroke.
Filter Interaction
Both filters (type chips and search) apply simultaneously. A node must pass all active filters to appear at full opacity with interactive pointer events enabled.
Tooltips and Popovers
Hover Tooltip
Hovering over a node displays a lightweight tooltip positioned near the cursor. The tooltip contains:
- Node type label in the node's color (e.g., "DOCUMENT", "DECISION").
- Node name in medium weight.
- A preview excerpt of the content (up to 100 characters).
- Creation date.
The tooltip is automatically repositioned to stay within the canvas bounds when it would otherwise overflow the right or bottom edge.
Hovering over an edge highlights it (thicker stroke, full opacity) and shows the relationship label near the midpoint of the edge.
Click Popover
Clicking a node opens a detail popover in the center of the canvas. The popover provides:
- A colored type badge and a close button.
- The full node name.
- Type-specific metadata: category, source type, creation date, chunk count (documents), or file size (artifacts).
- A preview of the node's content.
- A connections list showing all adjacent nodes with their relationship type and a colored type dot.
Clicking a connection item in the popover navigates directly to the connected node's popover. Clicking outside the popover or on another node closes it.
Color Coding
Node colors and edge colors follow a consistent scheme across the graph, filter chips, type dots, and popovers.
| Item | Color | Hex | |
|---|---|---|---|
| Document node | Blue | #4a9eff |
|
| Memory node | Green | #6bcf7f |
|
| Decision node | Orange | #f0a050 |
|
| Milestone node | Purple | #b07ce8 |
|
| Artifact node | Teal | #5cc6c6 |
|
supports edge |
Green | #6bcf7f |
|
supersedes edge |
Orange | #f0a050 |
|
blocks edge |
Red | #e05050 |
|
implements edge |
Blue | #4a9eff |
|
contradicts edge |
Red (dashed) | #e05050 |
|
refines edge |
Teal | #5cc6c6 |
|
similar edge (synthetic) |
Slate gray | #7a8a9a |
|
| Provenance edge | Sandy orange | #d4a96f |
All nodes are rendered at 85% fill opacity to allow edges behind overlapping nodes to remain faintly visible.
Diagnostics
When the graph stream fails partway through loading, a single diagnostic banner is rendered above the canvas describing the stage that failed and the underlying message reported by the server. The text takes the form:
Graph load failed at <stage>: <detail>
The streaming EventSource is closed when the banner is shown so the client does not retry against a broken connection. Triggering a refresh (for example, by reopening the workspace tab) clears the banner and re-establishes the stream.
Stage Values
The <stage> token in the banner is one of the
following:
| Stage | Meaning |
|---|---|
meta |
Workspace lookup or embedding-state header failed; usually a permissions or workspace-id error. |
init |
Pipeline initialization failed before any node or edge stage could run. |
pipeline |
An interior pipeline step (node enumeration, edge load, similarity computation, or cluster assignment) failed; consult the <detail> string for the specific cause. |
encoding |
The SSE event itself could not be encoded for transport. |
replay |
An aggregate-cache replay decoded an incomplete or malformed event; the live stream is rebuilt automatically. |
There is no separate empty-edge diagnostic. If the graph renders nodes but no similarity edges, an embeddings endpoint may not be provisioned for the project; see the embeddings and endpoint configuration docs to enable similarity edges.
Related Pages
- Document Workspace, uploading and managing workspace documents.
- Chat Memory, how memories are saved and recalled in conversations.
- Server-Side Tools, the
x_relate,x_track_decision, andx_track_milestonetools that write to the graph. - MCP, model-context-protocol surface that exposes the project intelligence tools.