Skip to content

feat: include simulator flow nodes from other files - #1032

Open
chenghao-mou wants to merge 6 commits into
chenghao/feat/AGT-3725-public-simulator-flow-schemafrom
chenghao/feat/AGT-3707-simulator-flow-includes
Open

chenghao-mou wants to merge 6 commits into
chenghao/feat/AGT-3725-public-simulator-flow-schemafrom
chenghao/feat/AGT-3707-simulator-flow-includes

Conversation

@chenghao-mou

@chenghao-mou chenghao-mou commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

Shared nodes such as a menu or a person no longer need copying into every scenarios file:

include: [nodes/menus.yaml, nodes/people.yaml]
scenarios:
  - label: menu-to-sam
    start: menu   # defined in nodes/menus.yaml

Paths are relative to the naming file, includes nest, and each file loads once. An included file holds only nodes and include. Cycles, a node defined in two files, and missing paths fail with the files named. Includes resolve on the client, so the server still receives one flat nodes map.

Not in this PR: the path-based Python loader in agents-private, which AGT-3707 also asks for.

Warning

Stacked on #1031.

Addresses AGT-3707

Initial prompt and agent context

Model: Claude Opus 5.5

does it support reading from another file for the steps

Can you open a stacked PR on that for this

@chenghao-mou
chenghao-mou force-pushed the chenghao/feat/AGT-3707-simulator-flow-includes branch from e2fbefc to fb07d1c Compare October 13, 2026 14:04
@chenghao-mou chenghao-mou changed the title feat: include simulator flow steps from other files feat: include simulator flow nodes from other files Oct 13, 2026
@chenghao-mou
chenghao-mou force-pushed the chenghao/feat/AGT-3707-simulator-flow-includes branch 4 times, most recently from eb74116 to 7e50e50 Compare October 21, 2026 11:31
@chenghao-mou
chenghao-mou added this pull request to stack #1068 October 21, 2026 11:50
@chenghao-mou
chenghao-mou force-pushed the chenghao/feat/AGT-3707-simulator-flow-includes branch from 7e50e50 to ee4fd5b Compare October 21, 2026 11:50
@chenghao-mou
chenghao-mou marked this pull request as ready for review October 21, 2026 11:50
A scenarios file had to hold every node its scenarios use, so shared
nodes such as a menu or a person were copied into each file. A top-level
`include` list now takes the nodes of other files. Paths are relative to
the file that names them, includes nest, and each file loads once by its
real path. An included file holds only `nodes` and `include`.

Includes resolve here, on the client: the server receives one flat
`nodes` map, so the protocol and the server do not change.

Addresses AGT-3707
@chenghao-mou
chenghao-mou force-pushed the chenghao/feat/AGT-3707-simulator-flow-includes branch from c2eee74 to 6dc2ac4 Compare October 21, 2026 14:48
…to chenghao/feat/AGT-3707-simulator-flow-includes
…to chenghao/feat/AGT-3707-simulator-flow-includes
…to chenghao/feat/AGT-3707-simulator-flow-includes

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Devin Review

Comment on lines +52 to +65
real, err := filepath.EvalSymlinks(path)
if err != nil {
return nil, err
}
r := &nodeResolver{
root: filepath.Dir(real),
loaded: map[string]bool{real: true},
chain: []string{real},
nodes: map[string]sourcedNode{},
}
if err := r.add(real, nodes); err != nil {
return nil, err
}
if err := r.includeAll(real, include); err != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Relative includes resolve beside symlink targets

When a file is opened through a symlink, resolveNodes looks for its relative includes beside the target. A neighboring include fails to load or resolves to a different file.

Learn more

The resolver needs two identities for each file: its path as included, for resolving its relative includes, and its canonical path, for detecting cycles and shared files. resolveNodes passes the canonical path to includeAll, and includeAll repeats that choice for nested files. If a symlink and its target reside in different directories, relative paths are searched beside the target rather than beside the symlink.

Example: /app/scenarios.yaml links to /shared/scenarios.yaml, which says include: [nodes.yaml]. With /app/nodes.yaml present and /shared/nodes.yaml absent, loading /app/scenarios.yaml fails instead of loading /app/nodes.yaml.

Recommended fix: Carry the path used to open each file through includeAll and load for relative path resolution. Keep EvalSymlinks only for loaded and chain identities; test both a symlinked root and a symlinked nested include.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant