Turns natural-language engineering tasks into validated, sandboxed, auditable workflows - powered by SmartMDAO.
Project description
smartmdao-agents
Turns a natural-language engineering task into a validated, sandboxed, auditable engineering workflow — a coupled analysis, a design study, an optimization under constraints. Hand it a task description and a way to call your LLM; it hands back a resolved result, or a structured reason why not.
Built on SmartMDAO, a Pythonic multidisciplinary analysis & optimization (MDA/MDAO) framework — the engine underneath.
pip install smartmdao-agents
Example: sizing a storage container
Write a smartmdao MDAO problem for designing an open-top rectangular box (no lid) with a fixed height of 10. Design variables are
widthanddepth. Minimize the total material used (surface area: the bottom plus the four sides), subject to the box holding at least a volume of 200 (width * depth * height >= 200).
@pipeline.step(outputs=["surface_area", "volume_slack"])
def evaluate_box(width, depth, height):
bottom = width * depth
sides = 2 * (width * height) + 2 * (depth * height)
surface_area = bottom + sides
volume = width * depth * height
return surface_area, volume - MIN_VOLUME # a slack, not the raw volume
evaluator = PipelineEvaluator(pipeline, design_vars=["width", "depth"], constants={"height": HEIGHT})
problem = OptimizationProblem(
evaluator=evaluator,
initial_guess=[5.0, 5.0],
bounds=[(0.1, 100.0), (0.1, 100.0)],
objective="surface_area",
constraints=[ConstraintSpec(name="volume_slack", kind="ineq", multiplier=1.0)],
)
Real, not hypothetical: this exact task description was sent to a freshly-spawned, isolated model
instance with no other context, and this is the exact code it produced - nothing hand-written,
nothing edited (full fixture). Converges to
width = depth ≈ 4.472, matching the textbook-optimal square-base ratio (w = d = √(V/h)) for
this problem - an independent check that the answer is actually right, not just that nothing
crashed. See docs/dogfooding.md for the full methodology, three more real
examples, and the project roadmap.
How it works
This repo never calls an LLM itself - no SDK dependency, no provider lock-in. You supply
call_model: a plain function taking a prompt string and returning the model's raw text
response. Everything else - building the prompt from the curated reference doc, extracting code
from the response, validating it, running it in a sandboxed subprocess, and retrying with the
error fed back on failure - is handled for you.
Source: assets/architecture.mmd - regenerate the SVG at mermaid.ink if the flow changes.
from smartmdao_agents import run_agent_task
def call_model(prompt: str) -> str:
return my_llm_client.complete(prompt) # wrap whatever you're already using
record = run_agent_task(
"compute the safety factor of a structural bracket given the applied load, "
"cross-sectional area, and material yield strength",
{"load_n": 5000.0, "area_mm2": 120.0, "yield_strength_mpa": 250.0},
call_model=call_model,
max_attempts=3,
)
record.status # "success" | "validation_failed" | "execution_failed" | "timeout"
record.outputs # every resolved variable, or None on failure
Already have code (not fresh off an LLM call) and just want it validated/sandboxed/recorded?
run_agent_pipeline(code, inputs) skips the prompt/extract/retry machinery - run_agent_task is
built on top of it, not a replacement. It's also what the CLI uses:
smartmdao-agents run --file pipeline.py --inputs '{"width": 2.0}'
Known gotchas
Found by dogfooding (see docs/dogfooding.md), fixed in reference.md, and
pinned down with regression tests so they can't silently regress.
| Gotcha | What goes wrong | Fix |
|---|---|---|
| Cycle execution order | Cyclic steps run in alphabetical order by function name, every iteration. A step seeding a cycle via a Python default has to sort before the step consuming its output, or the first iteration fails. | Name the seeding step earlier alphabetically (e.g. a_propose / b_review). |
Silent objective default |
OptimizationProblem.objective defaults to the literal string "objective", which almost never matches a real output name - fails with an opaque KeyError if left unset. |
Always set objective= explicitly. |
| Constraint on a raw value | ConstraintSpec on a raw output only enforces value >= 0. A real threshold is silently ignored and the run still reports success - the most severe finding, since nothing looks wrong. |
Encode the threshold as a slack (value - threshold) as the pipeline output, not the raw value. |
Development
uv sync
uv run pytest # 100% coverage enforced via pytest.ini
Depends on smartmdao from PyPI (>=1.5.0, the first
release with non-numeric convergence support). License: MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file smartmdao_agents-0.1.2.tar.gz.
File metadata
- Download URL: smartmdao_agents-0.1.2.tar.gz
- Upload date:
- Size: 19.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e4ebfc83270458464cd2a5ef66ced6d0cff4e7212ffba987cf8a96b781e06ea5
|
|
| MD5 |
bf396479d32de4ca0c03a22a26aacac1
|
|
| BLAKE2b-256 |
fff5a790ae492fef3642475bc7bc67d691c6f0d66be4ee2e0b4227ebb259ccc8
|
File details
Details for the file smartmdao_agents-0.1.2-py3-none-any.whl.
File metadata
- Download URL: smartmdao_agents-0.1.2-py3-none-any.whl
- Upload date:
- Size: 24.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ef4dac9d5486c7ff4ca2414d96b6c4506a1b3fb30259524713a594e7394a9fc
|
|
| MD5 |
913693a625792e1518dab601feac9edd
|
|
| BLAKE2b-256 |
d04236f599e0e9bc5a16542343bd60adcc22f31867e2ebabded6e4e36f81890a
|