Node settings arrive as keyword arguments, not a params dict

A python node's settings are constants of its own function, so they are passed
the way its ports are: by name. The controller binds them to the compiled
function, the `params` field is gone from the worker and remote protocols, and
a setting sharing a port's name is reported as a node error rather than
shadowing it. The panel's scaffold follows suit and keeps the header in step
with both ports and settings.

The demo's `pace` moves from a flow input to a setting of the training node,
which is what it always was.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NUb8YpL2s3gmN9WTACTt4q
This commit is contained in:
2026-08-20 17:47:45 +02:00
co-authored by Claude Opus 5
parent 2385e3cf8e
commit 4355c917f8
24 changed files with 225 additions and 126 deletions
+9 -7
View File
@@ -78,7 +78,7 @@ TRUE_SLOPE = 3.0
TRUE_INTERCEPT = 2.0
def process(seed, noise, samples, params):
def process(seed, noise, samples):
rng = random.Random(int(seed))
rows = [
[x, TRUE_SLOPE * x + TRUE_INTERCEPT + rng.gauss(0.0, float(noise))]
@@ -120,7 +120,7 @@ except ImportError: # The engine's own venv has no numpy; a GPU box will.
np = None
def process(dataset, learning_rate, epochs, pace, params):
def process(dataset, learning_rate, epochs, pace):
with open(fluksio.load_artifact(dataset)) as handle:
data = json.load(handle)
@@ -181,7 +181,7 @@ import json
import fluksio
def process(weights, dataset, params):
def process(weights, dataset):
with open(fluksio.load_artifact(weights)) as handle:
fit = json.load(handle)
with open(fluksio.load_artifact(dataset)) as handle:
@@ -235,11 +235,14 @@ NODES = [
# Generous, and an *idle* timeout: a node that keeps publishing keeps
# its deadline reset, so this is how long it may go quiet.
"timeout": 300,
# A setting: a constant of this node's own code, reaching `process` as
# an argument like the ports beside it. Only so a human can watch the
# curve arrive — set it to 0 in the node panel for a sweep.
"params": {"pace": 0.15},
"requires": [
{"name": "dataset", "dtype": "artifact"},
{"name": "learning_rate", "dtype": "float"},
{"name": "epochs", "dtype": "int"},
{"name": "pace", "dtype": "float"},
],
"provides": [
# The curve. `stream` says this port publishes repeatedly while the
@@ -273,8 +276,6 @@ INPUTS = [
{"spec": {"name": "samples", "dtype": "int"}, "initial": 200},
{"spec": {"name": "learning_rate", "dtype": "float"}, "initial": 0.2},
{"spec": {"name": "epochs", "dtype": "int"}, "initial": 40},
# Only so a human can watch the curve arrive; set it to 0 for a sweep.
{"spec": {"name": "pace", "dtype": "float"}, "initial": 0.15},
]
#: What a run reports as its result. Everything else the flow computed stays
@@ -448,7 +449,8 @@ def main() -> int:
print(
f"\nOpen /view/{PANEL}, then start a run:\n"
f' POST {API}/api/v1/runs/flows/{FLOW} {{"params": {{}}}}\n'
"The curve fills in as it trains. For a sweep, set pace to 0."
"The curve fills in as it trains. For a sweep, set the training\n"
"node's 'pace' setting to 0."
)
return 0