v0.15.4: Populate graph + nodes panel on page load
- /api/graph/active now includes node_details (model, max_tokens per node) - graph.js calls initNodesFromGraph() after fetching active graph - Nodes panel shows all nodes with models immediately on load (before first message) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2d649fa448
commit
e19520db74
15
agent/api.py
15
agent/api.py
@ -380,11 +380,26 @@ def register_routes(app):
|
|||||||
from .engine import load_graph, get_graph_for_cytoscape
|
from .engine import load_graph, get_graph_for_cytoscape
|
||||||
from .runtime import _active_graph_name
|
from .runtime import _active_graph_name
|
||||||
graph = load_graph(_active_graph_name)
|
graph = load_graph(_active_graph_name)
|
||||||
|
# Include model info from instantiated nodes if runtime exists
|
||||||
|
node_details = {}
|
||||||
|
if _active_runtime:
|
||||||
|
for role, impl_name in graph["nodes"].items():
|
||||||
|
# Find the node instance by role
|
||||||
|
node_inst = getattr(_active_runtime, 'frame_engine', None)
|
||||||
|
if node_inst and hasattr(node_inst, 'nodes'):
|
||||||
|
inst = node_inst.nodes.get(role)
|
||||||
|
if inst:
|
||||||
|
node_details[role] = {
|
||||||
|
"impl": impl_name,
|
||||||
|
"model": getattr(inst, 'model', None) or '',
|
||||||
|
"max_tokens": getattr(inst, 'max_context_tokens', 0),
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
"name": graph["name"],
|
"name": graph["name"],
|
||||||
"description": graph["description"],
|
"description": graph["description"],
|
||||||
"nodes": graph["nodes"],
|
"nodes": graph["nodes"],
|
||||||
"edges": graph["edges"],
|
"edges": graph["edges"],
|
||||||
|
"node_details": node_details,
|
||||||
"cytoscape": get_graph_for_cytoscape(graph),
|
"cytoscape": get_graph_for_cytoscape(graph),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -111,6 +111,23 @@ function renderNodes() {
|
|||||||
el.innerHTML = html;
|
el.innerHTML = html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function initNodesFromGraph(graphData) {
|
||||||
|
// Populate node cards from graph definition (before any messages)
|
||||||
|
const nodes = graphData.nodes || {};
|
||||||
|
const details = graphData.node_details || {};
|
||||||
|
for (const [role, impl] of Object.entries(nodes)) {
|
||||||
|
const n = _getNode(role);
|
||||||
|
const d = details[role];
|
||||||
|
if (d) {
|
||||||
|
n.model = (d.model || '').replace('google/', '').replace('anthropic/', '');
|
||||||
|
n.maxTokens = d.max_tokens || 0;
|
||||||
|
}
|
||||||
|
n.lastEvent = 'idle';
|
||||||
|
n.status = 'idle';
|
||||||
|
}
|
||||||
|
renderNodes();
|
||||||
|
}
|
||||||
|
|
||||||
export function clearNodes() {
|
export function clearNodes() {
|
||||||
for (const key of Object.keys(_nodeState)) delete _nodeState[key];
|
for (const key of Object.keys(_nodeState)) delete _nodeState[key];
|
||||||
const el = document.getElementById('node-metrics');
|
const el = document.getElementById('node-metrics');
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
/** Pipeline graph: Cytoscape visualization + animation. */
|
/** Pipeline graph: Cytoscape visualization + animation. */
|
||||||
|
|
||||||
|
import { initNodesFromGraph } from './awareness.js';
|
||||||
|
|
||||||
let cy = null;
|
let cy = null;
|
||||||
let _dragEnabled = true;
|
let _dragEnabled = true;
|
||||||
let _physicsRunning = false;
|
let _physicsRunning = false;
|
||||||
@ -90,6 +92,7 @@ export async function initGraph() {
|
|||||||
if (resp.ok) {
|
if (resp.ok) {
|
||||||
const graph = await resp.json();
|
const graph = await resp.json();
|
||||||
graphElements = buildGraphElements(graph, mx, cw, mid, row1, row2);
|
graphElements = buildGraphElements(graph, mx, cw, mid, row1, row2);
|
||||||
|
initNodesFromGraph(graph);
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user