Skip to main content

Turns natural-language engineering tasks into validated, sandboxed, auditable workflows - powered by SmartMDAO.

Project description

smartmdao-agents

CI PyPI version Python versions License: MIT

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 width and depth. 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.

Architecture: call_model supplies the LLM call; run_agent_task builds the prompt, validates, sandboxes, and retries with the error fed back on failure

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

smartmdao_agents-0.1.2.tar.gz (19.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

smartmdao_agents-0.1.2-py3-none-any.whl (24.9 kB view details)

Uploaded Python 3

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

Hashes for smartmdao_agents-0.1.2.tar.gz
Algorithm Hash digest
SHA256 e4ebfc83270458464cd2a5ef66ced6d0cff4e7212ffba987cf8a96b781e06ea5
MD5 bf396479d32de4ca0c03a22a26aacac1
BLAKE2b-256 fff5a790ae492fef3642475bc7bc67d691c6f0d66be4ee2e0b4227ebb259ccc8

See more details on using hashes here.

File details

Details for the file smartmdao_agents-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for smartmdao_agents-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 3ef4dac9d5486c7ff4ca2414d96b6c4506a1b3fb30259524713a594e7394a9fc
MD5 913693a625792e1518dab601feac9edd
BLAKE2b-256 d04236f599e0e9bc5a16542343bd60adcc22f31867e2ebabded6e4e36f81890a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page