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:
@@ -73,6 +73,9 @@ const SECTION = PANEL_SECTION
|
||||
/** Settings the engine reads itself, so they are not the author's to name. */
|
||||
const RESERVED_PARAMS = new Set(["synchronous"])
|
||||
|
||||
/** A setting reaches the function by name, so the name has to be one. */
|
||||
const IDENTIFIER = /^[A-Za-z_]\w*$/
|
||||
|
||||
/**
|
||||
* A text field that offers what is already in use elsewhere.
|
||||
*
|
||||
@@ -421,7 +424,9 @@ function FreeParamsForm({
|
||||
const entries = Object.entries(params).filter(([key]) => !reserved.has(key))
|
||||
|
||||
const rename = (from: string, to: string) => {
|
||||
if (to === from) return
|
||||
// A setting is an argument of `process`, so a name it cannot take is not
|
||||
// a rename — it is a typo on its way to a node that will not load.
|
||||
if (to === from || !IDENTIFIER.test(to)) return
|
||||
// Rebuilt rather than patched, so the settings keep the order they were
|
||||
// typed in instead of jumping around as one is renamed.
|
||||
const next: Record<string, unknown> = {}
|
||||
@@ -453,7 +458,8 @@ function FreeParamsForm({
|
||||
|
||||
{entries.length === 0 ? (
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Values your code reads from <code>params</code>.
|
||||
Constants of this node, passed to <code>process</code> by name like
|
||||
its inputs.
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
@@ -855,7 +861,7 @@ const SCAFFOLD_SHAPE = (() => {
|
||||
const value = Object.values(PLACEHOLDER).map(quote).join("|")
|
||||
const entry = `"[^"]+": (?:${value})`
|
||||
return new RegExp(
|
||||
`^${quote(SCAFFOLD_DOC)}\\n\\n\\ndef process\\(\\w+(?:, \\w+)*\\):\\n return \\{(?:${entry}(?:, ${entry})*)?\\}\\n$`,
|
||||
`^${quote(SCAFFOLD_DOC)}\\n\\n\\ndef process\\((?:\\w+(?:, \\w+)*)?\\):\\n return \\{(?:${entry}(?:, ${entry})*)?\\}\\n$`,
|
||||
)
|
||||
})()
|
||||
|
||||
@@ -863,20 +869,30 @@ const SCAFFOLD_SHAPE = (() => {
|
||||
const portName = (spec: MessageSpec) =>
|
||||
spec.port || (spec.name ?? "").split(".").pop() || ""
|
||||
|
||||
/** A `process` that takes this node's inputs and returns its outputs. */
|
||||
/**
|
||||
* A `process` that takes this node's inputs and settings, and returns its
|
||||
* outputs.
|
||||
*
|
||||
* Both arrive by name, so both are arguments — the ports first, in the order
|
||||
* they are declared, then the settings.
|
||||
*/
|
||||
function scaffoldFor(node: NodeDef_Input): string {
|
||||
const args = [
|
||||
...new Set(
|
||||
(node.requires ?? [])
|
||||
.map(portName)
|
||||
// Anything else cannot be a keyword argument, so it cannot be a port.
|
||||
.filter((port) => /^[A-Za-z_]\w*$/.test(port) && port !== "params"),
|
||||
[
|
||||
...(node.requires ?? []).map(portName),
|
||||
...Object.keys(node.params ?? {}).filter(
|
||||
(name) => !RESERVED_PARAMS.has(name),
|
||||
),
|
||||
]
|
||||
// Anything else cannot be a keyword argument, so it cannot be one.
|
||||
.filter((name) => IDENTIFIER.test(name)),
|
||||
),
|
||||
]
|
||||
const returns = (node.provides ?? [])
|
||||
.filter((spec) => portName(spec))
|
||||
.map((spec) => `"${portName(spec)}": ${PLACEHOLDER[spec.dtype ?? "float"]}`)
|
||||
return `${SCAFFOLD_DOC}\n\n\ndef process(${[...args, "params"].join(
|
||||
return `${SCAFFOLD_DOC}\n\n\ndef process(${args.join(
|
||||
", ",
|
||||
)}):\n return {${returns.join(", ")}}\n`
|
||||
}
|
||||
@@ -998,13 +1014,13 @@ function PanelBody({
|
||||
type={node.type}
|
||||
schema={nodeType?.params_schema}
|
||||
params={node.params ?? {}}
|
||||
onChange={(params) => onChange({ ...node, params })}
|
||||
onChange={(params) => editNode({ ...node, params })}
|
||||
/>
|
||||
{nodeType?.free_params ? (
|
||||
<FreeParamsForm
|
||||
params={node.params ?? {}}
|
||||
reserved={RESERVED_PARAMS}
|
||||
onChange={(params) => onChange({ ...node, params })}
|
||||
onChange={(params) => editNode({ ...node, params })}
|
||||
/>
|
||||
) : null}
|
||||
{hasSource ? (
|
||||
|
||||
Reference in New Issue
Block a user