Skip to content

fix(ai): Draw diagrams from structured data - #381

Merged
dboyd13 merged 2 commits into
mainfrom
fix/generate-diagrams-from-structured-data
Nov 11, 2026
Merged

dboyd13 merged 2 commits into
mainfrom
fix/generate-diagrams-from-structured-data

Conversation

@jessieweiyi

@jessieweiyi jessieweiyi commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Issue # (if applicable)

N/A

Reason for this change

The diagram agents wrote Python for the diagrams library, and the tools ran it to draw the SVG. A small slip in that code, such as a wrong import or a bad constructor argument, failed the whole step, and errors came back as Python tracebacks. Structured input fixes this: the model fills in a fixed shape, and the tool draws it the same way every time.

This affects CLI and MCP server users only. The web app and the extensions don't change. The MCP server doesn't expose the diagram tools directly; they run inside the workflow.

Description of changes

Area Change
threat_composer_dia_dfd Takes trust_boundaries, elements and flows instead of code. Each flow has a required id matching DF1…DF9999, unique within the diagram, and is drawn as DF1: <label>. The threats agent relies on these ids.
threat_composer_dia_architecture Takes clusters, nodes and edges instead of code. Icons are names like aws.compute.EC2, checked against the icons the diagrams package ships. A bare class name such as EC2 works when it is unique. A node without an icon is drawn as a plain box. Edges take an optional style (solid, dashed, dotted, bold).
Shared renderer Both tools validate their input and draw it with one renderer in threat_composer_dia_common.py. Labels are drawn as plain text.
Tool input schemas Each tool's inputSchema is generated from its pydantic model, with $refs inlined, so the schema the AI model sees always matches what the tool accepts. Field help comes from Field(description=...).
Validation Pydantic models reject unknown fields, unknown ids, duplicate ids (including duplicate DF ids), parent cycles and nesting deeper than 8. They cap sizes at 300 nodes, 600 edges, 100 groups and 200-character labels. Control characters in labels become spaces. Each error names the field, so the model can fix it and retry; up to 20 errors are reported at once.
Unknown icons The error suggests up to 5 close matches, for example aws.compute.Lambda for aws.compute.Lamda.
threat_composer_dia_list_icons Lists the same names the architecture tool accepts. It answers every query from the icon index and never builds file paths from its input (invariant 6, "AI file access"). The response format is unchanged.
Diagram agents Both system prompts describe the JSON input. The DFD prompt asks for the DF identifier in id and the description in label. The examples tool, which returned Python snippets, is removed.
Dependencies bandit moves from runtime to dev dependencies: only the removed code scanner used it at runtime. pydantic>=2,<3 is now declared directly, since the tools import it. strands-agents-tools is bounded to >=0.2,<0.9: 0.9.0 removed strands_tools.file_read, which the file read tool wraps, and uv tool install and uvx ignore uv.lock, so an install from git picked 0.9.0 and the CLI failed on import. uv.lock already pinned 0.8.6. It adds only bandit and stevedore; no existing versions change.

Describe any new or updated permissions being added

None.

Description of how you validated changes

  • tests/tools/test_diagram_tools.py covers input validation, DF ids, generated schemas, icon names and suggestions, label rendering, rendering from a worker thread, list_icons making no file system calls on its input (test_ai_file_access_list_icons_ignores_paths), and a check that the package makes no exec/eval/compile/__import__ calls.
  • tests/test_dependency_bounds.py checks that the strands-agents-tools bound allows 0.8.6 and excludes 0.9.0. It fails with the old <1 bound.
  • pnpm nx run threat-composer-ai:build (install, ruff check and format, tests) exits 0: 242 passed, 6 skipped. The 6 skips are in tests/eval/test_fixture.py. Graphviz was installed locally, so the render tests ran; CI doesn't install Graphviz, so they skip there.
  • pnpm lint, which .husky/pre-commit runs, exits 0.
  • Quality eval against Bedrock (global.anthropic.claude-sonnet-5, eval/browser-extension.json): PASS

Checklist

  • The title follows type(scope): Subject. It becomes the commit message on main.
  • The build passes locally. See "Verify a change" in AGENTS.md.
  • If behaviour changed, the docs are updated in this pull request, or the description says why not.
  • If this touches an area the threat model covers, the threat model is updated, or the description says why not.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

…ted code

The DFD and architecture diagram tools take the diagram as structured data,
validate it, and draw it with one shared renderer. The examples tool and the
code scanner are removed.

- Generate each tool's input schema from its pydantic model, with refs inlined.
- Give DFD flows a required, unique id (DF1, DF2, ...) drawn as "DF1: label".
- Answer list_icons queries from the icon index only.
- Suggest close icon names when an icon is unknown.
- Keep bandit as a dev dependency and bound pydantic below 3.
strands-agents-tools 0.9.0 removed strands_tools.file_read, which the file
read tool wraps. uv tool install and uvx ignore uv.lock and picked 0.9.0, so
the CLI failed on import. The lock already pins 0.8.6; no versions change.
@dboyd13 dboyd13 changed the title fix(ai): Draw diagrams from structured data instead of running generated code fix(ai): Draw diagrams from structured data Nov 11, 2026
@dboyd13
dboyd13 self-requested a review November 11, 2026 07:02

@dboyd13 dboyd13 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

@dboyd13
dboyd13 marked this pull request as ready for review November 11, 2026 07:29
@dboyd13
dboyd13 merged commit 8885b92 into main Nov 11, 2026
8 of 9 checks passed
@dboyd13
dboyd13 deleted the fix/generate-diagrams-from-structured-data branch November 11, 2026 07:32
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.0.92 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

This branch was previously deployed

1 inactive deployment
eval — 9b99f368 Deployed Nov 11, 2026 by jessieweiyi via quality #49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants