Add experiment logs to the monitoring page #48

Merged
0950726 merged 122 commits from feat/experiment-logs into dev 2026-01-28 10:16:00 +00:00
9 changed files with 30 additions and 27 deletions
Showing only changes of commit bb053fda21 - Show all commits

View File

@@ -1,7 +1,16 @@
:global(.react-flow__handle.source){
border-radius: 100%;
}
:global(.react-flow__handle.target){
border-radius: 15%;
}
:global(.react-flow__handle.connected) { :global(.react-flow__handle.connected) {
background: lightgray; background: lightgray;
border-color: green; border-color: green;
filter: drop-shadow(0 0 0.25rem green); filter: drop-shadow(0 0 0.15rem green);
} }
:global(.singleConnectionHandle.connected) { :global(.singleConnectionHandle.connected) {
@@ -16,19 +25,19 @@
:global(.singleConnectionHandle.unconnected){ :global(.singleConnectionHandle.unconnected){
background: lightsalmon; background: lightsalmon;
border-color: #ff6060; border-color: #ff6060;
filter: drop-shadow(0 0 0.25rem #ff6060); filter: drop-shadow(0 0 0.15rem #ff6060);
} }
:global(.react-flow__handle.connectingto) { :global(.react-flow__handle.connectingto) {
background: #ff6060; background: #ff6060;
border-color: coral; border-color: coral;
filter: drop-shadow(0 0 0.25rem coral); filter: drop-shadow(0 0 0.15rem coral);
} }
:global(.react-flow__handle.valid) { :global(.react-flow__handle.valid) {
background: #55dd99; background: #55dd99;
border-color: green; border-color: green;
filter: drop-shadow(0 0 0.25rem green); filter: drop-shadow(0 0 0.15rem green);
} }
:global(.react-flow__handle) { :global(.react-flow__handle) {

View File

@@ -4,7 +4,6 @@ import {
type Connection, type Connection,
useNodeId, useNodeConnections useNodeId, useNodeConnections
} from '@xyflow/react'; } from '@xyflow/react';
import {useState} from 'react';
import { type HandleRule, useHandleRules} from "../HandleRuleLogic.ts"; import { type HandleRule, useHandleRules} from "../HandleRuleLogic.ts";
import "./RuleBasedHandle.module.css"; import "./RuleBasedHandle.module.css";
@@ -29,21 +28,16 @@ export function MultiConnectionHandle({
handleId: id! handleId: id!
}) })
// initialise the handles state with { isValid: true } to show that connections are possible
const [handleState, setHandleState] = useState<{ isSatisfied: boolean, message?: string }>({ isSatisfied: true });
return ( return (
<Handle <Handle
{...otherProps} {...otherProps}
id={id} id={id}
type={type} type={type}
className={"multiConnectionHandle" + (connections.length === 0 ? " unconnected" : " connected")} className={"multiConnectionHandle" + (connections.length === 0 ? " unconnected" : " connected") + ` ${type}`}
isValidConnection={(connection) => { isValidConnection={(connection) => {
const result = validate(connection as Connection); const result = validate(connection as Connection);
setHandleState(result);
return result.isSatisfied; return result.isSatisfied;
}} }}
title={handleState.message}
/> />
); );
} }
@@ -66,22 +60,18 @@ export function SingleConnectionHandle({
handleId: id! handleId: id!
}) })
// initialise the handles state with { isValid: true } to show that connections are possible
const [handleState, setHandleState] = useState<{ isSatisfied: boolean, message?: string }>({ isSatisfied: true });
return ( return (
<Handle <Handle
{...otherProps} {...otherProps}
id={id} id={id}
type={type} type={type}
className={"singleConnectionHandle" + (connections.length === 0 ? " unconnected" : " connected")} className={"singleConnectionHandle" + (connections.length === 0 ? " unconnected" : " connected") + ` ${type}`}
isConnectable={connections.length === 0} isConnectable={connections.length === 0}
isValidConnection={(connection) => { isValidConnection={(connection) => {
const result = validate(connection as Connection); const result = validate(connection as Connection);
setHandleState(result);
return result.isSatisfied; return result.isSatisfied;
}} }}
title={handleState.message}
/> />
); );
} }

View File

@@ -190,7 +190,7 @@ export default function BasicBeliefNode(props: NodeProps<BasicBeliefNode>) {
)} )}
<MultiConnectionHandle type="source" position={Position.Right} id="source" rules={[ <MultiConnectionHandle type="source" position={Position.Right} id="source" rules={[
allowOnlyConnectionsFromHandle([{nodeType:"trigger",handleId:"TriggerBeliefs"}, {nodeType:"norm",handleId:"NormBeliefs"}]), allowOnlyConnectionsFromHandle([{nodeType:"trigger",handleId:"TriggerBeliefs"}, {nodeType:"norm",handleId:"NormBeliefs"}]),
]}/> ]} title="Connect to any number of trigger and/or normNode(-s)"/>
</div> </div>
</> </>
); );

View File

@@ -60,7 +60,7 @@ export default function EndNode(props: NodeProps<EndNode>) {
</div> </div>
<SingleConnectionHandle type="target" position={Position.Left} id="target" rules={[ <SingleConnectionHandle type="target" position={Position.Left} id="target" rules={[
allowOnlyConnectionsFromType(["phase"]) allowOnlyConnectionsFromType(["phase"])
]}/> ]} title="Connect to a phaseNode"/>
</div> </div>
</> </>
); );

View File

@@ -118,9 +118,11 @@ export default function GoalNode({id, data}: NodeProps<GoalNode>) {
</div> </div>
<MultiConnectionHandle type="source" position={Position.Right} id="GoalSource" rules={[ <MultiConnectionHandle type="source" position={Position.Right} id="GoalSource" rules={[
allowOnlyConnectionsFromHandle([{nodeType:"phase",handleId:"data"}]), allowOnlyConnectionsFromHandle([{nodeType:"phase",handleId:"data"}]),
]}/> ]} title="Connect to any number of phase and/or goalNode(-s)"/>
<MultiConnectionHandle type="target" position={Position.Bottom} id="GoalTarget" rules={[allowOnlyConnectionsFromType(["goal"])]}/> <MultiConnectionHandle type="target" position={Position.Bottom} id="GoalTarget" rules={[
allowOnlyConnectionsFromType(["goal"])]
} title="Connect to any number of goalNode(-s)"/>
</div> </div>

View File

@@ -79,10 +79,10 @@ export default function NormNode(props: NodeProps<NormNode>) {
<MultiConnectionHandle type="source" position={Position.Right} id="norms" rules={[ <MultiConnectionHandle type="source" position={Position.Right} id="norms" rules={[
allowOnlyConnectionsFromHandle([{nodeType:"phase",handleId:"data"}]) allowOnlyConnectionsFromHandle([{nodeType:"phase",handleId:"data"}])
]}/> ]} title="Connect to any number of phaseNode(-s)"/>
<SingleConnectionHandle type="target" position={Position.Bottom} id="NormBeliefs" rules={[ <SingleConnectionHandle type="target" position={Position.Bottom} id="NormBeliefs" rules={[
allowOnlyConnectionsFromType(["basic_belief"]) allowOnlyConnectionsFromType(["basic_belief"])
]}/> ]} title="Connect to a beliefNode or a set of beliefs combined using the AND/OR node"/>
</div> </div>
</>; </>;
}; };

View File

@@ -148,14 +148,14 @@ export default function PhaseNode(props: NodeProps<PhaseNode>) {
<SingleConnectionHandle type="target" position={Position.Left} id="target" rules={[ <SingleConnectionHandle type="target" position={Position.Left} id="target" rules={[
noSelfConnections, noSelfConnections,
allowOnlyConnectionsFromType(["phase", "start"]), allowOnlyConnectionsFromType(["phase", "start"]),
]}/> ]} title="Connect to a phase or the startNode"/>
<MultiConnectionHandle type="target" position={Position.Bottom} id="data" rules={[ <MultiConnectionHandle type="target" position={Position.Bottom} id="data" rules={[
allowOnlyConnectionsFromType(["norm", "goal", "trigger"]) allowOnlyConnectionsFromType(["norm", "goal", "trigger"])
]}/> ]} title="Connect to any number of norm, goal, and TriggerNode(-s)"/>
<SingleConnectionHandle type="source" position={Position.Right} id="source" rules={[ <SingleConnectionHandle type="source" position={Position.Right} id="source" rules={[
noSelfConnections, noSelfConnections,
allowOnlyConnectionsFromType(["phase", "end"]), allowOnlyConnectionsFromType(["phase", "end"]),
]}/> ]} title="Connect to a phase or the endNode"/>
</div> </div>
</> </>
); );

View File

@@ -58,7 +58,7 @@ export default function StartNode(props: NodeProps<StartNode>) {
</div> </div>
<SingleConnectionHandle type="source" position={Position.Right} id="source" rules={[ <SingleConnectionHandle type="source" position={Position.Right} id="source" rules={[
allowOnlyConnectionsFromHandle([{nodeType:"phase",handleId:"target"}]) allowOnlyConnectionsFromHandle([{nodeType:"phase",handleId:"target"}])
]}/> ]} title="Connect to a phaseNode"/>
</div> </div>
</> </>
); );

View File

@@ -65,7 +65,7 @@ export default function TriggerNode(props: NodeProps<TriggerNode>) {
<div className={"flex-row gap-md"}>Plan{data.plan ? (": " + data.plan.name) : ""} is currently {data.plan ? "" : "not"} set. {data.plan ? "🟢" : "🔴"}</div> <div className={"flex-row gap-md"}>Plan{data.plan ? (": " + data.plan.name) : ""} is currently {data.plan ? "" : "not"} set. {data.plan ? "🟢" : "🔴"}</div>
<MultiConnectionHandle type="source" position={Position.Right} id="TriggerSource" rules={[ <MultiConnectionHandle type="source" position={Position.Right} id="TriggerSource" rules={[
allowOnlyConnectionsFromHandle([{nodeType:"phase",handleId:"data"}]), allowOnlyConnectionsFromHandle([{nodeType:"phase",handleId:"data"}]),
]}/> ]} title="Connect to any number of phaseNodes"/>
<SingleConnectionHandle <SingleConnectionHandle
type="target" type="target"
position={Position.Bottom} position={Position.Bottom}
@@ -74,6 +74,7 @@ export default function TriggerNode(props: NodeProps<TriggerNode>) {
rules={[ rules={[
allowOnlyConnectionsFromType(['basic_belief']), allowOnlyConnectionsFromType(['basic_belief']),
]} ]}
title="Connect to a beliefNode or a set of beliefs combined using the AND/OR node"
/> />
<MultiConnectionHandle <MultiConnectionHandle
@@ -84,6 +85,7 @@ export default function TriggerNode(props: NodeProps<TriggerNode>) {
rules={[ rules={[
allowOnlyConnectionsFromType(['goal']), allowOnlyConnectionsFromType(['goal']),
]} ]}
title="Connect to any number of goalNodes"
/> />
<PlanEditorDialog <PlanEditorDialog