docs: Comprehensive documentation update for Dashboard V3 and Canvas
## Documentation Updates - DASHBOARD.md: Updated to V3.0 with Canvas V3 features, file browser, introspection - DASHBOARD_IMPLEMENTATION_STATUS.md: Marked Canvas V3 features as COMPLETE - CANVAS.md: New comprehensive guide for Canvas Builder V3 with all features - CLAUDE.md: Added dashboard quick reference and Canvas V3 features ## Canvas V3 Features Documented - File Browser: Browse studies directory for model files - Model Introspection: Auto-discover expressions, solver type, dependencies - One-Click Add: Add expressions as design variables instantly - Claude Bug Fixes: WebSocket reconnection, SQL errors resolved - Health Check: /api/health endpoint for monitoring ## Backend Services - NX introspection service with expression discovery - File browser API with type filtering - Claude session management improvements - Context builder enhancements ## Frontend Components - FileBrowser: Modal for file selection with search - IntrospectionPanel: View discovered model information - ExpressionSelector: Dropdown for design variable configuration - Improved chat hooks with reconnection logic ## Plan Documents - Added RALPH_LOOP_CANVAS_V2/V3 implementation records - Added ATOMIZER_DASHBOARD_V2_MASTER_PLAN - Added investigation and sync documentation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -235,7 +235,302 @@ function intentToConfig(intent: CanvasIntent, studyName: string): Record<string,
|
||||
};
|
||||
}
|
||||
|
||||
// Canvas modification tools - return instructions for the frontend to apply
|
||||
interface CanvasModification {
|
||||
action: 'add_node' | 'update_node' | 'remove_node' | 'add_edge' | 'remove_edge';
|
||||
nodeType?: string;
|
||||
nodeId?: string;
|
||||
data?: Record<string, unknown>;
|
||||
source?: string;
|
||||
target?: string;
|
||||
edgeId?: string;
|
||||
}
|
||||
|
||||
export const canvasTools: AtomizerTool[] = [
|
||||
// Canvas Modification Tools
|
||||
{
|
||||
definition: {
|
||||
name: "canvas_add_node",
|
||||
description:
|
||||
"Add a new node to the canvas. Use this when the user asks to add a design variable, extractor, objective, constraint, etc. Returns a modification instruction for the frontend.",
|
||||
inputSchema: {
|
||||
type: "object" as const,
|
||||
properties: {
|
||||
node_type: {
|
||||
type: "string",
|
||||
enum: ["designVar", "extractor", "objective", "constraint", "surrogate"],
|
||||
description: "Type of node to add",
|
||||
},
|
||||
label: {
|
||||
type: "string",
|
||||
description: "Display label for the node",
|
||||
},
|
||||
// Design variable properties
|
||||
expression_name: {
|
||||
type: "string",
|
||||
description: "For designVar: the NX expression name",
|
||||
},
|
||||
min_value: {
|
||||
type: "number",
|
||||
description: "For designVar: minimum value",
|
||||
},
|
||||
max_value: {
|
||||
type: "number",
|
||||
description: "For designVar: maximum value",
|
||||
},
|
||||
baseline: {
|
||||
type: "number",
|
||||
description: "For designVar: baseline/initial value",
|
||||
},
|
||||
unit: {
|
||||
type: "string",
|
||||
description: "For designVar: unit (mm, deg, etc.)",
|
||||
},
|
||||
// Extractor properties
|
||||
extractor_id: {
|
||||
type: "string",
|
||||
description: "For extractor: extractor ID (E1-E10)",
|
||||
},
|
||||
extractor_type: {
|
||||
type: "string",
|
||||
description: "For extractor: type (zernike_opd, displacement, mass, etc.)",
|
||||
},
|
||||
// Objective properties
|
||||
direction: {
|
||||
type: "string",
|
||||
enum: ["minimize", "maximize"],
|
||||
description: "For objective: optimization direction",
|
||||
},
|
||||
weight: {
|
||||
type: "number",
|
||||
description: "For objective: weight in weighted sum",
|
||||
},
|
||||
// Constraint properties
|
||||
operator: {
|
||||
type: "string",
|
||||
enum: ["<=", ">=", "<", ">", "=="],
|
||||
description: "For constraint: comparison operator",
|
||||
},
|
||||
value: {
|
||||
type: "number",
|
||||
description: "For constraint: threshold value",
|
||||
},
|
||||
},
|
||||
required: ["node_type", "label"],
|
||||
},
|
||||
},
|
||||
handler: async (args) => {
|
||||
const nodeType = args.node_type as string;
|
||||
const label = args.label as string;
|
||||
|
||||
// Build node data based on type
|
||||
const data: Record<string, unknown> = {
|
||||
label,
|
||||
configured: true,
|
||||
};
|
||||
|
||||
switch (nodeType) {
|
||||
case "designVar":
|
||||
data.expressionName = args.expression_name || label;
|
||||
if (args.min_value !== undefined) data.minValue = args.min_value;
|
||||
if (args.max_value !== undefined) data.maxValue = args.max_value;
|
||||
if (args.baseline !== undefined) data.baseline = args.baseline;
|
||||
if (args.unit) data.unit = args.unit;
|
||||
data.enabled = true;
|
||||
break;
|
||||
case "extractor":
|
||||
data.extractorId = args.extractor_id || "E5";
|
||||
data.extractorName = label;
|
||||
data.extractorType = args.extractor_type;
|
||||
break;
|
||||
case "objective":
|
||||
data.name = label;
|
||||
data.direction = args.direction || "minimize";
|
||||
data.weight = args.weight || 1;
|
||||
break;
|
||||
case "constraint":
|
||||
data.name = label;
|
||||
data.operator = args.operator || "<=";
|
||||
data.value = args.value || 0;
|
||||
break;
|
||||
case "surrogate":
|
||||
data.enabled = true;
|
||||
data.modelType = "MLP";
|
||||
break;
|
||||
}
|
||||
|
||||
const modification: CanvasModification = {
|
||||
action: "add_node",
|
||||
nodeType,
|
||||
data,
|
||||
};
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify({
|
||||
success: true,
|
||||
modification,
|
||||
message: `Added ${nodeType} node "${label}" to the canvas.`,
|
||||
}, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
definition: {
|
||||
name: "canvas_update_node",
|
||||
description:
|
||||
"Update an existing node's properties on the canvas. Use this when the user asks to change bounds, weights, names, etc.",
|
||||
inputSchema: {
|
||||
type: "object" as const,
|
||||
properties: {
|
||||
node_id: {
|
||||
type: "string",
|
||||
description: "ID of the node to update (or label/name to find it)",
|
||||
},
|
||||
find_by: {
|
||||
type: "string",
|
||||
enum: ["id", "label", "expression_name"],
|
||||
description: "How to find the node (default: label)",
|
||||
},
|
||||
updates: {
|
||||
type: "object",
|
||||
description: "Key-value pairs of properties to update",
|
||||
},
|
||||
},
|
||||
required: ["node_id", "updates"],
|
||||
},
|
||||
},
|
||||
handler: async (args) => {
|
||||
const nodeId = args.node_id as string;
|
||||
const findBy = (args.find_by as string) || "label";
|
||||
const updates = args.updates as Record<string, unknown>;
|
||||
|
||||
const modification: CanvasModification = {
|
||||
action: "update_node",
|
||||
nodeId,
|
||||
data: {
|
||||
findBy,
|
||||
...updates,
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify({
|
||||
success: true,
|
||||
modification,
|
||||
message: `Updated node "${nodeId}" with: ${JSON.stringify(updates)}`,
|
||||
}, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
definition: {
|
||||
name: "canvas_remove_node",
|
||||
description: "Remove a node from the canvas.",
|
||||
inputSchema: {
|
||||
type: "object" as const,
|
||||
properties: {
|
||||
node_id: {
|
||||
type: "string",
|
||||
description: "ID or label of the node to remove",
|
||||
},
|
||||
find_by: {
|
||||
type: "string",
|
||||
enum: ["id", "label"],
|
||||
description: "How to find the node (default: label)",
|
||||
},
|
||||
},
|
||||
required: ["node_id"],
|
||||
},
|
||||
},
|
||||
handler: async (args) => {
|
||||
const nodeId = args.node_id as string;
|
||||
const findBy = (args.find_by as string) || "label";
|
||||
|
||||
const modification: CanvasModification = {
|
||||
action: "remove_node",
|
||||
nodeId,
|
||||
data: { findBy },
|
||||
};
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify({
|
||||
success: true,
|
||||
modification,
|
||||
message: `Removed node "${nodeId}" from the canvas.`,
|
||||
}, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
definition: {
|
||||
name: "canvas_connect_nodes",
|
||||
description: "Create an edge (connection) between two nodes on the canvas.",
|
||||
inputSchema: {
|
||||
type: "object" as const,
|
||||
properties: {
|
||||
source: {
|
||||
type: "string",
|
||||
description: "Source node (ID or label)",
|
||||
},
|
||||
target: {
|
||||
type: "string",
|
||||
description: "Target node (ID or label)",
|
||||
},
|
||||
find_by: {
|
||||
type: "string",
|
||||
enum: ["id", "label"],
|
||||
description: "How to find nodes (default: label)",
|
||||
},
|
||||
},
|
||||
required: ["source", "target"],
|
||||
},
|
||||
},
|
||||
handler: async (args) => {
|
||||
const source = args.source as string;
|
||||
const target = args.target as string;
|
||||
const findBy = (args.find_by as string) || "label";
|
||||
|
||||
const modification: CanvasModification = {
|
||||
action: "add_edge",
|
||||
source,
|
||||
target,
|
||||
data: { findBy },
|
||||
};
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify({
|
||||
success: true,
|
||||
modification,
|
||||
message: `Connected "${source}" to "${target}".`,
|
||||
}, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
// Original Intent Processing Tools
|
||||
{
|
||||
definition: {
|
||||
name: "validate_canvas_intent",
|
||||
|
||||
Reference in New Issue
Block a user