From 006f5fb3b226d69680437069f6ccdec838a2fd41 Mon Sep 17 00:00:00 2001 From: matthewli125 Date: Tue, 13 Jan 2026 12:42:01 -0800 Subject: [PATCH 01/12] add Agentlogger and tests; integrate with existing low fidelity agent; fix some pylance issues --- src/autoboltagent/agents.py | 37 ++++-- src/autoboltagent/tools/high_fidelity_tool.py | 6 +- src/autoboltagent/tools/logger.py | 116 ++++++++++++++++++ tests/test_agents.py | 14 ++- tests/test_logger.py | 103 ++++++++++++++++ 5 files changed, 263 insertions(+), 13 deletions(-) create mode 100644 src/autoboltagent/tools/logger.py create mode 100644 tests/test_logger.py diff --git a/src/autoboltagent/agents.py b/src/autoboltagent/agents.py index 35a19fb..0fc6416 100644 --- a/src/autoboltagent/agents.py +++ b/src/autoboltagent/agents.py @@ -7,8 +7,10 @@ ) from .tools import AnalyticalTool, FiniteElementTool +from .tools.logger import AgentLogger -class GuessingAgent(smolagents.ToolCallingAgent): + +class GuessingAgent(smolagents.agents.ToolCallingAgent): """ An agent that makes guesses without using any tools. @@ -16,7 +18,7 @@ class GuessingAgent(smolagents.ToolCallingAgent): It is designed to provide initial estimates or solutions based on its knowledge and reasoning capabilities. """ - def __init__(self, model: smolagents.Model) -> None: + def __init__(self, model: smolagents.models.Model) -> None: """ Initializes a GuessingAgent that does not use any tools. @@ -33,7 +35,7 @@ def __init__(self, model: smolagents.Model) -> None: ) -class LowFidelityAgent(smolagents.ToolCallingAgent): +class LowFidelityAgent(smolagents.agents.ToolCallingAgent): """ An agent that utilizes a low-fidelity analytical tool for bolted connection design. @@ -41,24 +43,43 @@ class LowFidelityAgent(smolagents.ToolCallingAgent): It is designed to provide solutions based on simplified models and assumptions, making it suitable for quick estimates and preliminary designs. """ - def __init__(self, model: smolagents.Model) -> None: + def __init__(self, model: smolagents.models.Model, agent_id: str, run_id: str, target_fos: float, agent_logger: AgentLogger|None = None, max_steps=20) -> None: """ Initializes a LowFidelityAgent that uses an analytical tool. Args: model: An instance of smolagents.Model to be used by the agent. """ + + self.agent_logger = agent_logger + self.agent_id = agent_id + self.run_id = run_id + self.target_fos = target_fos + + callbacks = [self.log] if self.agent_logger else [] + super().__init__( name="LowFidelityAgent", tools=[AnalyticalTool()], add_base_tools=False, model=model, instructions=BASE_INSTRUCTIONS + TOOL_USING_INSTRUCTION, + step_callbacks = callbacks, verbosity_level=2, + max_steps=max_steps ) + def log(self, step, agent): + if self.agent_logger and step.__class__.__name__ == "ActionStep": + self.agent_logger.log( + agent_id=self.agent_id, + run_id=self.run_id, + target_fos=self.target_fos, + action_step=step + ) + -class HighFidelityAgent(smolagents.ToolCallingAgent): +class HighFidelityAgent(smolagents.agents.ToolCallingAgent): """ An agent that utilizes a high-fidelity finite element analysis tool for bolted connection design. @@ -66,7 +87,7 @@ class HighFidelityAgent(smolagents.ToolCallingAgent): It is designed to provide accurate and reliable solutions based on comprehensive models, making it suitable for """ - def __init__(self, model: smolagents.Model) -> None: + def __init__(self, model: smolagents.models.Model) -> None: """ Initializes a HighFidelityAgent that uses a finite element tool. @@ -83,7 +104,7 @@ def __init__(self, model: smolagents.Model) -> None: ) -class DualFidelityAgent(smolagents.ToolCallingAgent): +class DualFidelityAgent(smolagents.agents.ToolCallingAgent): """ An agent that utilizes both low-fidelity and high-fidelity tools for bolted connection design. @@ -91,7 +112,7 @@ class DualFidelityAgent(smolagents.ToolCallingAgent): It is designed to provide solutions that balance speed and accuracy by using the low-fidelity tool """ - def __init__(self, model: smolagents.Model) -> None: + def __init__(self, model: smolagents.models.Model) -> None: """ Initializes a DualFidelityAgent that uses both analytical and finite element tools. diff --git a/src/autoboltagent/tools/high_fidelity_tool.py b/src/autoboltagent/tools/high_fidelity_tool.py index 02a7bf9..52e9f73 100644 --- a/src/autoboltagent/tools/high_fidelity_tool.py +++ b/src/autoboltagent/tools/high_fidelity_tool.py @@ -1,10 +1,11 @@ import autobolt import smolagents +from typing import Dict, Any, Union, cast from .inputs import INPUTS -class FiniteElementTool(smolagents.Tool): +class FiniteElementTool(smolagents.tools.Tool): """ A tool that calculates the factor of safety for a bolted connection using finite element analysis. @@ -15,7 +16,8 @@ class FiniteElementTool(smolagents.Tool): name = "fea_fos_calculation" description = "Calculates the factor of safety using finite element analysis." - inputs = INPUTS + input_type = dict[str, dict[str, Union[str, type, bool]]] + inputs: input_type = cast(input_type,INPUTS) output_type = "number" diff --git a/src/autoboltagent/tools/logger.py b/src/autoboltagent/tools/logger.py new file mode 100644 index 0000000..c71a497 --- /dev/null +++ b/src/autoboltagent/tools/logger.py @@ -0,0 +1,116 @@ +from sqlalchemy import create_engine + +from sqlalchemy.orm import declarative_base, Session, sessionmaker, Mapped, mapped_column +from contextlib import contextmanager + +from pathlib import Path + +from datetime import datetime, timezone + +Base = declarative_base() + +class Iteration(Base): + __tablename__ = "iterations" + + id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) + agent_id: Mapped[str] = mapped_column() + run_id: Mapped[str] = mapped_column() + iteration_no: Mapped[int] = mapped_column() + + start_time: Mapped[datetime] = mapped_column(nullable=True) + end_time: Mapped[datetime] = mapped_column(nullable=True) + + status: Mapped[str] = mapped_column(nullable=True) + tool_call: Mapped[str] = mapped_column(nullable=True) + observations: Mapped[str] = mapped_column(nullable=True) + target_fos: Mapped[float] = mapped_column(nullable=True) + + failure_reason: Mapped[str] = mapped_column(nullable=True) + llm_output: Mapped[str] = mapped_column(nullable=True) + error_message: Mapped[str] = mapped_column(nullable=True) + +class AgentLogger: + _instance = None + + def connect_to_db(self, db_url: str): + self.db_url = db_url + self.engine = create_engine(db_url, future=True, pool_pre_ping=True) + + with self.engine.connect() as conn: + conn.exec_driver_sql("PRAGMA journal_mode=WAL;") + conn.exec_driver_sql("PRAGMA synchronous=NORMAL;") + + Base.metadata.create_all(self.engine) + + self.db_session = sessionmaker(bind=self.engine, expire_on_commit=False, future=True) + + def __new__(cls, db_url: str): + if not cls._instance: + cls._instance = super().__new__(cls) + cls._instance.db_url = None + cls._instance.engine = None + cls._instance.db_session = None + cls._instance.connect_to_db(db_url) + return cls._instance + + @classmethod + def reset(cls): + if not cls._instance: + return + + inst = cls._instance + + if inst.engine: + inst.engine.dispose() + + if inst.db_url: + for suffix in ("", "-wal", "-shm"): + file_path = Path(inst.db_url.replace("sqlite:///", "") + suffix) + file_path.unlink(missing_ok=True) + + cls._instance = None + + def log( + self, + run_id, + agent_id, + target_fos, + action_step + ): + + iteration_no = action_step.step_number + start_dt = datetime.fromtimestamp(action_step.timing.start_time, tz=timezone.utc) + end_dt = datetime.fromtimestamp(action_step.timing.end_time, tz=timezone.utc) + + error = getattr(action_step, "error", None) + tool_calls = getattr(action_step, "tool_calls", None) + observations = getattr(action_step, "observations", None) + llm_message = getattr(action_step, "model_output_message", None) + llm_output = getattr(llm_message, "content", None) + + print(tool_calls) + print(error) + print(observations) + print(llm_message) + print(action_step.token_usage) + + with self.db_session() as session: + session.add( + Iteration( + run_id=run_id, + agent_id=agent_id, + iteration_no=iteration_no, + start_time=start_dt, + end_time=end_dt, + tool_call=str(tool_calls[0] if tool_calls else None), + observations=observations, + target_fos=target_fos, + llm_output=llm_output, + error_message=error.message if error else None + ) + ) + session.commit() + + + + \ No newline at end of file diff --git a/tests/test_agents.py b/tests/test_agents.py index d002ba4..4fe66f3 100644 --- a/tests/test_agents.py +++ b/tests/test_agents.py @@ -10,7 +10,7 @@ def is_macos() -> bool: return platform.system() == "Darwin" -def get_testing_model() -> smolagents.Model: +def get_testing_model() -> smolagents.models.Model: if is_macos(): # Use a local model on macOS for faster testing return smolagents.MLXModel( @@ -18,7 +18,7 @@ def get_testing_model() -> smolagents.Model: ) else: # Use the smallest Instruct model available for fast CI feedback - return smolagents.TransformersModel( + return smolagents.models.TransformersModel( model_id="HuggingFaceTB/SmolLM-135M-Instruct", max_new_tokens=200, # Keep generation short for speed ) @@ -38,7 +38,15 @@ def test_guessing_agent(): def test_low_fidelity_agent(): # Create the LowFidelityAgent and run it - response = autoboltagent.LowFidelityAgent(get_testing_model()).run( + agent = autoboltagent.LowFidelityAgent( + model=get_testing_model(), + agent_id="low fidelity agent", + run_id="test 1", + target_fos=3.0, + max_steps=5 + ) + + response = agent.run( autoboltagent.prompts.EXAMPLE_TASK_INSTRUCTIONS ) diff --git a/tests/test_logger.py b/tests/test_logger.py new file mode 100644 index 0000000..23179d2 --- /dev/null +++ b/tests/test_logger.py @@ -0,0 +1,103 @@ +from autoboltagent.tools.logger import AgentLogger +from autoboltagent.tools.logger import Iteration +from smolagents import ActionStep, Timing, ToolCall, ChatMessage, MessageRole, AgentError +from sqlalchemy import create_engine, select +from sqlalchemy.orm import Session +from datetime import datetime, timezone +import pytest + +db_url = "sqlite:///agent_logs_test.db" + +@pytest.fixture +def logger(): + """ + Fixture to create a new AgentLogger with a fresh db per test + """ + AgentLogger.reset() + logger = AgentLogger(db_url) + yield logger + AgentLogger.reset() + +def get_log_session(db_url): + """ + Helper function to get db session from url + """ + engine = create_engine(db_url) + return Session(engine) + +def test_logger_empty_when_fresh(logger): + """ + Test to see if the logger db is empty when fresh + """ + with get_log_session(db_url) as session: + iterations = session.query(Iteration).all() + + assert len(iterations) == 0 + +def test_logger_one_write_fields_persist(logger): + """ + Test one log write and see if all fields persists in the db + """ + start_time = datetime.now(timezone.utc).timestamp() + end_time = datetime.now(timezone.utc).timestamp() + + step = ActionStep( + step_number=1, + timing=Timing( + start_time=start_time, + end_time=end_time + ), + observations = "observation observation", + tool_calls=[ToolCall(name="tool call", arguments={"asdf": 1}, id="1341fad")], + model_output_message=ChatMessage(role=MessageRole("assistant"), content="LLM output 1"), + error=None + ) + + logger.log( + run_id="run_1", + agent_id="agent_1", + target_fos=1, + action_step=step + ) + + with get_log_session(db_url) as session: + iteration = session.query(Iteration).one() + + assert iteration.run_id == "run_1" + assert iteration.agent_id == "agent_1" + assert iteration.iteration_no == 1 + assert type(iteration.start_time) == datetime + assert type(iteration.end_time) == datetime + assert iteration.target_fos == 1 + assert iteration.llm_output == "LLM output 1" + assert iteration.error_message == None + + +def test_logger_large_write(logger): + """ + Test 50 log writes and see if db contains 50 rows + """ + for i in range(50): + start_time = datetime.now(timezone.utc).timestamp() + end_time = datetime.now(timezone.utc).timestamp() + step = ActionStep( + step_number=1, + timing=Timing( + start_time=start_time, + end_time=end_time + ), + observations = "observation observation", + tool_calls=[ToolCall(name="tool call", arguments={"asdf": 1}, id="1341fad")], + model_output_message=ChatMessage(role=MessageRole("assistant"), content=f"LLM output {i}"), + error=None + ) + logger.log( + run_id="run_1", + agent_id="agent_1", + target_fos=1, + action_step=step + ) + with get_log_session(db_url) as session: + iterations = session.query(Iteration).all() + + assert len(iterations) == 50 \ No newline at end of file From 189c5e8ecc815fcb731a76472b84a71c6d807a2c Mon Sep 17 00:00:00 2001 From: matthewli125 Date: Wed, 14 Jan 2026 16:24:22 -0800 Subject: [PATCH 02/12] update gitignore to include db files --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 441facd..95e55f1 100644 --- a/.gitignore +++ b/.gitignore @@ -207,3 +207,9 @@ cython_debug/ marimo/_static/ marimo/_lsp/ __marimo__/ + + +# +autobolt/ +*.db-* +*.db \ No newline at end of file From 372c311273a071fc81f7b4e116ef51da88f30acf Mon Sep 17 00:00:00 2001 From: matthewli125 Date: Wed, 14 Jan 2026 16:34:41 -0800 Subject: [PATCH 03/12] update environment to include sqlalchemy --- environment.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/environment.yml b/environment.yml index 8d41493..465a54d 100644 --- a/environment.yml +++ b/environment.yml @@ -17,4 +17,5 @@ dependencies: - pandas - "autobolt @ git+https://github.com/sriyanc2001/AutoBolt.git" - black - - pytest \ No newline at end of file + - pytest + - sqlalchemy \ No newline at end of file From c58a39068ff788656b0a74c95a3f0c4478224d91 Mon Sep 17 00:00:00 2001 From: matthewli125 Date: Wed, 21 Jan 2026 10:27:35 -0800 Subject: [PATCH 04/12] make logging more resilient --- src/autoboltagent/tools/logger.py | 50 ++++++++++++++++++------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/autoboltagent/tools/logger.py b/src/autoboltagent/tools/logger.py index c71a497..e1e7db7 100644 --- a/src/autoboltagent/tools/logger.py +++ b/src/autoboltagent/tools/logger.py @@ -36,13 +36,16 @@ def connect_to_db(self, db_url: str): self.db_url = db_url self.engine = create_engine(db_url, future=True, pool_pre_ping=True) - with self.engine.connect() as conn: - conn.exec_driver_sql("PRAGMA journal_mode=WAL;") - conn.exec_driver_sql("PRAGMA synchronous=NORMAL;") + try: + with self.engine.connect() as conn: + conn.exec_driver_sql("PRAGMA journal_mode=WAL;") + conn.exec_driver_sql("PRAGMA synchronous=NORMAL;") - Base.metadata.create_all(self.engine) + Base.metadata.create_all(self.engine) - self.db_session = sessionmaker(bind=self.engine, expire_on_commit=False, future=True) + self.db_session = sessionmaker(bind=self.engine, expire_on_commit=False, future=True) + except Exception as e: + raise IOError("Failed to connect to DB, check if file in use", repr(e)) def __new__(cls, db_url: str): if not cls._instance: @@ -94,23 +97,30 @@ def log( print(llm_message) print(action_step.token_usage) - with self.db_session() as session: - session.add( - Iteration( - run_id=run_id, - agent_id=agent_id, - iteration_no=iteration_no, - start_time=start_dt, - end_time=end_dt, - tool_call=str(tool_calls[0] if tool_calls else None), - observations=observations, - target_fos=target_fos, - llm_output=llm_output, - error_message=error.message if error else None + try: + + with self.db_session() as session: + session.add( + Iteration( + run_id=run_id, + agent_id=agent_id, + iteration_no=iteration_no, + start_time=start_dt, + end_time=end_dt, + tool_call=str(tool_calls[0] if tool_calls else None), + observations=observations, + target_fos=target_fos, + llm_output=llm_output, + error_message=error.message if (error and error.message) else None + ) ) - ) - session.commit() + session.flush() + session.commit() + except Exception as e: + print("\n\n") + print(e) + print("\n\n") \ No newline at end of file From 1dd545511f4d076354c7bc4fe261bb4c74acfd26 Mon Sep 17 00:00:00 2001 From: matthewli125 Date: Wed, 21 Jan 2026 11:25:01 -0800 Subject: [PATCH 05/12] add verbose prompts and simplified tool --- src/autoboltagent/grammars.py | 74 +++++++++ src/autoboltagent/tools/low_fidelity_tool.py | 88 ++++++++++- src/autoboltagent/verbose_agents.py | 49 ++++++ src/autoboltagent/verbose_prompts.py | 150 +++++++++++++++++++ 4 files changed, 358 insertions(+), 3 deletions(-) create mode 100644 src/autoboltagent/grammars.py create mode 100644 src/autoboltagent/verbose_agents.py create mode 100644 src/autoboltagent/verbose_prompts.py diff --git a/src/autoboltagent/grammars.py b/src/autoboltagent/grammars.py new file mode 100644 index 0000000..ce4dfcd --- /dev/null +++ b/src/autoboltagent/grammars.py @@ -0,0 +1,74 @@ +# grammar that outputs low-fidelity tool call or final_answer +low_fidelity_agent_grammar = r""" +root ::= "\n" payload "\n" +payload ::= fos | final + +fos ::= "{\"name\": \"analytical_fos_calculation\", \"arguments\": " fos_args "}}" +fos_args ::= "{" ( num_field ", " dia_field ) | ( dia_field ", " num_field ) "}" +num_field ::= "\"num_bolts\": " int +dia_field ::= "\"bolt_diameter\": " number + +final ::= "{\"name\": \"final_answer\", \"arguments\": {\"answer\": " fos_args "}}}" + +int ::= digit+ +number ::= digit+ frac? +frac ::= "." digit{1,4} + +digit ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" +""" + +# grammar that outputs high-fidelity tool call or final_answer +high_fidelity_agent_grammar = r""" +root ::= "\n" payload "\n" +payload ::= fos | final + +fos ::= "{\"name\": \"fea_fos_calculation\", \"arguments\": " fos_args "}}" +fos_args ::= "{" ( num_field ", " dia_field ) | ( dia_field ", " num_field ) "}" +num_field ::= "\"num_bolts\": " int +dia_field ::= "\"bolt_diameter\": " number + +final ::= "{\"name\": \"final_answer\", \"arguments\": {\"answer\": " fos_args "}}}" + +int ::= digit+ +number ::= digit+ frac? +frac ::= "." digit{1,4} + +digit ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" +""" + +# grammar that outputs both types of tool call and final_answer +dual_fidelity_agent_grammar = r""" +root ::= "\n" payload "\n" +payload ::= fos | final + +fos ::= "{\"name\": ("\"analytical_fos_calculation\"" | "\"fea_fos_calculation\""), \"arguments\": " fos_args "}}" +fos_args ::= "{" ( num_field ", " dia_field ) | ( dia_field ", " num_field ) "}" +num_field ::= "\"num_bolts\": " int +dia_field ::= "\"bolt_diameter\": " number + +final ::= "{\"name\": \"final_answer\", \"arguments\": {\"answer\": " fos_args "}}}" + +int ::= digit+ +number ::= digit+ frac? +frac ::= "." digit{1,4} + +digit ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" +""" + +low_fidelity_agent_grammar_original = r""" +root ::= "\n" payload "\n" +payload ::= fos | final + +fos ::= "{\"name\": \"analytical_fos_calculation\", \"arguments\": " fos_args "}}" +fos_args ::= "{" ( num_field ", " dia_field ) | ( dia_field ", " num_field ) "}" +num_field ::= "\"num_bolts\": " int +dia_field ::= "\"bolt_diameter\": " number + +final ::= "{\"name\": \"final_answer\", \"arguments\": {\"answer\": " fos_args "}}" + +int ::= digit+ +number ::= digit+ frac? +frac ::= "." digit{1,4} + +digit ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" +""" \ No newline at end of file diff --git a/src/autoboltagent/tools/low_fidelity_tool.py b/src/autoboltagent/tools/low_fidelity_tool.py index e250a0e..b5a62f9 100644 --- a/src/autoboltagent/tools/low_fidelity_tool.py +++ b/src/autoboltagent/tools/low_fidelity_tool.py @@ -1,5 +1,7 @@ import smolagents +from typing import Dict, Any, Union, cast + from .fastener_toolkit import ( get_joint_constant, get_tensile_stress_area, @@ -8,7 +10,7 @@ from .inputs import INPUTS -class AnalyticalTool(smolagents.Tool): +class AnalyticalTool(smolagents.tools.Tool): """ A tool that calculates the factor of safety for a bolted connection using analytical expressions. @@ -18,8 +20,9 @@ class AnalyticalTool(smolagents.Tool): name = "analytical_fos_calculation" description = "Calculates the factor of safety using analytical expressions." - - inputs = INPUTS + + input_type = dict[str, dict[str, Union[str, type, bool]]] + inputs: input_type = cast(input_type,INPUTS) output_type = "number" @@ -81,3 +84,82 @@ def forward( f"The factor of safety for bolts is {bolt_fos:.2f} ({bolt_comparison}) and " f"the factor of safety for plates is {plate_fos:.2f} ({plate_comparison})." ) + + +class VerboseAnalyticalTool(smolagents.tools.Tool): + """ + A tool that calculates the factor of safety for a bolted connection using analytical expressions. + + This tool uses established engineering formulas to compute the factor of safety for a bolted connection + based on the provided parameters. + """ + + name = "analytical_fos_calculation" + description = "Calculates the factor of safety using analytical expressions." + + inputs = { + "num_bolts": { + "type": "number", + "description": "Number of bolts used in the joint", + }, + "bolt_diameter": { + "type": "number", + "description": "Diameter of the bolt in mm", + } + } + + output_type = "object" + + def __init__(self, joint_configuration: Dict[str, Any], tolerance: float = 0.1): + super().__init__() + self.tolerance = tolerance + self.desired_safety_factor = joint_configuration["desired_safety_factor"] + self.load = joint_configuration["load"] + self.preload = joint_configuration["preload"] + self.bolt_yield_strength = joint_configuration["bolt_yield_strength"] + self.bolt_elastic_modulus = joint_configuration["bolt_elastic_modulus"] + self.plate_thickness = joint_configuration["plate_thickness"] + self.plate_elastic_modulus = joint_configuration["plate_elastic_modulus"] + self.plate_yield_strength = joint_configuration["plate_yield_strength"] + self.pitch = joint_configuration["pitch"] + + def forward( + self, + num_bolts: int, + bolt_diameter: float, + ) -> dict: + + load_per_bolt = self.load / num_bolts + preload_per_bolt = self.preload / num_bolts + tensile_area = get_tensile_stress_area(bolt_diameter, self.pitch) + + c = get_joint_constant( + bolt_diameter, + self.plate_thickness * 2, + self.plate_elastic_modulus, + self.bolt_elastic_modulus, + ) + + bolt_fos = bolt_yield_safety_factor( + c=c, + load=load_per_bolt, + preload=preload_per_bolt, + a_ts=tensile_area, + b_ys=self.bolt_yield_strength, + ) + + bearing_area = bolt_diameter * self.plate_thickness * num_bolts + bearing_stress = self.load / bearing_area + allowable_bearing_stress = 1.5 * self.plate_yield_strength + plate_fos = allowable_bearing_stress / bearing_stress + + bolt_diff = bolt_fos - self.desired_safety_factor + plate_diff = plate_fos - self.desired_safety_factor + + return { + "ok": (abs(bolt_diff) < self.tolerance) and (abs(plate_diff) < self.tolerance), + "bolt_fos": bolt_fos, + "bolt_diff": bolt_diff, + "plate_fos": plate_fos, + "plate_diff": plate_diff + } \ No newline at end of file diff --git a/src/autoboltagent/verbose_agents.py b/src/autoboltagent/verbose_agents.py new file mode 100644 index 0000000..d8c9286 --- /dev/null +++ b/src/autoboltagent/verbose_agents.py @@ -0,0 +1,49 @@ +import smolagents + +from .verbose_prompts import ( + TOOL_USING_INSTRUCTION, + SIMPLIFIED_TOOL_USING_INSTRUCTION, + BASE_INSTRUCTIONS, + INPUT_FORMAT, + OUTPUT_FORMAT, + LOW_FIDELITY_TOOL_INSTRUCTION, + EXAMPLE_TASK_INSTRUCTIONS +) +from .tools.low_fidelity_tool import VerboseAnalyticalTool + +from .tools.logger import AgentLogger + + +class VerboseLowFidelityAgent(smolagents.agents.ToolCallingAgent): + def __init__(self, model: smolagents.models.Model, joint_configuration: dict, agent_id: str, run_id: str, target_fos: float, agent_logger: AgentLogger|None = None) -> None: + + self.agent_logger = agent_logger + self.agent_id = agent_id + self.run_id = run_id + self.target_fos = target_fos + + callbacks = [self.log] if self.agent_logger else [] + super().__init__( + name="VerboseLowFidelityAgent", + tools=[VerboseAnalyticalTool(joint_configuration)], + add_base_tools=False, + model=model, + instructions=( + BASE_INSTRUCTIONS + + INPUT_FORMAT + + OUTPUT_FORMAT + + SIMPLIFIED_TOOL_USING_INSTRUCTION + + LOW_FIDELITY_TOOL_INSTRUCTION + ), + step_callbacks=callbacks, + verbosity_level=2, + ) + + def log(self, step, agent): + if self.agent_logger and step.__class__.__name__ == "ActionStep": + self.agent_logger.log( + agent_id=self.agent_id, + run_id=self.run_id, + target_fos=self.target_fos, + action_step=step + ) \ No newline at end of file diff --git a/src/autoboltagent/verbose_prompts.py b/src/autoboltagent/verbose_prompts.py new file mode 100644 index 0000000..ad42c46 --- /dev/null +++ b/src/autoboltagent/verbose_prompts.py @@ -0,0 +1,150 @@ +# Base prompt for the agent +BASE_INSTRUCTIONS = """ +# BASE INSTRUCTIONS + +You are a mechanical engineering expert specializing in the design of bolted connections. +You will be given tasks that require you to determine the number and size of bolts to achieve a required factor of safety. +Work iteratively to refine your solution. +Before you complete the task, you must satisfy the following requirements: +- The factor of safety for both the bolt and the plate is within +/-0.1 of the target value. +- You must recommend both a bolt size (diameter) and the number of bolts. +""" + +INPUT_FORMAT = """ +# INPUT FORMAT + +You will be given a json-like object called "joint_configuration" with some fields corresponding to a joint configuration. The fields are listed below: + + - load: (number) The external load force, in Newtons (N) + - desired_safety_factor: (number) the desired FOS number + - bolt_yield_strength: (number) the yield strength of the bolt material, in MegaPascals (MPa) + - plate_yield_strength: (number) the yield strength of the plate material, in MegaPascals (MPa) + - preload: the force of preload per joint, in Newtons (N) + - pitch: (number) thread pitch in mm + - plate_thickness: (number) plate thickness in mm + - bolt_elastic_modulus: (number) elastic modulus of bolt, in GigaPascals (GPa) + - plate_elastic_modulus: (number) elastic modulus of plate material, in GigaPascals (GPa) + +Below is an example of a valid input: + +joint_configuration = { + "load": 60000, + "desired_safety_factor": 3.0, + "bolt_yield_strength": 940, + "plate_yield_strength": 250, + "preload": 150000, + "pitch": 1.5, + "plate_thickness": 10, + "bolt_elastic_modulus": 210, + "plate_elastic_modulus": 210 +} + +These inputs will also be used to call the tool, and the names correspond exactly to those in the function signature of the tool. +""" + +# Instructions for using tools +TOOL_USING_INSTRUCTION = """ +# TOOL INSTRUCTIONS + +You will be given some tool(s) that use different methods to calculate the FOS of a joint configuration. + +They will be called with the following function signature: + +tool_call( + desired_safety_factor: float, + load: float, + preload: float, + num_bolts: int, + bolt_diameter: float, + bolt_yield_strength: float, + bolt_elastic_modulus: float, + plate_thickness: float, + plate_elastic_modulus: float, + plate_yield_strength: float, + pitch: float +) + +These inputs include the specifications of the joint_configuration as well as num_bolts and bolt_diameter (in mm), which you will need to supply. You MUST include every parameter in the signature. Partial calls are strictly forbidden and will result in failure. +The output of the tool will be a python dictionary with two fields: bolt_fos and plate_fos, which refer to the factor of safety for the bolt and plate respectively. + +When calling the tool, you must copy all joint_configuration fields exactly as provided. Do not change, round, “correct,” or infer any value (including pitch). +""" + +SIMPLIFIED_TOOL_USING_INSTRUCTION = """ +# TOOL INSTRUCTIONS + +You will be given one or more tools that tell you if the factor of safety (FOS) for a joint configuration is within target. + +The tool is called using the following EXACT format: + + +{"name":"analytical_fos_calculation","arguments":{"num_bolts":,"bolt_diameter":}} + + +# RULES (ABSOLUTE): + +0) Your entire message MUST be EXACTLY one block OR EXACTLY the final JSON. No other characters, no extra lines, no explanation. + +1) After ANY tool result (True OR False), your NEXT message MUST be a block OR the final JSON. + You are FORBIDDEN from writing explanations, analysis, narration, or repeating observations. + +2) If the tool result is False, you MUST output a NEW . + You MUST change at least one of (num_bolts, bolt_diameter). + +3) If the tool result IS True, output ONLY the final JSON and NOTHING ELSE. + +## Heuristic +Roughly speaking, the FOS will increase if the bolt diameter or number of bolts is increased. Keep that in mind when choosing your new values. +""" + +LOW_FIDELITY_TOOL_INSTRUCTION = """ +## analytical_fos_calculation + +This tool is the low-fidelity tool that uses analytical methods to calculate the FOS for the joint configuration and determine if it is within tolerance. It is computationally efficient but may be lacking in accuracy. +""" + +HIGH_FIDELITY_TOOL_INSTRUCTION = """ +## fea_fos_calculation + +This tool is the high-fidelity tool that uses a computationally intensive but very accurate finite element analysis method to calculate the FOS. +""" + +OUTPUT_FORMAT = """ +# OUTPUT FORMAT + +You will output two different things depending on the result of the tool call. + +## FOS not within tolerance OR error +If the tool returns an FOS that is not within tolerance, or an error message is returned, then the previous values you suggested for the number of bolts and the bolt diameter is wrong, and you must rethink them. + +After you have come up with new numbers, output a tool call with the new numbers like this and NOTHING ELSE: + + +{"name":"analytical_fos_calculation","arguments":{"num_bolts": , "bolt_diameter": }} + + +## FOS within tolerance +If the tool returns an acceptable FOS, then you are done. Return the number of bolts and diameter that resulted in this FOS in a json-like. + +{ + "num_bolts": , + "bolt_diameter": +} +""" + +# Instructions specific to dual-fidelity agent +DUAL_FIDELITY_COORDINATION = """ + +You should also note that you have access to a low-fidelity analytical tool and a high-fidelity finite element analysis tool. +- Use the low-fidelity tool for quick initial estimates and to explore different design options. +- Use the high-fidelity tool to validate and refine your designs. +""" + +# Instructions for an example design task +EXAMPLE_TASK_INSTRUCTIONS = """ +Given the following joint configuration: + +joint_configuration = {} + +Determine the optimal number of bolts and the major diameter of the bolts: +""" From 7fda9665205b0c54084456a65e26599b9d1f6dd5 Mon Sep 17 00:00:00 2001 From: matthewli125 Date: Wed, 21 Jan 2026 11:29:10 -0800 Subject: [PATCH 06/12] custom VLLM model to support grammar --- src/autoboltagent/VLLMModelCustom.py | 97 ++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/autoboltagent/VLLMModelCustom.py diff --git a/src/autoboltagent/VLLMModelCustom.py b/src/autoboltagent/VLLMModelCustom.py new file mode 100644 index 0000000..242f66a --- /dev/null +++ b/src/autoboltagent/VLLMModelCustom.py @@ -0,0 +1,97 @@ +from smolagents import VLLMModel +from smolagents.tools import Tool +from smolagents.monitoring import TokenUsage +from vllm.transformers_utils.tokenizer import get_tokenizer +from smolagents.models import ( + ChatMessage, + MessageRole, + remove_content_after_stop_sequences, + +) + +from typing import Any + +class VLLMModelCustom(VLLMModel): + def __init__( + self, + model_id, + model_kwargs: dict[str, Any] | None = None, + apply_chat_template_kwargs: dict[str, Any] | None = None, + sampling_params=None, + **kwargs, + ): + super().__init__( + model_id=model_id, + model_kwargs=model_kwargs, + apply_chat_template_kwargs=apply_chat_template_kwargs, + **kwargs + ) + self.sampling_params = sampling_params + + def generate( + self, + messages: list[ChatMessage | dict], + stop_sequences: list[str] | None = None, + response_format: dict[str, str] | None = None, + tools_to_call_from: list[Tool] | None = None, + **kwargs, + ) -> ChatMessage: + from vllm import SamplingParams # type: ignore + from vllm.sampling_params import StructuredOutputsParams # type: ignore + + completion_kwargs = self._prepare_completion_kwargs( + messages=messages, + flatten_messages_as_text=(not self._is_vlm), + stop_sequences=stop_sequences, + tools_to_call_from=tools_to_call_from, + **kwargs, + ) + + prepared_stop_sequences = completion_kwargs.pop("stop", []) + messages = completion_kwargs.pop("messages") + tools = completion_kwargs.pop("tools", None) + completion_kwargs.pop("tool_choice", None) + + if not self.sampling_params: + # Override the OpenAI schema for VLLM compatibility + structured_outputs = ( + StructuredOutputsParams(json=response_format["json_schema"]["schema"]) if response_format else None + ) + + + self.sampling_params = SamplingParams( + n=kwargs.get("n", 1), + temperature=kwargs.get("temperature", 0.0), + max_tokens=kwargs.get("max_tokens", 2048), + stop=prepared_stop_sequences, + structured_outputs=structured_outputs, + ) + + + prompt = self.tokenizer.apply_chat_template( + messages, + tools=tools, + add_generation_prompt=True, + tokenize=False, + **self.apply_chat_template_kwargs, + ) + + + out = self.model.generate( + prompt, + sampling_params=self.sampling_params, + **completion_kwargs, + ) + + output_text = out[0].outputs[0].text + if stop_sequences is not None and not self.supports_stop_parameter: + output_text = remove_content_after_stop_sequences(output_text, stop_sequences) + return ChatMessage( + role=MessageRole.ASSISTANT, + content=output_text, + raw={"out": output_text, "completion_kwargs": completion_kwargs}, + token_usage=TokenUsage( + input_tokens=len(out[0].prompt_token_ids), + output_tokens=len(out[0].outputs[0].token_ids), + ), + ) \ No newline at end of file From 868275eca88cb472db3a19780115c579b4842cbd Mon Sep 17 00:00:00 2001 From: matthewli125 Date: Thu, 29 Jan 2026 12:55:15 -0800 Subject: [PATCH 07/12] updated prompts --- src/autoboltagent/verbose_prompts.py | 243 +++++++++++++++++++++++---- 1 file changed, 212 insertions(+), 31 deletions(-) diff --git a/src/autoboltagent/verbose_prompts.py b/src/autoboltagent/verbose_prompts.py index ad42c46..a663bdf 100644 --- a/src/autoboltagent/verbose_prompts.py +++ b/src/autoboltagent/verbose_prompts.py @@ -6,10 +6,30 @@ You will be given tasks that require you to determine the number and size of bolts to achieve a required factor of safety. Work iteratively to refine your solution. Before you complete the task, you must satisfy the following requirements: -- The factor of safety for both the bolt and the plate is within +/-0.1 of the target value. +- The output of the analytical tool must have ok==True. - You must recommend both a bolt size (diameter) and the number of bolts. -""" +# HARD TERMINATION GATE (NON-NEGOTIABLE) + +You have exactly two allowed tool calls: +1) analytical_fos_calculation(num_bolts, bolt_diameter) +2) final_answer(answer) + +Rule A (no early final): +- You MUST NOT call final_answer unless the most recent tool observation contains: ok == True. +- If ok == False, calling final_answer is a failure. +- + +Rule B (forced continuation): +- If the most recent tool observation has ok == False, your next message MUST be a tool call to analytical_fos_calculation. +- Do not explain, do not summarize, do not output any recommendation when ok == False. + +Rule C (final schema): +- final_answer MUST be called exactly as: + {"name":"final_answer","arguments":{"answer":{"num_bolts":,"bolt_diameter":}}} +- The field "answer" MUST be an object, NOT a string. +""" +# The factor of safety for both the bolt and the plate is within +/-0.1 of the target value. INPUT_FORMAT = """ # INPUT FORMAT @@ -38,8 +58,6 @@ "bolt_elastic_modulus": 210, "plate_elastic_modulus": 210 } - -These inputs will also be used to call the tool, and the names correspond exactly to those in the function signature of the tool. """ # Instructions for using tools @@ -78,23 +96,8 @@ The tool is called using the following EXACT format: -{"name":"analytical_fos_calculation","arguments":{"num_bolts":,"bolt_diameter":}} +{"name":"","arguments":{"num_bolts":,"bolt_diameter":}} - -# RULES (ABSOLUTE): - -0) Your entire message MUST be EXACTLY one block OR EXACTLY the final JSON. No other characters, no extra lines, no explanation. - -1) After ANY tool result (True OR False), your NEXT message MUST be a block OR the final JSON. - You are FORBIDDEN from writing explanations, analysis, narration, or repeating observations. - -2) If the tool result is False, you MUST output a NEW . - You MUST change at least one of (num_bolts, bolt_diameter). - -3) If the tool result IS True, output ONLY the final JSON and NOTHING ELSE. - -## Heuristic -Roughly speaking, the FOS will increase if the bolt diameter or number of bolts is increased. Keep that in mind when choosing your new values. """ LOW_FIDELITY_TOOL_INSTRUCTION = """ @@ -109,27 +112,139 @@ This tool is the high-fidelity tool that uses a computationally intensive but very accurate finite element analysis method to calculate the FOS. """ +TOOL_OUTPUT_FORMAT = """ +# TOOL OUTPUT FORMAT + +The output of the FOS tool will be a json-like object with the following fields: + +- ok: (bool) this field is true if the bolt_fos and plate_fos values are within tolerance, and false otherwise. If ok is true, then the task is complete. +- bolt_fos: (float) the calculated FOS value for the bolt +- bolt_diff: (float) the signed difference between the calculated bolt FOS and the desired FOS. +- plate_fos: (float) the calculated FOS value for the plate +- plate_diff: (float) the signed difference between the calculated plate FOS and the desired FOS. + +Below is an example output from a FOS tool: + +{ + 'ok': False, + 'bolt_fos': 0.00667551832522406, + 'bolt_diff': -2.993324481674776, + 'plate_fos': 0.5, + 'plate_diff': -2.5 +} +""" + +SEARCH_RULES = """ +# SEARCH RULES (2-PHASE, PLATE THEN BOLT) + +Goal: make ok == True. + +Definitions (from tool output): +- bolt_diff = bolt_fos - desired_safety_factor +- plate_diff = plate_fos - desired_safety_factor +- tolerance = 0.1 + +Important structure: +- plate_fos depends ONLY on (num_bolts * bolt_diameter), NOT preload or moduli. +- Therefore, first satisfy plate_diff, then hold plate_fos ~ constant while tuning bolt_fos. + +PHASE 0 (plate target product): +Compute the target capacity-product: + target_dn = (desired_safety_factor * load) / (1.5 * plate_yield_strength * plate_thickness) + +PHASE 1 (plate bracketing on capacity): +- Keep bolt_diameter fixed initially. +- Adjust num_bolts aggressively until plate_diff changes sign (bracket plate). + * if plate_diff < 0: increase num_bolts by +6 (cap 40) + * if plate_diff > 0: decrease num_bolts by -6 (floor 2) +- Once bracketed, bisect num_bolts until abs(plate_diff) <= tolerance. + +PHASE 2 (bolt tuning with plate held near target): +- Keep (num_bolts * bolt_diameter) approximately constant near target_dn. +- If bolt_diff < 0 (bolt too weak), increase num_bolts and decrease bolt_diameter to keep num_bolts*bolt_diameter ~ constant. +- If bolt_diff > 0 (bolt too strong), decrease num_bolts and increase bolt_diameter to keep product ~ constant. +- After each move, re-check plate_diff; if abs(plate_diff) > tolerance, do ONE correction step to restore plate by nudging num_bolts (keeping diameter fixed). + +Constraints: +- num_bolts ∈ [2,40], bolt_diameter ∈ [3.0,40.0] +- Never reuse an exact (num_bolts, bolt_diameter) pair. +""" + +SEARCH_RULES_1 = """ +# SEARCH RULES (BRACKET + BISECT, NO EXTRA STATE) + +Goal: make 'ok' == True in the tool output + +Definitions: +- bolt_diff and plate_diff are provided by the tool. +- controlling_diff = bolt_diff if abs(bolt_diff) >= abs(plate_diff) else plate_diff. + +Memory rule (use transcript only): +- Treat each tool observation as a data point: + (num_bolts, bolt_diameter, bolt_diff, plate_diff). + +Bracketing rule: +- Find the most recent previous data point in the transcript whose controlling_diff has the OPPOSITE SIGN + of the current controlling_diff. +- If such a point exists, you have a bracket. + +Update rule: +A) If you HAVE a bracket: + - Next guess MUST be the midpoint between the two bracket endpoints for EXACTLY ONE variable: + * If both points have the same bolt_diameter, bisect num_bolts: + num_bolts_next = round((n_low + n_high)/2) + bolt_diameter_next = current bolt_diameter + * Otherwise, bisect bolt_diameter: + bolt_diameter_next = round((d_low + d_high)/2, 2) + num_bolts_next = current num_bolts + - This guarantees zig-zag and shrinking steps. + +B) If you DO NOT have a bracket yet: + - Make a LARGE move to force a sign change in controlling_diff: + * If controlling_diff < 0, increase capacity: num_bolts += 6 (cap at 40). + * If controlling_diff > 0, decrease capacity: num_bolts -= 6 (floor at 2). + - Keep bolt_diameter fixed until the first bracket is found. + +Bounds: +- num_bolts in [2, 40], bolt_diameter in [3.0, 40.0]. +""" + OUTPUT_FORMAT = """ -# OUTPUT FORMAT +# OUTPUT FORMAT (STRICT) -You will output two different things depending on the result of the tool call. +You will output your reasoning and a tool call. Your reasoning must be at most 512 characters, and must be very specifically explain why you are chosen your numbers. Cite the FOS and diff numbers from the tool call. -## FOS not within tolerance OR error -If the tool returns an FOS that is not within tolerance, or an error message is returned, then the previous values you suggested for the number of bolts and the bolt diameter is wrong, and you must rethink them. +# FINAL ANSWER GATE (STRICT) -After you have come up with new numbers, output a tool call with the new numbers like this and NOTHING ELSE: +Before you call ANY tool, you must check the most recent observation: +- If there is no observation yet: call analytical_fos_calculation. +- If the most recent observation has ok == False: + You MUST call analytical_fos_calculation next. + Calling final_answer here is INVALID and will be graded as FAILURE. + +- If the most recent observation has ok == True: + You MUST call final_answer next. + +If ok == False: +Output ONLY your reasoning (512 chars MAX) and the tool call: + +reason: {"name":"analytical_fos_calculation","arguments":{"num_bolts": , "bolt_diameter": }} -## FOS within tolerance -If the tool returns an acceptable FOS, then you are done. Return the number of bolts and diameter that resulted in this FOS in a json-like. +If ok == True: +Output ONLY: + +reason: + +{"name":"final_answer", "arguments":{"answer":{"num_bolts": , "bolt_diameter": }}} + +""" + +FOS_CONTEXT = """ -{ - "num_bolts": , - "bolt_diameter": -} """ # Instructions specific to dual-fidelity agent @@ -140,6 +255,72 @@ - Use the high-fidelity tool to validate and refine your designs. """ +MINIMAL_PROMPT = """ +# BOLTED JOINT DESIGN TASK + +You must determine the number and size of bolts to achieve a target safety factor (FOS) for both the bolt and plate. Use tool calls iteratively. Do not guess final values until ok==True in the tool response. + +--- + +# INPUT FORMAT + +You will receive a dictionary named `joint_configuration` containing: +- load, desired_safety_factor, bolt_yield_strength, plate_yield_strength +- preload, pitch, plate_thickness, bolt_elastic_modulus, plate_elastic_modulus + +These values are fixed and used in tool calls. + +--- + +# TOOL USAGE + +Use only this tool format: +```json +{"name": "analytical_fos_calculation", "arguments": {"num_bolts": , "bolt_diameter": }} +``` + +The tool will return: +```json +{"bolt_fos": , "plate_fos": } +``` + +You must compute: +```python +bolt_diff = bolt_fos - desired_safety_factor +plate_diff = plate_fos - desired_safety_factor +controlling_diff = bolt_diff if abs(bolt_diff) >= abs(plate_diff) else plate_diff +sign = -1 if controlling_diff < 0 else +1 +``` + +--- + +# SEARCH RULES + +- Keep `bolt_diameter` fixed throughout. Search only on `num_bolts ∈ [2, 40]`. +- Never change `num_bolts` by ±1 or reuse a tried value. + +**Phase 1: Bracketing** +- Start from any `num_bolts`. +- If `sign = -1`: increase `num_bolts` by 12. +- If `sign = +1`: decrease `num_bolts` by 12. +- Continue until you’ve tried two values with opposite signs → this forms a bracket. + +**Phase 2: Bisection** +- Once a bracket exists, bisect it: + `num_bolts = round((low + high)/2)` +- If you get stuck (same sign 2× in a row and no improvement), increase jump to ±18 once. + +--- + +# TERMINATION + +When both diffs are within ±0.1, output only: +```json +{"name": "final_answer", "arguments": {"answer": {"num_bolts": , "bolt_diameter": }}} +``` + +""" + # Instructions for an example design task EXAMPLE_TASK_INSTRUCTIONS = """ Given the following joint configuration: From 414c9a3eb3237b2cb6377a34ba162c8c1c065558 Mon Sep 17 00:00:00 2001 From: matthewli125 Date: Thu, 29 Jan 2026 21:02:45 -0800 Subject: [PATCH 08/12] add simplified FEA tool --- src/autoboltagent/tools/high_fidelity_tool.py | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/autoboltagent/tools/high_fidelity_tool.py b/src/autoboltagent/tools/high_fidelity_tool.py index 52e9f73..c43b9a4 100644 --- a/src/autoboltagent/tools/high_fidelity_tool.py +++ b/src/autoboltagent/tools/high_fidelity_tool.py @@ -67,3 +67,79 @@ def forward( comparison = "within acceptable range" return f"The factor of safety for the assembly is {fos:.2f} ({comparison})." + + +class VerboseFiniteElementTool(smolagents.tools.Tool): + """ + A tool that calculates the factor of safety for a bolted connection using finite element analysis. + + This tool leverages the autobolt library to perform finite element calculations and determine the factor of safety + for a bolted connection based on the provided parameters. + """ + + name = "fea_fos_calculation" + description = "Calculates the factor of safety using finite element analysis." + + input_type = dict[str, dict[str, Union[str, type, bool]]] + inputs = { + "num_bolts": { + "type": "number", + "description": "Number of bolts used in the joint", + }, + "bolt_diameter": { + "type": "number", + "description": "Diameter of the bolt in mm", + } + } + + output_type = "object" + + def __init__(self, joint_configuration: Dict[str, Any], tolerance: float = 0.1): + super().__init__() + self.tolerance = tolerance + self.desired_safety_factor = joint_configuration["desired_safety_factor"] + self.load = joint_configuration["load"] + self.preload = joint_configuration["preload"] + self.bolt_yield_strength = joint_configuration["bolt_yield_strength"] + self.bolt_elastic_modulus = joint_configuration["bolt_elastic_modulus"] + self.plate_thickness = joint_configuration["plate_thickness"] + self.plate_elastic_modulus = joint_configuration["plate_elastic_modulus"] + self.plate_yield_strength = joint_configuration["plate_yield_strength"] + self.pitch = joint_configuration["pitch"] + + def forward( + self, + num_bolts: int, + bolt_diameter: float, + ) -> dict: + + # Define dimensions of the plate + plate_width = 0.1 # [m] + plate_length = 0.2 # [m] + + # Compute traction + traction = -self.load / (self.plate_thickness / 1000 * plate_length) + + fos = autobolt.calculate_fos( + plate_thickness_m=self.plate_thickness / 1000, + num_holes=num_bolts, + elastic_modulus=self.plate_elastic_modulus * 10**9, + yield_strength=self.plate_yield_strength * 10**6, + traction_values=[(0, traction, 0)], + hole_radius_m=bolt_diameter / 2 / 1000, + plate_length_m=plate_length, + plate_width_m=plate_width, + edge_margin_m=plate_length / (2 * num_bolts), + hole_spacing_m=plate_length / num_bolts, + hole_offset_from_bottom_m=0.020, # [m] vertical position of hole centers (Y from bottom edge) + plate_gap_mm=0.01, # [mm] gap between the two plates + poissons_ratio=0.3, # Poisson's ratio for steel + ) + + diff = fos - self.desired_safety_factor + + return { + "ok": bool((abs(diff) < self.tolerance)), + "fos": float(fos), + "diff": float(diff), + } \ No newline at end of file From 56753f4db6e533244f1c0ed074b04aaa902d0e5d Mon Sep 17 00:00:00 2001 From: matthewli125 Date: Thu, 29 Jan 2026 21:03:18 -0800 Subject: [PATCH 09/12] jupyter notebook for manually testing FOS tools --- utilities/tool_testing.ipynb | 519 +++++++++++++++++++++++++++++++++++ 1 file changed, 519 insertions(+) create mode 100644 utilities/tool_testing.ipynb diff --git a/utilities/tool_testing.ipynb b/utilities/tool_testing.ipynb new file mode 100644 index 0000000..8f2e8d3 --- /dev/null +++ b/utilities/tool_testing.ipynb @@ -0,0 +1,519 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "de3fb190", + "metadata": {}, + "source": [ + "# Imports" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "44771eae", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/matthewli125/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n", + "/home/matthewli125/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/ufl/__init__.py:250: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.\n", + " import pkg_resources\n" + ] + } + ], + "source": [ + "from autoboltagent.tools.low_fidelity_tool import VerboseAnalyticalTool\n", + "from autoboltagent.tools.high_fidelity_tool import VerboseFiniteElementTool" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cffaf6f6", + "metadata": {}, + "outputs": [], + "source": [ + "from collections import deque\n", + "import numpy as np\n", + "from tqdm import tqdm" + ] + }, + { + "cell_type": "markdown", + "id": "acf3d0aa", + "metadata": {}, + "source": [ + "# Manual Guessing" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "0f96da72", + "metadata": {}, + "outputs": [], + "source": [ + "joint_config = {\n", + " \"load\": 60000,\n", + " \"desired_safety_factor\": 3.0,\n", + " \"bolt_yield_strength\": 940,\n", + " \"plate_yield_strength\": 250,\n", + " \"preload\": 150000,\n", + " \"pitch\": 1.5,\n", + " \"plate_thickness\": 10,\n", + " \"bolt_elastic_modulus\": 210,\n", + " \"plate_elastic_modulus\": 210\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "bf28dd68", + "metadata": {}, + "outputs": [], + "source": [ + "analytical_tool = VerboseAnalyticalTool(joint_configuration=joint_config)\n", + "fea_tool = VerboseFiniteElementTool(joint_configuration=joint_config)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6897da3a", + "metadata": {}, + "outputs": [], + "source": [ + "def cached_analytical_guess(past_guesses, num_bolts, bolt_diameter):\n", + " result = analytical_tool.forward(num_bolts=num_bolts, bolt_diameter=bolt_diameter)\n", + " past_guesses.appendleft((num_bolts, bolt_diameter, result))\n", + " \n", + " for row in past_guesses:\n", + " print(row)\n", + "\n", + "def cached_fea_guess(past_guesses, num_bolts, bolt_diameter):\n", + " result = fea_tool.forward(num_bolts=num_bolts, bolt_diameter=bolt_diameter)\n", + " past_guesses.appendleft((num_bolts, bolt_diameter, result))\n", + " \n", + " for row in past_guesses:\n", + " print(row)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "b8a88d0e", + "metadata": {}, + "outputs": [], + "source": [ + "past_guesses = deque()" + ] + }, + { + "cell_type": "markdown", + "id": "cc066a9d", + "metadata": {}, + "source": [ + "### Usage\n", + "\n", + "Simply modify the num_bolts and bolt_diameter parameters; past guesses are saved and will be printed out as well. Note that the FEA tool generates a lot of output that can't be suppressed." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "87688dd8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(2, 17, {'ok': False, 'bolt_fos': 2.1834956164436536, 'bolt_diff': -0.8165043835563464, 'plate_fos': 2.125, 'plate_diff': -0.875})\n" + ] + } + ], + "source": [ + "cached_analytical_guess(past_guesses, num_bolts=2, bolt_diameter=17)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "d58a840c", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "PETSc Error --- Application was linked against both OpenMPI and MPICH based MPI libraries and will not run correctly\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Info : Reading '/tmp/tmpabrul051/model.step'...\n", + "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:2]/ASSEMBLY/=>[0:1:1:3]/SOLID' (3D)\n", + "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:4]/ASSEMBLY/=>[0:1:1:5]/ASSEMBLY/=>[0:1:1:6]/SOLID' (3D)\n", + "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:7]/ASSEMBLY/=>[0:1:1:8]/SOLID' (3D)\n", + "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:7]/ASSEMBLY/=>[0:1:1:9]/SOLID' (3D)\n", + "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:3]/SOLID' (3D)\n", + "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:5]/ASSEMBLY/=>[0:1:1:6]/SOLID' (3D)\n", + "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:6]/SOLID' (3D)\n", + "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:8]/SOLID' (3D)\n", + "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:9]/SOLID' (3D)\n", + "Info : Done reading '/tmp/tmpabrul051/model.step'\n", + "Info : Meshing 1D...\n", + "Info : [ 0%] Meshing curve 1 (Line)\n", + "Info : [ 10%] Meshing curve 2 (Line)\n", + "Info : [ 10%] Meshing curve 3 (Line)\n", + "Info : [ 10%] Meshing curve 4 (Line)\n", + "Info : [ 10%] Meshing curve 5 (Line)\n", + "Info : [ 20%] Meshing curve 6 (Line)\n", + "Info : [ 20%] Meshing curve 7 (Line)\n", + "Info : [ 20%] Meshing curve 8 (Line)\n", + "Info : [ 20%] Meshing curve 9 (Line)\n", + "Info : [ 30%] Meshing curve 10 (Circle)\n", + "Info : [ 30%] Meshing curve 11 (Circle)\n", + "Info : [ 30%] Meshing curve 12 (Line)\n", + "Info : [ 30%] Meshing curve 13 (Line)\n", + "Info : [ 40%] Meshing curve 14 (Line)\n", + "Info : [ 40%] Meshing curve 15 (Circle)\n", + "Info : [ 40%] Meshing curve 16 (Circle)\n", + "Info : [ 40%] Meshing curve 17 (Line)\n", + "Info : [ 50%] Meshing curve 18 (Line)\n", + "Info : [ 50%] Meshing curve 19 (Line)\n", + "Info : [ 50%] Meshing curve 20 (Line)\n", + "Info : [ 50%] Meshing curve 21 (Line)\n", + "Info : [ 60%] Meshing curve 22 (Line)\n", + "Info : [ 60%] Meshing curve 23 (Line)\n", + "Info : [ 60%] Meshing curve 24 (Line)\n", + "Info : [ 60%] Meshing curve 25 (Line)\n", + "Info : [ 60%] Meshing curve 26 (Line)\n", + "Info : [ 70%] Meshing curve 27 (Line)\n", + "Info : [ 70%] Meshing curve 28 (Circle)\n", + "Info : [ 70%] Meshing curve 29 (Circle)\n", + "Info : [ 70%] Meshing curve 30 (Line)\n", + "Info : [ 80%] Meshing curve 31 (Line)\n", + "Info : [ 80%] Meshing curve 32 (Line)\n", + "Info : [ 80%] Meshing curve 33 (Circle)\n", + "Info : [ 80%] Meshing curve 34 (Circle)\n", + "Info : [ 90%] Meshing curve 35 (Line)\n", + "Info : [ 90%] Meshing curve 36 (Line)\n", + "Info : [ 90%] Meshing curve 37 (Circle)\n", + "Info : [ 90%] Meshing curve 38 (Line)\n", + "Info : [100%] Meshing curve 39 (Circle)\n", + "Info : [100%] Meshing curve 40 (Circle)\n", + "Info : [100%] Meshing curve 41 (Line)\n", + "Info : [100%] Meshing curve 42 (Circle)\n", + "Info : Done meshing 1D (Wall 0.00219436s, CPU 0.002691s)\n", + "Info : Meshing 2D...\n", + "Info : [ 0%] Meshing surface 1 (Plane, Frontal-Delaunay)\n", + "Info : [ 10%] Meshing surface 2 (Plane, Frontal-Delaunay)\n", + "Info : [ 10%] Meshing surface 3 (Plane, Frontal-Delaunay)\n", + "Info : [ 20%] Meshing surface 4 (Plane, Frontal-Delaunay)\n", + "Info : [ 20%] Meshing surface 5 (Plane, Frontal-Delaunay)\n", + "Info : [ 30%] Meshing surface 6 (Plane, Frontal-Delaunay)\n", + "Info : [ 30%] Meshing surface 7 (Cylinder, Frontal-Delaunay)\n", + "Info : [ 40%] Meshing surface 8 (Cylinder, Frontal-Delaunay)\n", + "Info : [ 40%] Meshing surface 9 (Plane, Frontal-Delaunay)\n", + "Info : [ 50%] Meshing surface 10 (Plane, Frontal-Delaunay)\n", + "Info : [ 50%] Meshing surface 11 (Plane, Frontal-Delaunay)\n", + "Info : [ 60%] Meshing surface 12 (Plane, Frontal-Delaunay)\n", + "Info : [ 60%] Meshing surface 13 (Plane, Frontal-Delaunay)\n", + "Info : [ 60%] Meshing surface 14 (Plane, Frontal-Delaunay)\n", + "Info : [ 70%] Meshing surface 15 (Cylinder, Frontal-Delaunay)\n", + "Info : [ 70%] Meshing surface 16 (Cylinder, Frontal-Delaunay)\n", + "Info : [ 80%] Meshing surface 17 (Cylinder, Frontal-Delaunay)\n", + "Info : [ 80%] Meshing surface 18 (Plane, Frontal-Delaunay)\n", + "Info : [ 90%] Meshing surface 19 (Plane, Frontal-Delaunay)\n", + "Info : [ 90%] Meshing surface 20 (Cylinder, Frontal-Delaunay)\n", + "Info : [100%] Meshing surface 21 (Plane, Frontal-Delaunay)\n", + "Info : [100%] Meshing surface 22 (Plane, Frontal-Delaunay)\n", + "Info : Done meshing 2D (Wall 0.0719964s, CPU 0.069294s)\n", + "Info : Meshing 3D...\n", + "Info : 3D Meshing 4 volumes with 4 connected components\n", + "Info : Tetrahedrizing 260 nodes...\n", + "Info : Done tetrahedrizing 268 nodes (Wall 0.00138845s, CPU 0.001092s)\n", + "Info : Reconstructing mesh...\n", + "Info : - Creating surface mesh\n", + "Info : - Identifying boundary edges\n", + "Info : - Recovering boundary\n", + "Info : - Added 3 Steiner points\n", + "Info : Done reconstructing mesh (Wall 0.00485352s, CPU 0.004481s)\n", + "Info : Found volume 1\n", + "Info : It. 0 - 0 nodes created - worst tet radius 0.98006 (nodes removed 0 0)\n", + "Info : 3D refinement terminated (587 nodes total):\n", + "Info : - 0 Delaunay cavities modified for star shapeness\n", + "Info : - 0 nodes could not be inserted\n", + "Info : - 705 tetrahedra created in 3.6739e-05 sec. (19189423 tets/s)\n", + "Info : 0 node relocations\n", + "Info : Tetrahedrizing 262 nodes...\n", + "Info : Done tetrahedrizing 270 nodes (Wall 0.00385722s, CPU 0.003864s)\n", + "Info : Reconstructing mesh...\n", + "Info : - Creating surface mesh\n", + "Info : - Identifying boundary edges\n", + "Info : - Recovering boundary\n", + "Info : - Added 2 Steiner points\n", + "Info : Done reconstructing mesh (Wall 0.00803251s, CPU 0.00788s)\n", + "Info : Found volume 2\n", + "Info : It. 0 - 0 nodes created - worst tet radius 0.90247 (nodes removed 0 0)\n", + "Info : 3D refinement terminated (586 nodes total):\n", + "Info : - 0 Delaunay cavities modified for star shapeness\n", + "Info : - 0 nodes could not be inserted\n", + "Info : - 707 tetrahedra created in 2.7909e-05 sec. (25332328 tets/s)\n", + "Info : 0 node relocations\n", + "Info : Tetrahedrizing 31 nodes...\n", + "Info : Done tetrahedrizing 39 nodes (Wall 0.000136907s, CPU 0.000156s)\n", + "Info : Reconstructing mesh...\n", + "Info : - Creating surface mesh\n", + "Info : - Identifying boundary edges\n", + "Info : - Recovering boundary\n", + "Info : Done reconstructing mesh (Wall 0.000363324s, CPU 0.000425s)\n", + "Info : Found volume 3\n", + "Info : It. 0 - 0 nodes created - worst tet radius 2.91212 (nodes removed 0 0)\n", + "Info : 3D refinement terminated (585 nodes total):\n", + "Info : - 0 Delaunay cavities modified for star shapeness\n", + "Info : - 3 nodes could not be inserted\n", + "Info : - 61 tetrahedra created in 8.048e-05 sec. (757952 tets/s)\n", + "Info : 0 node relocations\n", + "Info : Tetrahedrizing 31 nodes...\n", + "Info : Done tetrahedrizing 39 nodes (Wall 0.000130817s, CPU 0.000172s)\n", + "Info : Reconstructing mesh...\n", + "Info : - Creating surface mesh\n", + "Info : - Identifying boundary edges\n", + "Info : - Recovering boundary\n", + "Info : Done reconstructing mesh (Wall 0.000326484s, CPU 0.000452s)\n", + "Info : Found volume 4\n", + "Info : It. 0 - 0 nodes created - worst tet radius 2.91212 (nodes removed 0 0)\n", + "Info : 3D refinement terminated (585 nodes total):\n", + "Info : - 0 Delaunay cavities modified for star shapeness\n", + "Info : - 3 nodes could not be inserted\n", + "Info : - 61 tetrahedra created in 0.00017466 sec. (349249 tets/s)\n", + "Info : 0 node relocations\n", + "Info : Done meshing 3D (Wall 0.0288194s, CPU 0.028817s)\n", + "Info : Optimizing mesh...\n", + "Info : Optimizing volume 1\n", + "Info : Optimization starts (volume = 0.000195872) with worst = 0.153175 / average = 0.67823:\n", + "Info : 0.00 < quality < 0.10 : 0 elements\n", + "Info : 0.10 < quality < 0.20 : 2 elements\n", + "Info : 0.20 < quality < 0.30 : 3 elements\n", + "Info : 0.30 < quality < 0.40 : 41 elements\n", + "Info : 0.40 < quality < 0.50 : 34 elements\n", + "Info : 0.50 < quality < 0.60 : 64 elements\n", + "Info : 0.60 < quality < 0.70 : 176 elements\n", + "Info : 0.70 < quality < 0.80 : 309 elements\n", + "Info : 0.80 < quality < 0.90 : 60 elements\n", + "Info : 0.90 < quality < 1.00 : 16 elements\n", + "Info : 2 edge swaps, 1 node relocations (volume = 0.000195872): worst = 0.29686 / average = 0.680162 (Wall 0.000410718s, CPU 0.000717s)\n", + "Info : No ill-shaped tets in the mesh :-)\n", + "Info : 0.00 < quality < 0.10 : 0 elements\n", + "Info : 0.10 < quality < 0.20 : 0 elements\n", + "Info : 0.20 < quality < 0.30 : 2 elements\n", + "Info : 0.30 < quality < 0.40 : 45 elements\n", + "Info : 0.40 < quality < 0.50 : 29 elements\n", + "Info : 0.50 < quality < 0.60 : 66 elements\n", + "Info : 0.60 < quality < 0.70 : 176 elements\n", + "Info : 0.70 < quality < 0.80 : 309 elements\n", + "Info : 0.80 < quality < 0.90 : 60 elements\n", + "Info : 0.90 < quality < 1.00 : 16 elements\n", + "Info : Optimizing volume 2\n", + "Info : Optimization starts (volume = 0.000195872) with worst = 0.08867 / average = 0.680311:\n", + "Info : 0.00 < quality < 0.10 : 1 elements\n", + "Info : 0.10 < quality < 0.20 : 2 elements\n", + "Info : 0.20 < quality < 0.30 : 4 elements\n", + "Info : 0.30 < quality < 0.40 : 42 elements\n", + "Info : 0.40 < quality < 0.50 : 28 elements\n", + "Info : 0.50 < quality < 0.60 : 55 elements\n", + "Info : 0.60 < quality < 0.70 : 179 elements\n", + "Info : 0.70 < quality < 0.80 : 322 elements\n", + "Info : 0.80 < quality < 0.90 : 57 elements\n", + "Info : 0.90 < quality < 1.00 : 17 elements\n", + "Info : 3 edge swaps, 0 node relocations (volume = 0.000195872): worst = 0.29686 / average = 0.683139 (Wall 0.000108185s, CPU 0.000151s)\n", + "Info : No ill-shaped tets in the mesh :-)\n", + "Info : 0.00 < quality < 0.10 : 0 elements\n", + "Info : 0.10 < quality < 0.20 : 0 elements\n", + "Info : 0.20 < quality < 0.30 : 4 elements\n", + "Info : 0.30 < quality < 0.40 : 42 elements\n", + "Info : 0.40 < quality < 0.50 : 26 elements\n", + "Info : 0.50 < quality < 0.60 : 56 elements\n", + "Info : 0.60 < quality < 0.70 : 181 elements\n", + "Info : 0.70 < quality < 0.80 : 321 elements\n", + "Info : 0.80 < quality < 0.90 : 57 elements\n", + "Info : 0.90 < quality < 1.00 : 17 elements\n", + "Info : Optimizing volume 3\n", + "Info : Optimization starts (volume = 4.07734e-06) with worst = 0.0172911 / average = 0.830608:\n", + "Info : 0.00 < quality < 0.10 : 3 elements\n", + "Info : 0.10 < quality < 0.20 : 0 elements\n", + "Info : 0.20 < quality < 0.30 : 0 elements\n", + "Info : 0.30 < quality < 0.40 : 0 elements\n", + "Info : 0.40 < quality < 0.50 : 0 elements\n", + "Info : 0.50 < quality < 0.60 : 0 elements\n", + "Info : 0.60 < quality < 0.70 : 0 elements\n", + "Info : 0.70 < quality < 0.80 : 2 elements\n", + "Info : 0.80 < quality < 0.90 : 40 elements\n", + "Info : 0.90 < quality < 1.00 : 16 elements\n", + "Info : 2 edge swaps, 1 node relocations (volume = 4.07734e-06): worst = 0.0258124 / average = 0.809727 (Wall 7.8652e-05s, CPU 7.8e-05s)\n", + "Info : 3 edge swaps, 1 node relocations (volume = 4.07734e-06): worst = 0.213928 / average = 0.808979 (Wall 0.000108591s, CPU 0.000108s)\n", + "Info : No ill-shaped tets in the mesh :-)\n", + "Info : 0.00 < quality < 0.10 : 0 elements\n", + "Info : 0.10 < quality < 0.20 : 0 elements\n", + "Info : 0.20 < quality < 0.30 : 2 elements\n", + "Info : 0.30 < quality < 0.40 : 2 elements\n", + "Info : 0.40 < quality < 0.50 : 4 elements\n", + "Info : 0.50 < quality < 0.60 : 0 elements\n", + "Info : 0.60 < quality < 0.70 : 0 elements\n", + "Info : 0.70 < quality < 0.80 : 0 elements\n", + "Info : 0.80 < quality < 0.90 : 36 elements\n", + "Info : 0.90 < quality < 1.00 : 16 elements\n", + "Info : Optimizing volume 4\n", + "Info : Optimization starts (volume = 4.07734e-06) with worst = 0.0172911 / average = 0.830608:\n", + "Info : 0.00 < quality < 0.10 : 3 elements\n", + "Info : 0.10 < quality < 0.20 : 0 elements\n", + "Info : 0.20 < quality < 0.30 : 0 elements\n", + "Info : 0.30 < quality < 0.40 : 0 elements\n", + "Info : 0.40 < quality < 0.50 : 0 elements\n", + "Info : 0.50 < quality < 0.60 : 0 elements\n", + "Info : 0.60 < quality < 0.70 : 0 elements\n", + "Info : 0.70 < quality < 0.80 : 2 elements\n", + "Info : 0.80 < quality < 0.90 : 40 elements\n", + "Info : 0.90 < quality < 1.00 : 16 elements\n", + "Info : 3 edge swaps, 2 node relocations (volume = 4.07734e-06): worst = 0.21364 / average = 0.808968 (Wall 0.000471611s, CPU 0.000465s)\n", + "Info : No ill-shaped tets in the mesh :-)\n", + "Info : 0.00 < quality < 0.10 : 0 elements\n", + "Info : 0.10 < quality < 0.20 : 0 elements\n", + "Info : 0.20 < quality < 0.30 : 2 elements\n", + "Info : 0.30 < quality < 0.40 : 2 elements\n", + "Info : 0.40 < quality < 0.50 : 4 elements\n", + "Info : 0.50 < quality < 0.60 : 0 elements\n", + "Info : 0.60 < quality < 0.70 : 0 elements\n", + "Info : 0.70 < quality < 0.80 : 0 elements\n", + "Info : 0.80 < quality < 0.90 : 36 elements\n", + "Info : 0.90 < quality < 1.00 : 16 elements\n", + "Info : Done optimizing mesh (Wall 0.00384576s, CPU 0.004583s)\n", + "Info : 591 nodes 2917 elements\n", + "Info : Removing duplicate mesh nodes...\n", + "Info : Found 28 duplicate nodes \n", + "Info : Removed 28 duplicate mesh nodes\n", + "Info : Done removing duplicate mesh nodes\n", + "Info : Writing '/tmp/tmpabrul051/mesh_merged.msh'...\n", + "Info : Done writing '/tmp/tmpabrul051/mesh_merged.msh'\n", + "\n", + "Solving linear variational problem.\n", + "(2, 17, {'ok': False, 'fos': 0.1137652680507679, 'diff': -2.8862347319492323})\n", + "(2, 17, {'ok': False, 'fos': 0.1137652680507679, 'diff': -2.8862347319492323})\n", + "(2, 17, {'ok': False, 'fos': 0.1137652680507679, 'diff': -2.8862347319492323})\n", + "(2, 17, {'ok': False, 'fos': 0.1137652680507679, 'diff': -2.8862347319492323})\n", + "(2, 17, {'ok': False, 'bolt_fos': 2.1834956164436536, 'bolt_diff': -0.8165043835563464, 'plate_fos': 2.125, 'plate_diff': -0.875})\n" + ] + } + ], + "source": [ + "import logging\n", + "logging.basicConfig(level=logging.CRITICAL)\n", + "\n", + "cached_fea_guess(past_guesses, num_bolts=2, bolt_diameter=17)" + ] + }, + { + "cell_type": "markdown", + "id": "cd57334d", + "metadata": {}, + "source": [ + "# Brute Force Search" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "b19839ea", + "metadata": {}, + "outputs": [], + "source": [ + "def brute_force_search(\n", + " num_bolts_low, \n", + " num_bolts_high, \n", + " bolt_diameter_low, \n", + " bolt_diameter_high,\n", + " step_size=0.1\n", + "):\n", + " for num_bolts in range(num_bolts_low, num_bolts_high):\n", + " for bolt_diameter in np.arange(bolt_diameter_low, bolt_diameter_high, step_size):\n", + " result = analytical_tool.forward(num_bolts=num_bolts, bolt_diameter=float(bolt_diameter))\n", + "\n", + " if abs(result[\"bolt_diff\"]) < 0.25 and abs(result[\"plate_diff\"]) < 0.25:\n", + " print(num_bolts, bolt_diameter,result)\n", + " if result[\"ok\"]:\n", + " print(\"ANSWER \", num_bolts, bolt_diameter,result)" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "4af7b215", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3 15.700000000000012 {'ok': False, 'bolt_fos': 2.7527559285221455, 'bolt_diff': -0.24724407147785454, 'plate_fos': 2.9437500000000023, 'plate_diff': -0.05624999999999769}\n", + "3 15.800000000000011 {'ok': False, 'bolt_fos': 2.7909823520750883, 'bolt_diff': -0.20901764792491173, 'plate_fos': 2.962500000000002, 'plate_diff': -0.03749999999999787}\n", + "3 15.900000000000011 {'ok': False, 'bolt_fos': 2.829900224552613, 'bolt_diff': -0.1700997754473872, 'plate_fos': 2.9812500000000024, 'plate_diff': -0.018749999999997602}\n", + "3 16.00000000000001 {'ok': False, 'bolt_fos': 2.8690875598645036, 'bolt_diff': -0.1309124401354964, 'plate_fos': 3.000000000000002, 'plate_diff': 2.220446049250313e-15}\n", + "3 16.100000000000012 {'ok': True, 'bolt_fos': 2.9085443580107597, 'bolt_diff': -0.09145564198924028, 'plate_fos': 3.018750000000002, 'plate_diff': 0.018750000000002043}\n", + "ANSWER 3 16.100000000000012 {'ok': True, 'bolt_fos': 2.9085443580107597, 'bolt_diff': -0.09145564198924028, 'plate_fos': 3.018750000000002, 'plate_diff': 0.018750000000002043}\n", + "3 16.20000000000001 {'ok': True, 'bolt_fos': 2.9481737740977123, 'bolt_diff': -0.05182622590228769, 'plate_fos': 3.0375000000000023, 'plate_diff': 0.03750000000000231}\n", + "ANSWER 3 16.20000000000001 {'ok': True, 'bolt_fos': 2.9481737740977123, 'bolt_diff': -0.05182622590228769, 'plate_fos': 3.0375000000000023, 'plate_diff': 0.03750000000000231}\n", + "3 16.30000000000001 {'ok': True, 'bolt_fos': 2.98811910721272, 'bolt_diff': -0.011880892787280217, 'plate_fos': 3.056250000000002, 'plate_diff': 0.05625000000000213}\n", + "ANSWER 3 16.30000000000001 {'ok': True, 'bolt_fos': 2.98811910721272, 'bolt_diff': -0.011880892787280217, 'plate_fos': 3.056250000000002, 'plate_diff': 0.05625000000000213}\n", + "3 16.400000000000013 {'ok': True, 'bolt_fos': 3.0283325733774613, 'bolt_diff': 0.028332573377461312, 'plate_fos': 3.075000000000002, 'plate_diff': 0.07500000000000195}\n", + "ANSWER 3 16.400000000000013 {'ok': True, 'bolt_fos': 3.0283325733774613, 'bolt_diff': 0.028332573377461312, 'plate_fos': 3.075000000000002, 'plate_diff': 0.07500000000000195}\n", + "3 16.500000000000014 {'ok': True, 'bolt_fos': 3.068814159381124, 'bolt_diff': 0.06881415938112401, 'plate_fos': 3.0937500000000027, 'plate_diff': 0.09375000000000266}\n", + "ANSWER 3 16.500000000000014 {'ok': True, 'bolt_fos': 3.068814159381124, 'bolt_diff': 0.06881415938112401, 'plate_fos': 3.0937500000000027, 'plate_diff': 0.09375000000000266}\n", + "3 16.600000000000012 {'ok': False, 'bolt_fos': 3.1095638520137596, 'bolt_diff': 0.10956385201375962, 'plate_fos': 3.112500000000002, 'plate_diff': 0.11250000000000204}\n", + "3 16.70000000000001 {'ok': False, 'bolt_fos': 3.1505816380662903, 'bolt_diff': 0.15058163806629032, 'plate_fos': 3.1312500000000023, 'plate_diff': 0.1312500000000023}\n", + "3 16.80000000000001 {'ok': False, 'bolt_fos': 3.1918675043305074, 'bolt_diff': 0.19186750433050737, 'plate_fos': 3.150000000000002, 'plate_diff': 0.15000000000000213}\n", + "3 16.900000000000013 {'ok': False, 'bolt_fos': 3.233421437599064, 'bolt_diff': 0.23342143759906397, 'plate_fos': 3.1687500000000024, 'plate_diff': 0.1687500000000024}\n" + ] + } + ], + "source": [ + "brute_force_search(num_bolts_low=2, num_bolts_high=40, bolt_diameter_low=3.0, bolt_diameter_high=40.0)" + ] + }, + { + "cell_type": "markdown", + "id": "34f4e480", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "autoboltagent", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.19" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 20a5f665a8bb219f0625e519faf81a9da9bd6145 Mon Sep 17 00:00:00 2001 From: Matthew Li Date: Thu, 29 Jan 2026 21:28:36 -0800 Subject: [PATCH 10/12] add agent testing notebook --- utilities/agent_testing.ipynb | 300 ++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 utilities/agent_testing.ipynb diff --git a/utilities/agent_testing.ipynb b/utilities/agent_testing.ipynb new file mode 100644 index 0000000..4f8be1e --- /dev/null +++ b/utilities/agent_testing.ipynb @@ -0,0 +1,300 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1efd1f50", + "metadata": {}, + "source": [ + "# Imports" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "aa00e50c", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/matthewli125/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n", + "/home/matthewli125/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/ufl/__init__.py:250: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.\n", + " import pkg_resources\n" + ] + } + ], + "source": [ + "from autoboltagent import verbose_prompts, grammars\n", + "from autoboltagent import prompts\n", + "from autoboltagent.verbose_agents import VerboseLowFidelityAgent\n", + "from autoboltagent.agents import LowFidelityAgent\n", + "from autoboltagent.tools.logger import AgentLogger\n", + "from autoboltagent.VLLMModelCustom import VLLMModelCustom" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "85dcc950", + "metadata": {}, + "outputs": [], + "source": [ + "from vllm import SamplingParams\n", + "from vllm.sampling_params import StructuredOutputsParams\n", + "import smolagents" + ] + }, + { + "cell_type": "markdown", + "id": "fb89c141", + "metadata": {}, + "source": [ + "# Setup" + ] + }, + { + "cell_type": "markdown", + "id": "a87e3fec", + "metadata": {}, + "source": [ + "### set up logger and db" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "c84a2a1a", + "metadata": {}, + "outputs": [], + "source": [ + "db_url = \"sqlite:///../src/agent_logs_grammar_prod.db\"\n", + "logger = AgentLogger(db_url)" + ] + }, + { + "cell_type": "markdown", + "id": "d00aa648", + "metadata": {}, + "source": [ + "### params" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "653c34d2", + "metadata": {}, + "outputs": [], + "source": [ + "joint_configuration = {\n", + " \"load\": 60000,\n", + " \"desired_safety_factor\": 3.0,\n", + " \"bolt_yield_strength\": 940,\n", + " \"plate_yield_strength\": 250,\n", + " \"preload\": 150000,\n", + " \"pitch\": 1.5,\n", + " \"plate_thickness\": 10,\n", + " \"bolt_elastic_modulus\": 210,\n", + " \"plate_elastic_modulus\": 210\n", + " }\n", + "\n", + "input = \"\"\"{\n", + " \"load\": 60000,\n", + " \"desired_safety_factor\": 3.0,\n", + " \"bolt_yield_strength\": 940,\n", + " \"plate_yield_strength\": 250,\n", + " \"preload\": 150000,\n", + " \"pitch\": 1.5,\n", + " \"plate_thickness\": 10,\n", + " \"bolt_elastic_modulus\": 210,\n", + " \"plate_elastic_modulus\": 210\n", + " }\"\"\"\n", + "\n", + "grammar_sop = StructuredOutputsParams(\n", + " grammar=grammars.low_fidelity_agent_grammar_debug\n", + ")\n", + "\n", + "sampling_params = SamplingParams(\n", + " max_tokens=200,\n", + " temperature=0.0,\n", + " structured_outputs=grammar_sop\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "8f17629d", + "metadata": {}, + "source": [ + "# Models" + ] + }, + { + "cell_type": "markdown", + "id": "e8e3c23e", + "metadata": {}, + "source": [ + "### Local" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4143950e", + "metadata": {}, + "outputs": [], + "source": [ + "model = smolagents.VLLMModel(\n", + " model_id=\"RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8\",\n", + " model_kwargs={\n", + " \"gpu_memory_utilization\": 0.85,\n", + " },\n", + " grammar=grammars.low_fidelity_agent_grammar\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00cec7de", + "metadata": {}, + "outputs": [], + "source": [ + "# Custom local VLLM model with grammar\n", + "\n", + "model = VLLMModelCustom(\n", + " model_id=\"RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8\",\n", + " apply_chat_template_kwargs=None,\n", + " model_kwargs={\n", + " \"gpu_memory_utilization\": 0.85,\n", + " },\n", + " sampling_params=sampling_params,\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "278e5eeb", + "metadata": {}, + "source": [ + "### Cloud models" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ce9ba947", + "metadata": {}, + "outputs": [], + "source": [ + "FIREWORKS_API_KEY = \"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a14fa02a", + "metadata": {}, + "outputs": [], + "source": [ + "# smolagents InferenceClientModel\n", + "\n", + "model = smolagents.InferenceClientModel( # type: ignore\n", + " provider=\"fireworks-ai\",\n", + " model_id=\"openai/gpt-oss-20b\",\n", + " token=FIREWORKS_API_KEY,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "83fce9b8", + "metadata": {}, + "outputs": [], + "source": [ + "model = smolagents.OpenAIServerModel(\n", + " model_id=\"accounts/fireworks/models/gpt-oss-20b\",\n", + " api_base=\"https://api.fireworks.ai/inference/v1\", \n", + " api_key=FIREWORKS_API_KEY,\n", + " # response_format={\n", + " # \"type\": \"grammar\",\n", + " # \"grammar\": grammars.low_fidelity_agent_grammar_debug\n", + " # }\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "92627081", + "metadata": {}, + "source": [ + "# Run agent" + ] + }, + { + "cell_type": "markdown", + "id": "05023b62", + "metadata": {}, + "source": [ + "### Single agent run" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "96b94fe8", + "metadata": {}, + "outputs": [], + "source": [ + "agent = VerboseLowFidelityAgent(model, joint_configuration, \"verbose low fidelity agent\", f\"verbose prompts + minimized + reason 512 + gpt 1\", 3.0, logger, max_steps=100)\n", + "instruction = verbose_prompts.EXAMPLE_TASK_INSTRUCTIONS.format(input)\n", + "agent.run(instruction)" + ] + }, + { + "cell_type": "markdown", + "id": "e4207a92", + "metadata": {}, + "source": [ + "### Loop agent run" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "691f9b15", + "metadata": {}, + "outputs": [], + "source": [ + "for i in range(0,25):\n", + " agent = VerboseLowFidelityAgent(model, joint_configuration, \"verbose low fidelity agent\", f\"verbose prompts + minimized + reason 512 + gpt {i}\", 3.0, logger, max_steps=100)\n", + " instruction = verbose_prompts.EXAMPLE_TASK_INSTRUCTIONS.format(input)\n", + " agent.run(instruction)\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "autoboltagent", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.19" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 164ff7c55d91da139a9e32015312ad724f26b170 Mon Sep 17 00:00:00 2001 From: matthewli125 Date: Thu, 29 Jan 2026 21:31:20 -0800 Subject: [PATCH 11/12] add agent testing notebook --- utilities/agent_testing.ipynb | 231 ++++++++++++++++++++++++++++++++-- 1 file changed, 221 insertions(+), 10 deletions(-) diff --git a/utilities/agent_testing.ipynb b/utilities/agent_testing.ipynb index 4f8be1e..279e912 100644 --- a/utilities/agent_testing.ipynb +++ b/utilities/agent_testing.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "aa00e50c", "metadata": {}, "outputs": [ @@ -36,7 +36,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 2, "id": "85dcc950", "metadata": {}, "outputs": [], @@ -64,7 +64,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "id": "c84a2a1a", "metadata": {}, "outputs": [], @@ -83,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "id": "653c34d2", "metadata": {}, "outputs": [], @@ -141,17 +141,109 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "4143950e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO 01-29 21:24:13 [utils.py:263] non-default args: {'gpu_memory_utilization': 0.85, 'disable_log_stats': True, 'model': 'RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8'}\n", + "INFO 01-29 21:24:14 [model.py:530] Resolved architecture: Qwen2ForCausalLM\n", + "INFO 01-29 21:24:14 [model.py:1545] Using max model len 32768\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2026-01-29 21:24:15,764\tINFO util.py:154 -- Missing packages: ['ipywidgets']. Run `pip install -U ipywidgets`, then restart the notebook server for rich notebook output.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO 01-29 21:24:15 [scheduler.py:229] Chunked prefill is enabled with max_num_batched_tokens=8192.\n", + "INFO 01-29 21:24:15 [vllm.py:630] Asynchronous scheduling is enabled.\n", + "INFO 01-29 21:24:15 [vllm.py:637] Disabling NCCL for DP synchronization when using async scheduling.\n", + "WARNING 01-29 21:24:16 [interface.py:470] Using 'pin_memory=False' as WSL is detected. This may slow down the performance.\n", + "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m INFO 01-29 21:24:21 [core.py:97] Initializing a V1 LLM engine (v0.14.1) with config: model='RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8', speculative_config=None, tokenizer='RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8', skip_tokenizer_init=False, tokenizer_mode=auto, revision=None, tokenizer_revision=None, trust_remote_code=False, dtype=torch.bfloat16, max_seq_len=32768, download_dir=None, load_format=auto, tensor_parallel_size=1, pipeline_parallel_size=1, data_parallel_size=1, disable_custom_all_reduce=False, quantization=compressed-tensors, enforce_eager=False, enable_return_routed_experts=False, kv_cache_dtype=auto, device_config=cuda, structured_outputs_config=StructuredOutputsConfig(backend='auto', disable_fallback=False, disable_any_whitespace=False, disable_additional_properties=False, reasoning_parser='', reasoning_parser_plugin='', enable_in_reasoning=False), observability_config=ObservabilityConfig(show_hidden_metrics_for_version=None, otlp_traces_endpoint=None, collect_detailed_traces=None, kv_cache_metrics=False, kv_cache_metrics_sample=0.01, cudagraph_metrics=False, enable_layerwise_nvtx_tracing=False, enable_mfu_metrics=False, enable_mm_processor_stats=False, enable_logging_iteration_details=False), seed=0, served_model_name=RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8, enable_prefix_caching=True, enable_chunked_prefill=True, pooler_config=None, compilation_config={'level': None, 'mode': , 'debug_dump_path': None, 'cache_dir': '', 'compile_cache_save_format': 'binary', 'backend': 'inductor', 'custom_ops': ['none'], 'splitting_ops': ['vllm::unified_attention', 'vllm::unified_attention_with_output', 'vllm::unified_mla_attention', 'vllm::unified_mla_attention_with_output', 'vllm::mamba_mixer2', 'vllm::mamba_mixer', 'vllm::short_conv', 'vllm::linear_attention', 'vllm::plamo2_mamba_mixer', 'vllm::gdn_attention_core', 'vllm::kda_attention', 'vllm::sparse_attn_indexer'], 'compile_mm_encoder': False, 'compile_sizes': [], 'compile_ranges_split_points': [8192], 'inductor_compile_config': {'enable_auto_functionalized_v2': False, 'combo_kernels': True, 'benchmark_combo_kernel': True}, 'inductor_passes': {}, 'cudagraph_mode': , 'cudagraph_num_of_warmups': 1, 'cudagraph_capture_sizes': [1, 2, 4, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232, 240, 248, 256, 272, 288, 304, 320, 336, 352, 368, 384, 400, 416, 432, 448, 464, 480, 496, 512], 'cudagraph_copy_inputs': False, 'cudagraph_specialize_lora': True, 'use_inductor_graph_partition': False, 'pass_config': {'fuse_norm_quant': False, 'fuse_act_quant': False, 'fuse_attn_quant': False, 'eliminate_noops': True, 'enable_sp': False, 'fuse_gemm_comms': False, 'fuse_allreduce_rms': False}, 'max_cudagraph_capture_size': 512, 'dynamic_shapes_config': {'type': , 'evaluate_guards': False, 'assume_32_bit_indexing': True}, 'local_cache_dir': None}\n", + "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m INFO 01-29 21:24:21 [parallel_state.py:1214] world_size=1 rank=0 local_rank=0 distributed_init_method=tcp://172.24.215.16:51509 backend=nccl\n", + "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m INFO 01-29 21:24:23 [parallel_state.py:1425] rank 0 in world size 1 is assigned as DP rank 0, PP rank 0, PCP rank 0, TP rank 0, EP rank N/A\n", + "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m WARNING 01-29 21:24:23 [interface.py:470] Using 'pin_memory=False' as WSL is detected. This may slow down the performance.\n", + "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m INFO 01-29 21:24:23 [gpu_model_runner.py:3808] Starting to load model RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8...\n", + "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m INFO 01-29 21:24:23 [compressed_tensors_w8a8_int8.py:62] Using CutlassScaledMMLinearKernel for CompressedTensorsW8A8Int8\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m /home/matthewli125/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/tvm_ffi/_optional_torch_c_dlpack.py:174: UserWarning: Failed to JIT torch c dlpack extension, EnvTensorAllocator will not be enabled.\n", + "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m We recommend installing via `pip install torch-c-dlpack-ext`\n", + "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m warnings.warn(\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m INFO 01-29 21:24:25 [cuda.py:351] Using FLASH_ATTN attention backend out of potential backends: ('FLASH_ATTN', 'FLASHINFER', 'TRITON_ATTN', 'FLEX_ATTENTION')\n", + "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m INFO 01-29 21:24:25 [weight_utils.py:550] No model.safetensors.index.json found in remote.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Loading safetensors checkpoint shards: 0% Completed | 0/1 [00:00╭─────────────────────────────────────── New run - VerboseLowFidelityAgent ───────────────────────────────────────╮\n", + " \n", + " Given the following joint configuration: \n", + " \n", + " joint_configuration = { \n", + " \"load\": 60000, \n", + " \"desired_safety_factor\": 3.0, \n", + " \"bolt_yield_strength\": 940, \n", + " \"plate_yield_strength\": 250, \n", + " \"preload\": 150000, \n", + " \"pitch\": 1.5, \n", + " \"plate_thickness\": 10, \n", + " \"bolt_elastic_modulus\": 210, \n", + " \"plate_elastic_modulus\": 210 \n", + " } \n", + " \n", + " Determine the optimal number of bolts and the major diameter of the bolts: \n", + " \n", + "╰─ VLLMModel - RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8 ───────────────────────────────────────────────────────╯\n", + "\n" + ], + "text/plain": [ + "\u001b[38;2;212;183;2m╭─\u001b[0m\u001b[38;2;212;183;2m──────────────────────────────────────\u001b[0m\u001b[38;2;212;183;2m \u001b[0m\u001b[1;38;2;212;183;2mNew run - VerboseLowFidelityAgent\u001b[0m\u001b[38;2;212;183;2m \u001b[0m\u001b[38;2;212;183;2m──────────────────────────────────────\u001b[0m\u001b[38;2;212;183;2m─╮\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1mGiven the following joint configuration:\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1mjoint_configuration = {\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"load\": 60000,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"desired_safety_factor\": 3.0,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"bolt_yield_strength\": 940,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"plate_yield_strength\": 250,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"preload\": 150000,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"pitch\": 1.5,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"plate_thickness\": 10,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"bolt_elastic_modulus\": 210,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"plate_elastic_modulus\": 210\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m }\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1mDetermine the optimal number of bolts and the major diameter of the bolts:\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m│\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", + "\u001b[38;2;212;183;2m╰─\u001b[0m\u001b[38;2;212;183;2m VLLMModel - RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8 \u001b[0m\u001b[38;2;212;183;2m──────────────────────────────────────────────────────\u001b[0m\u001b[38;2;212;183;2m─╯\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Step 1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;2;212;183;2m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ \u001b[0m\u001b[1;37mStep 1\u001b[0m\u001b[38;2;212;183;2m ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Adding requests: 100%|██████████| 1/1 [00:00<00:00, 134.97it/s]\n", + "Processed prompts: 0%| | 0/1 [00:00[Step 1: Duration 290.16 seconds]\n", + "\n" + ], + "text/plain": [ + "\u001b[2m[Step 1: Duration 290.16 seconds]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[6], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m agent \u001b[38;5;241m=\u001b[39m VerboseLowFidelityAgent(model, joint_configuration, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mverbose low fidelity agent\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mverbose prompts + minimized + reason 512 + gpt 11\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;241m3.0\u001b[39m, logger, max_steps\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m100\u001b[39m)\n\u001b[1;32m 2\u001b[0m instruction \u001b[38;5;241m=\u001b[39m verbose_prompts\u001b[38;5;241m.\u001b[39mEXAMPLE_TASK_INSTRUCTIONS\u001b[38;5;241m.\u001b[39mformat(\u001b[38;5;28minput\u001b[39m)\n\u001b[0;32m----> 3\u001b[0m \u001b[43magent\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[43minstruction\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/smolagents/agents.py:498\u001b[0m, in \u001b[0;36mMultiStepAgent.run\u001b[0;34m(self, task, stream, reset, images, additional_args, max_steps, return_full_result)\u001b[0m\n\u001b[1;32m 495\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_run_stream(task\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtask, max_steps\u001b[38;5;241m=\u001b[39mmax_steps, images\u001b[38;5;241m=\u001b[39mimages)\n\u001b[1;32m 497\u001b[0m run_start_time \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime()\n\u001b[0;32m--> 498\u001b[0m steps \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mlist\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_stream\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmax_steps\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmax_steps\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mimages\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mimages\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 500\u001b[0m \u001b[38;5;66;03m# Outputs are returned only at the end. We only look at the last step.\u001b[39;00m\n\u001b[1;32m 501\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(steps[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m], FinalAnswerStep)\n", + "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/smolagents/agents.py:577\u001b[0m, in \u001b[0;36mMultiStepAgent._run_stream\u001b[0;34m(self, task, max_steps, images)\u001b[0m\n\u001b[1;32m 575\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlogger\u001b[38;5;241m.\u001b[39mlog_rule(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mStep \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstep_number\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m, level\u001b[38;5;241m=\u001b[39mLogLevel\u001b[38;5;241m.\u001b[39mINFO)\n\u001b[1;32m 576\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 577\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m output \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_step_stream(action_step):\n\u001b[1;32m 578\u001b[0m \u001b[38;5;66;03m# Yield all\u001b[39;00m\n\u001b[1;32m 579\u001b[0m \u001b[38;5;28;01myield\u001b[39;00m output\n\u001b[1;32m 581\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(output, ActionOutput) \u001b[38;5;129;01mand\u001b[39;00m output\u001b[38;5;241m.\u001b[39mis_final_answer:\n", + "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/smolagents/agents.py:1293\u001b[0m, in \u001b[0;36mToolCallingAgent._step_stream\u001b[0;34m(self, memory_step)\u001b[0m\n\u001b[1;32m 1291\u001b[0m chat_message \u001b[38;5;241m=\u001b[39m agglomerate_stream_deltas(chat_message_stream_deltas)\n\u001b[1;32m 1292\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 1293\u001b[0m chat_message: ChatMessage \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgenerate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 1294\u001b[0m \u001b[43m \u001b[49m\u001b[43minput_messages\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1295\u001b[0m \u001b[43m \u001b[49m\u001b[43mstop_sequences\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mObservation:\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mCalling tools:\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1296\u001b[0m \u001b[43m \u001b[49m\u001b[43mtools_to_call_from\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtools_and_managed_agents\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1297\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1298\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlogger\u001b[38;5;241m.\u001b[39mlog_markdown(\n\u001b[1;32m 1299\u001b[0m content\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mstr\u001b[39m(chat_message\u001b[38;5;241m.\u001b[39mcontent \u001b[38;5;129;01mor\u001b[39;00m chat_message\u001b[38;5;241m.\u001b[39mraw \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m\"\u001b[39m),\n\u001b[1;32m 1300\u001b[0m title\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mOutput message of the LLM:\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 1301\u001b[0m level\u001b[38;5;241m=\u001b[39mLogLevel\u001b[38;5;241m.\u001b[39mDEBUG,\n\u001b[1;32m 1302\u001b[0m )\n\u001b[1;32m 1304\u001b[0m \u001b[38;5;66;03m# Record model output\u001b[39;00m\n", + "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/smolagents/models.py:731\u001b[0m, in \u001b[0;36mVLLMModel.generate\u001b[0;34m(self, messages, stop_sequences, response_format, tools_to_call_from, **kwargs)\u001b[0m\n\u001b[1;32m 715\u001b[0m prompt \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtokenizer\u001b[38;5;241m.\u001b[39mapply_chat_template(\n\u001b[1;32m 716\u001b[0m messages,\n\u001b[1;32m 717\u001b[0m tools\u001b[38;5;241m=\u001b[39mtools,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 720\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mapply_chat_template_kwargs,\n\u001b[1;32m 721\u001b[0m )\n\u001b[1;32m 723\u001b[0m sampling_params \u001b[38;5;241m=\u001b[39m SamplingParams(\n\u001b[1;32m 724\u001b[0m n\u001b[38;5;241m=\u001b[39mkwargs\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mn\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;241m1\u001b[39m),\n\u001b[1;32m 725\u001b[0m temperature\u001b[38;5;241m=\u001b[39mkwargs\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtemperature\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;241m0.0\u001b[39m),\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 728\u001b[0m structured_outputs\u001b[38;5;241m=\u001b[39mstructured_outputs,\n\u001b[1;32m 729\u001b[0m )\n\u001b[0;32m--> 731\u001b[0m out \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgenerate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 732\u001b[0m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 733\u001b[0m \u001b[43m \u001b[49m\u001b[43msampling_params\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msampling_params\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 734\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcompletion_kwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 735\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 737\u001b[0m output_text \u001b[38;5;241m=\u001b[39m out[\u001b[38;5;241m0\u001b[39m]\u001b[38;5;241m.\u001b[39moutputs[\u001b[38;5;241m0\u001b[39m]\u001b[38;5;241m.\u001b[39mtext\n\u001b[1;32m 738\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m stop_sequences \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msupports_stop_parameter:\n", + "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/vllm/entrypoints/llm.py:439\u001b[0m, in \u001b[0;36mLLM.generate\u001b[0;34m(self, prompts, sampling_params, use_tqdm, lora_request, priority)\u001b[0m\n\u001b[1;32m 429\u001b[0m lora_request \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_modality_specific_lora_reqs(prompts, lora_request)\n\u001b[1;32m 431\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_validate_and_add_requests(\n\u001b[1;32m 432\u001b[0m prompts\u001b[38;5;241m=\u001b[39mprompts,\n\u001b[1;32m 433\u001b[0m params\u001b[38;5;241m=\u001b[39msampling_params,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 436\u001b[0m priority\u001b[38;5;241m=\u001b[39mpriority,\n\u001b[1;32m 437\u001b[0m )\n\u001b[0;32m--> 439\u001b[0m outputs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_engine\u001b[49m\u001b[43m(\u001b[49m\u001b[43muse_tqdm\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43muse_tqdm\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 440\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mengine_class\u001b[38;5;241m.\u001b[39mvalidate_outputs(outputs, RequestOutput)\n", + "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/vllm/entrypoints/llm.py:1764\u001b[0m, in \u001b[0;36mLLM._run_engine\u001b[0;34m(self, use_tqdm)\u001b[0m\n\u001b[1;32m 1762\u001b[0m total_out_toks \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0\u001b[39m\n\u001b[1;32m 1763\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mllm_engine\u001b[38;5;241m.\u001b[39mhas_unfinished_requests():\n\u001b[0;32m-> 1764\u001b[0m step_outputs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mllm_engine\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstep\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1765\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m output \u001b[38;5;129;01min\u001b[39;00m step_outputs:\n\u001b[1;32m 1766\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m output\u001b[38;5;241m.\u001b[39mfinished:\n", + "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/vllm/v1/engine/llm_engine.py:294\u001b[0m, in \u001b[0;36mLLMEngine.step\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 292\u001b[0m \u001b[38;5;66;03m# 1) Get EngineCoreOutput from the EngineCore.\u001b[39;00m\n\u001b[1;32m 293\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m record_function_or_nullcontext(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mllm_engine step: get_output\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[0;32m--> 294\u001b[0m outputs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mengine_core\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_output\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 296\u001b[0m \u001b[38;5;66;03m# 2) Process EngineCoreOutputs.\u001b[39;00m\n\u001b[1;32m 297\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m record_function_or_nullcontext(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mllm_engine step: process_outputs\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n", + "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/vllm/v1/engine/core_client.py:719\u001b[0m, in \u001b[0;36mSyncMPClient.get_output\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 715\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mget_output\u001b[39m(\u001b[38;5;28mself\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m EngineCoreOutputs:\n\u001b[1;32m 716\u001b[0m \u001b[38;5;66;03m# If an exception arises in process_outputs_socket task,\u001b[39;00m\n\u001b[1;32m 717\u001b[0m \u001b[38;5;66;03m# it is forwarded to the outputs_queue so we can raise it\u001b[39;00m\n\u001b[1;32m 718\u001b[0m \u001b[38;5;66;03m# from this (run_output_handler) task to shut down the server.\u001b[39;00m\n\u001b[0;32m--> 719\u001b[0m outputs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43moutputs_queue\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 720\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(outputs, \u001b[38;5;167;01mException\u001b[39;00m):\n\u001b[1;32m 721\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_format_exception(outputs) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m\n", + "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/queue.py:171\u001b[0m, in \u001b[0;36mQueue.get\u001b[0;34m(self, block, timeout)\u001b[0m\n\u001b[1;32m 169\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m timeout \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 170\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_qsize():\n\u001b[0;32m--> 171\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnot_empty\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mwait\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 172\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m timeout \u001b[38;5;241m<\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[1;32m 173\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtimeout\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m must be a non-negative number\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", + "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/threading.py:320\u001b[0m, in \u001b[0;36mCondition.wait\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m 318\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m: \u001b[38;5;66;03m# restore state no matter what (e.g., KeyboardInterrupt)\u001b[39;00m\n\u001b[1;32m 319\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m timeout \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 320\u001b[0m \u001b[43mwaiter\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43macquire\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 321\u001b[0m gotit \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m 322\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ERROR 01-29 21:29:41 [core_client.py:610] Engine core proc EngineCore_DP0 died unexpectedly, shutting down client.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[rank0]:[W129 21:29:41.511292951 ProcessGroupNCCL.cpp:1524] Warning: WARNING: destroy_process_group() was not called before program exit, which can leak resources. For more info, please see https://pytorch.org/docs/stable/distributed.html#shutdown (function operator())\n" + ] + } + ], "source": [ - "agent = VerboseLowFidelityAgent(model, joint_configuration, \"verbose low fidelity agent\", f\"verbose prompts + minimized + reason 512 + gpt 1\", 3.0, logger, max_steps=100)\n", + "agent = VerboseLowFidelityAgent(model, joint_configuration, \"verbose low fidelity agent\", f\"verbose prompts + minimized + reason 512 + gpt 11\", 3.0, logger, max_steps=100)\n", "instruction = verbose_prompts.EXAMPLE_TASK_INSTRUCTIONS.format(input)\n", "agent.run(instruction)" ] From ad42799fdcdbd9505c4ffb6ab9a848d59e97b848 Mon Sep 17 00:00:00 2001 From: matthewli125 Date: Thu, 29 Jan 2026 21:35:14 -0800 Subject: [PATCH 12/12] remove outputs from notebooks --- utilities/agent_testing.ipynb | 241 +----------------------- utilities/tool_testing.ipynb | 335 ++-------------------------------- 2 files changed, 21 insertions(+), 555 deletions(-) diff --git a/utilities/agent_testing.ipynb b/utilities/agent_testing.ipynb index 279e912..3354bb6 100644 --- a/utilities/agent_testing.ipynb +++ b/utilities/agent_testing.ipynb @@ -10,21 +10,10 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "aa00e50c", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/matthewli125/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", - " from .autonotebook import tqdm as notebook_tqdm\n", - "/home/matthewli125/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/ufl/__init__.py:250: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.\n", - " import pkg_resources\n" - ] - } - ], + "outputs": [], "source": [ "from autoboltagent import verbose_prompts, grammars\n", "from autoboltagent import prompts\n", @@ -36,7 +25,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "85dcc950", "metadata": {}, "outputs": [], @@ -64,7 +53,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "c84a2a1a", "metadata": {}, "outputs": [], @@ -83,7 +72,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "653c34d2", "metadata": {}, "outputs": [], @@ -141,103 +130,10 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "4143950e", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 01-29 21:24:13 [utils.py:263] non-default args: {'gpu_memory_utilization': 0.85, 'disable_log_stats': True, 'model': 'RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8'}\n", - "INFO 01-29 21:24:14 [model.py:530] Resolved architecture: Qwen2ForCausalLM\n", - "INFO 01-29 21:24:14 [model.py:1545] Using max model len 32768\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2026-01-29 21:24:15,764\tINFO util.py:154 -- Missing packages: ['ipywidgets']. Run `pip install -U ipywidgets`, then restart the notebook server for rich notebook output.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 01-29 21:24:15 [scheduler.py:229] Chunked prefill is enabled with max_num_batched_tokens=8192.\n", - "INFO 01-29 21:24:15 [vllm.py:630] Asynchronous scheduling is enabled.\n", - "INFO 01-29 21:24:15 [vllm.py:637] Disabling NCCL for DP synchronization when using async scheduling.\n", - "WARNING 01-29 21:24:16 [interface.py:470] Using 'pin_memory=False' as WSL is detected. This may slow down the performance.\n", - "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m INFO 01-29 21:24:21 [core.py:97] Initializing a V1 LLM engine (v0.14.1) with config: model='RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8', speculative_config=None, tokenizer='RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8', skip_tokenizer_init=False, tokenizer_mode=auto, revision=None, tokenizer_revision=None, trust_remote_code=False, dtype=torch.bfloat16, max_seq_len=32768, download_dir=None, load_format=auto, tensor_parallel_size=1, pipeline_parallel_size=1, data_parallel_size=1, disable_custom_all_reduce=False, quantization=compressed-tensors, enforce_eager=False, enable_return_routed_experts=False, kv_cache_dtype=auto, device_config=cuda, structured_outputs_config=StructuredOutputsConfig(backend='auto', disable_fallback=False, disable_any_whitespace=False, disable_additional_properties=False, reasoning_parser='', reasoning_parser_plugin='', enable_in_reasoning=False), observability_config=ObservabilityConfig(show_hidden_metrics_for_version=None, otlp_traces_endpoint=None, collect_detailed_traces=None, kv_cache_metrics=False, kv_cache_metrics_sample=0.01, cudagraph_metrics=False, enable_layerwise_nvtx_tracing=False, enable_mfu_metrics=False, enable_mm_processor_stats=False, enable_logging_iteration_details=False), seed=0, served_model_name=RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8, enable_prefix_caching=True, enable_chunked_prefill=True, pooler_config=None, compilation_config={'level': None, 'mode': , 'debug_dump_path': None, 'cache_dir': '', 'compile_cache_save_format': 'binary', 'backend': 'inductor', 'custom_ops': ['none'], 'splitting_ops': ['vllm::unified_attention', 'vllm::unified_attention_with_output', 'vllm::unified_mla_attention', 'vllm::unified_mla_attention_with_output', 'vllm::mamba_mixer2', 'vllm::mamba_mixer', 'vllm::short_conv', 'vllm::linear_attention', 'vllm::plamo2_mamba_mixer', 'vllm::gdn_attention_core', 'vllm::kda_attention', 'vllm::sparse_attn_indexer'], 'compile_mm_encoder': False, 'compile_sizes': [], 'compile_ranges_split_points': [8192], 'inductor_compile_config': {'enable_auto_functionalized_v2': False, 'combo_kernels': True, 'benchmark_combo_kernel': True}, 'inductor_passes': {}, 'cudagraph_mode': , 'cudagraph_num_of_warmups': 1, 'cudagraph_capture_sizes': [1, 2, 4, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232, 240, 248, 256, 272, 288, 304, 320, 336, 352, 368, 384, 400, 416, 432, 448, 464, 480, 496, 512], 'cudagraph_copy_inputs': False, 'cudagraph_specialize_lora': True, 'use_inductor_graph_partition': False, 'pass_config': {'fuse_norm_quant': False, 'fuse_act_quant': False, 'fuse_attn_quant': False, 'eliminate_noops': True, 'enable_sp': False, 'fuse_gemm_comms': False, 'fuse_allreduce_rms': False}, 'max_cudagraph_capture_size': 512, 'dynamic_shapes_config': {'type': , 'evaluate_guards': False, 'assume_32_bit_indexing': True}, 'local_cache_dir': None}\n", - "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m INFO 01-29 21:24:21 [parallel_state.py:1214] world_size=1 rank=0 local_rank=0 distributed_init_method=tcp://172.24.215.16:51509 backend=nccl\n", - "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m INFO 01-29 21:24:23 [parallel_state.py:1425] rank 0 in world size 1 is assigned as DP rank 0, PP rank 0, PCP rank 0, TP rank 0, EP rank N/A\n", - "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m WARNING 01-29 21:24:23 [interface.py:470] Using 'pin_memory=False' as WSL is detected. This may slow down the performance.\n", - "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m INFO 01-29 21:24:23 [gpu_model_runner.py:3808] Starting to load model RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8...\n", - "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m INFO 01-29 21:24:23 [compressed_tensors_w8a8_int8.py:62] Using CutlassScaledMMLinearKernel for CompressedTensorsW8A8Int8\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m /home/matthewli125/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/tvm_ffi/_optional_torch_c_dlpack.py:174: UserWarning: Failed to JIT torch c dlpack extension, EnvTensorAllocator will not be enabled.\n", - "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m We recommend installing via `pip install torch-c-dlpack-ext`\n", - "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m warnings.warn(\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m INFO 01-29 21:24:25 [cuda.py:351] Using FLASH_ATTN attention backend out of potential backends: ('FLASH_ATTN', 'FLASHINFER', 'TRITON_ATTN', 'FLEX_ATTENTION')\n", - "\u001b[0;36m(EngineCore_DP0 pid=40850)\u001b[0;0m INFO 01-29 21:24:25 [weight_utils.py:550] No model.safetensors.index.json found in remote.\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Loading safetensors checkpoint shards: 0% Completed | 0/1 [00:00╭─────────────────────────────────────── New run - VerboseLowFidelityAgent ───────────────────────────────────────╮\n", - " \n", - " Given the following joint configuration: \n", - " \n", - " joint_configuration = { \n", - " \"load\": 60000, \n", - " \"desired_safety_factor\": 3.0, \n", - " \"bolt_yield_strength\": 940, \n", - " \"plate_yield_strength\": 250, \n", - " \"preload\": 150000, \n", - " \"pitch\": 1.5, \n", - " \"plate_thickness\": 10, \n", - " \"bolt_elastic_modulus\": 210, \n", - " \"plate_elastic_modulus\": 210 \n", - " } \n", - " \n", - " Determine the optimal number of bolts and the major diameter of the bolts: \n", - " \n", - "╰─ VLLMModel - RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8 ───────────────────────────────────────────────────────╯\n", - "\n" - ], - "text/plain": [ - "\u001b[38;2;212;183;2m╭─\u001b[0m\u001b[38;2;212;183;2m──────────────────────────────────────\u001b[0m\u001b[38;2;212;183;2m \u001b[0m\u001b[1;38;2;212;183;2mNew run - VerboseLowFidelityAgent\u001b[0m\u001b[38;2;212;183;2m \u001b[0m\u001b[38;2;212;183;2m──────────────────────────────────────\u001b[0m\u001b[38;2;212;183;2m─╮\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1mGiven the following joint configuration:\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1mjoint_configuration = {\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"load\": 60000,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"desired_safety_factor\": 3.0,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"bolt_yield_strength\": 940,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"plate_yield_strength\": 250,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"preload\": 150000,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"pitch\": 1.5,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"plate_thickness\": 10,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"bolt_elastic_modulus\": 210,\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m \"plate_elastic_modulus\": 210\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1m }\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[1mDetermine the optimal number of bolts and the major diameter of the bolts:\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m│\u001b[0m \u001b[38;2;212;183;2m│\u001b[0m\n", - "\u001b[38;2;212;183;2m╰─\u001b[0m\u001b[38;2;212;183;2m VLLMModel - RedHatAI/Qwen2.5-3B-Instruct-quantized.w8a8 \u001b[0m\u001b[38;2;212;183;2m──────────────────────────────────────────────────────\u001b[0m\u001b[38;2;212;183;2m─╯\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Step 1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[38;2;212;183;2m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ \u001b[0m\u001b[1;37mStep 1\u001b[0m\u001b[38;2;212;183;2m ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Adding requests: 100%|██████████| 1/1 [00:00<00:00, 134.97it/s]\n", - "Processed prompts: 0%| | 0/1 [00:00[Step 1: Duration 290.16 seconds]\n", - "\n" - ], - "text/plain": [ - "\u001b[2m[Step 1: Duration 290.16 seconds]\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[6], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m agent \u001b[38;5;241m=\u001b[39m VerboseLowFidelityAgent(model, joint_configuration, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mverbose low fidelity agent\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mverbose prompts + minimized + reason 512 + gpt 11\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;241m3.0\u001b[39m, logger, max_steps\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m100\u001b[39m)\n\u001b[1;32m 2\u001b[0m instruction \u001b[38;5;241m=\u001b[39m verbose_prompts\u001b[38;5;241m.\u001b[39mEXAMPLE_TASK_INSTRUCTIONS\u001b[38;5;241m.\u001b[39mformat(\u001b[38;5;28minput\u001b[39m)\n\u001b[0;32m----> 3\u001b[0m \u001b[43magent\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[43minstruction\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/smolagents/agents.py:498\u001b[0m, in \u001b[0;36mMultiStepAgent.run\u001b[0;34m(self, task, stream, reset, images, additional_args, max_steps, return_full_result)\u001b[0m\n\u001b[1;32m 495\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_run_stream(task\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtask, max_steps\u001b[38;5;241m=\u001b[39mmax_steps, images\u001b[38;5;241m=\u001b[39mimages)\n\u001b[1;32m 497\u001b[0m run_start_time \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mtime()\n\u001b[0;32m--> 498\u001b[0m steps \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mlist\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_stream\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtask\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtask\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmax_steps\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmax_steps\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mimages\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mimages\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 500\u001b[0m \u001b[38;5;66;03m# Outputs are returned only at the end. We only look at the last step.\u001b[39;00m\n\u001b[1;32m 501\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(steps[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m], FinalAnswerStep)\n", - "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/smolagents/agents.py:577\u001b[0m, in \u001b[0;36mMultiStepAgent._run_stream\u001b[0;34m(self, task, max_steps, images)\u001b[0m\n\u001b[1;32m 575\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlogger\u001b[38;5;241m.\u001b[39mlog_rule(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mStep \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstep_number\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m, level\u001b[38;5;241m=\u001b[39mLogLevel\u001b[38;5;241m.\u001b[39mINFO)\n\u001b[1;32m 576\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 577\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m output \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_step_stream(action_step):\n\u001b[1;32m 578\u001b[0m \u001b[38;5;66;03m# Yield all\u001b[39;00m\n\u001b[1;32m 579\u001b[0m \u001b[38;5;28;01myield\u001b[39;00m output\n\u001b[1;32m 581\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(output, ActionOutput) \u001b[38;5;129;01mand\u001b[39;00m output\u001b[38;5;241m.\u001b[39mis_final_answer:\n", - "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/smolagents/agents.py:1293\u001b[0m, in \u001b[0;36mToolCallingAgent._step_stream\u001b[0;34m(self, memory_step)\u001b[0m\n\u001b[1;32m 1291\u001b[0m chat_message \u001b[38;5;241m=\u001b[39m agglomerate_stream_deltas(chat_message_stream_deltas)\n\u001b[1;32m 1292\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 1293\u001b[0m chat_message: ChatMessage \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgenerate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 1294\u001b[0m \u001b[43m \u001b[49m\u001b[43minput_messages\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1295\u001b[0m \u001b[43m \u001b[49m\u001b[43mstop_sequences\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mObservation:\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mCalling tools:\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1296\u001b[0m \u001b[43m \u001b[49m\u001b[43mtools_to_call_from\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtools_and_managed_agents\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1297\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1298\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlogger\u001b[38;5;241m.\u001b[39mlog_markdown(\n\u001b[1;32m 1299\u001b[0m content\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mstr\u001b[39m(chat_message\u001b[38;5;241m.\u001b[39mcontent \u001b[38;5;129;01mor\u001b[39;00m chat_message\u001b[38;5;241m.\u001b[39mraw \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m\"\u001b[39m),\n\u001b[1;32m 1300\u001b[0m title\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mOutput message of the LLM:\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 1301\u001b[0m level\u001b[38;5;241m=\u001b[39mLogLevel\u001b[38;5;241m.\u001b[39mDEBUG,\n\u001b[1;32m 1302\u001b[0m )\n\u001b[1;32m 1304\u001b[0m \u001b[38;5;66;03m# Record model output\u001b[39;00m\n", - "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/smolagents/models.py:731\u001b[0m, in \u001b[0;36mVLLMModel.generate\u001b[0;34m(self, messages, stop_sequences, response_format, tools_to_call_from, **kwargs)\u001b[0m\n\u001b[1;32m 715\u001b[0m prompt \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtokenizer\u001b[38;5;241m.\u001b[39mapply_chat_template(\n\u001b[1;32m 716\u001b[0m messages,\n\u001b[1;32m 717\u001b[0m tools\u001b[38;5;241m=\u001b[39mtools,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 720\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mapply_chat_template_kwargs,\n\u001b[1;32m 721\u001b[0m )\n\u001b[1;32m 723\u001b[0m sampling_params \u001b[38;5;241m=\u001b[39m SamplingParams(\n\u001b[1;32m 724\u001b[0m n\u001b[38;5;241m=\u001b[39mkwargs\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mn\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;241m1\u001b[39m),\n\u001b[1;32m 725\u001b[0m temperature\u001b[38;5;241m=\u001b[39mkwargs\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtemperature\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;241m0.0\u001b[39m),\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 728\u001b[0m structured_outputs\u001b[38;5;241m=\u001b[39mstructured_outputs,\n\u001b[1;32m 729\u001b[0m )\n\u001b[0;32m--> 731\u001b[0m out \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgenerate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 732\u001b[0m \u001b[43m \u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 733\u001b[0m \u001b[43m \u001b[49m\u001b[43msampling_params\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msampling_params\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 734\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcompletion_kwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 735\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 737\u001b[0m output_text \u001b[38;5;241m=\u001b[39m out[\u001b[38;5;241m0\u001b[39m]\u001b[38;5;241m.\u001b[39moutputs[\u001b[38;5;241m0\u001b[39m]\u001b[38;5;241m.\u001b[39mtext\n\u001b[1;32m 738\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m stop_sequences \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msupports_stop_parameter:\n", - "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/vllm/entrypoints/llm.py:439\u001b[0m, in \u001b[0;36mLLM.generate\u001b[0;34m(self, prompts, sampling_params, use_tqdm, lora_request, priority)\u001b[0m\n\u001b[1;32m 429\u001b[0m lora_request \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_modality_specific_lora_reqs(prompts, lora_request)\n\u001b[1;32m 431\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_validate_and_add_requests(\n\u001b[1;32m 432\u001b[0m prompts\u001b[38;5;241m=\u001b[39mprompts,\n\u001b[1;32m 433\u001b[0m params\u001b[38;5;241m=\u001b[39msampling_params,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 436\u001b[0m priority\u001b[38;5;241m=\u001b[39mpriority,\n\u001b[1;32m 437\u001b[0m )\n\u001b[0;32m--> 439\u001b[0m outputs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_engine\u001b[49m\u001b[43m(\u001b[49m\u001b[43muse_tqdm\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43muse_tqdm\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 440\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mengine_class\u001b[38;5;241m.\u001b[39mvalidate_outputs(outputs, RequestOutput)\n", - "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/vllm/entrypoints/llm.py:1764\u001b[0m, in \u001b[0;36mLLM._run_engine\u001b[0;34m(self, use_tqdm)\u001b[0m\n\u001b[1;32m 1762\u001b[0m total_out_toks \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0\u001b[39m\n\u001b[1;32m 1763\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mllm_engine\u001b[38;5;241m.\u001b[39mhas_unfinished_requests():\n\u001b[0;32m-> 1764\u001b[0m step_outputs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mllm_engine\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstep\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1765\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m output \u001b[38;5;129;01min\u001b[39;00m step_outputs:\n\u001b[1;32m 1766\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m output\u001b[38;5;241m.\u001b[39mfinished:\n", - "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/vllm/v1/engine/llm_engine.py:294\u001b[0m, in \u001b[0;36mLLMEngine.step\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 292\u001b[0m \u001b[38;5;66;03m# 1) Get EngineCoreOutput from the EngineCore.\u001b[39;00m\n\u001b[1;32m 293\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m record_function_or_nullcontext(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mllm_engine step: get_output\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[0;32m--> 294\u001b[0m outputs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mengine_core\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_output\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 296\u001b[0m \u001b[38;5;66;03m# 2) Process EngineCoreOutputs.\u001b[39;00m\n\u001b[1;32m 297\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m record_function_or_nullcontext(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mllm_engine step: process_outputs\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n", - "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/vllm/v1/engine/core_client.py:719\u001b[0m, in \u001b[0;36mSyncMPClient.get_output\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 715\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mget_output\u001b[39m(\u001b[38;5;28mself\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m EngineCoreOutputs:\n\u001b[1;32m 716\u001b[0m \u001b[38;5;66;03m# If an exception arises in process_outputs_socket task,\u001b[39;00m\n\u001b[1;32m 717\u001b[0m \u001b[38;5;66;03m# it is forwarded to the outputs_queue so we can raise it\u001b[39;00m\n\u001b[1;32m 718\u001b[0m \u001b[38;5;66;03m# from this (run_output_handler) task to shut down the server.\u001b[39;00m\n\u001b[0;32m--> 719\u001b[0m outputs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43moutputs_queue\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 720\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(outputs, \u001b[38;5;167;01mException\u001b[39;00m):\n\u001b[1;32m 721\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_format_exception(outputs) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m\n", - "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/queue.py:171\u001b[0m, in \u001b[0;36mQueue.get\u001b[0;34m(self, block, timeout)\u001b[0m\n\u001b[1;32m 169\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m timeout \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 170\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_qsize():\n\u001b[0;32m--> 171\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnot_empty\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mwait\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 172\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m timeout \u001b[38;5;241m<\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[1;32m 173\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtimeout\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m must be a non-negative number\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", - "File \u001b[0;32m~/miniconda3/envs/autoboltagent/lib/python3.10/threading.py:320\u001b[0m, in \u001b[0;36mCondition.wait\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m 318\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m: \u001b[38;5;66;03m# restore state no matter what (e.g., KeyboardInterrupt)\u001b[39;00m\n\u001b[1;32m 319\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m timeout \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 320\u001b[0m \u001b[43mwaiter\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43macquire\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 321\u001b[0m gotit \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m 322\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ERROR 01-29 21:29:41 [core_client.py:610] Engine core proc EngineCore_DP0 died unexpectedly, shutting down client.\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "[rank0]:[W129 21:29:41.511292951 ProcessGroupNCCL.cpp:1524] Warning: WARNING: destroy_process_group() was not called before program exit, which can leak resources. For more info, please see https://pytorch.org/docs/stable/distributed.html#shutdown (function operator())\n" - ] - } - ], + "outputs": [], "source": [ "agent = VerboseLowFidelityAgent(model, joint_configuration, \"verbose low fidelity agent\", f\"verbose prompts + minimized + reason 512 + gpt 11\", 3.0, logger, max_steps=100)\n", "instruction = verbose_prompts.EXAMPLE_TASK_INSTRUCTIONS.format(input)\n", diff --git a/utilities/tool_testing.ipynb b/utilities/tool_testing.ipynb index 8f2e8d3..10a05a7 100644 --- a/utilities/tool_testing.ipynb +++ b/utilities/tool_testing.ipynb @@ -10,21 +10,10 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "44771eae", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/matthewli125/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", - " from .autonotebook import tqdm as notebook_tqdm\n", - "/home/matthewli125/miniconda3/envs/autoboltagent/lib/python3.10/site-packages/ufl/__init__.py:250: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.\n", - " import pkg_resources\n" - ] - } - ], + "outputs": [], "source": [ "from autoboltagent.tools.low_fidelity_tool import VerboseAnalyticalTool\n", "from autoboltagent.tools.high_fidelity_tool import VerboseFiniteElementTool" @@ -52,7 +41,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "0f96da72", "metadata": {}, "outputs": [], @@ -72,7 +61,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "bf28dd68", "metadata": {}, "outputs": [], @@ -105,7 +94,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "b8a88d0e", "metadata": {}, "outputs": [], @@ -125,295 +114,20 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "87688dd8", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(2, 17, {'ok': False, 'bolt_fos': 2.1834956164436536, 'bolt_diff': -0.8165043835563464, 'plate_fos': 2.125, 'plate_diff': -0.875})\n" - ] - } - ], + "outputs": [], "source": [ "cached_analytical_guess(past_guesses, num_bolts=2, bolt_diameter=17)" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "id": "d58a840c", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "PETSc Error --- Application was linked against both OpenMPI and MPICH based MPI libraries and will not run correctly\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Info : Reading '/tmp/tmpabrul051/model.step'...\n", - "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:2]/ASSEMBLY/=>[0:1:1:3]/SOLID' (3D)\n", - "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:4]/ASSEMBLY/=>[0:1:1:5]/ASSEMBLY/=>[0:1:1:6]/SOLID' (3D)\n", - "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:7]/ASSEMBLY/=>[0:1:1:8]/SOLID' (3D)\n", - "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:7]/ASSEMBLY/=>[0:1:1:9]/SOLID' (3D)\n", - "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:3]/SOLID' (3D)\n", - "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:5]/ASSEMBLY/=>[0:1:1:6]/SOLID' (3D)\n", - "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:6]/SOLID' (3D)\n", - "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:8]/SOLID' (3D)\n", - "Info : - Label 'Shapes/ASSEMBLY/=>[0:1:1:9]/SOLID' (3D)\n", - "Info : Done reading '/tmp/tmpabrul051/model.step'\n", - "Info : Meshing 1D...\n", - "Info : [ 0%] Meshing curve 1 (Line)\n", - "Info : [ 10%] Meshing curve 2 (Line)\n", - "Info : [ 10%] Meshing curve 3 (Line)\n", - "Info : [ 10%] Meshing curve 4 (Line)\n", - "Info : [ 10%] Meshing curve 5 (Line)\n", - "Info : [ 20%] Meshing curve 6 (Line)\n", - "Info : [ 20%] Meshing curve 7 (Line)\n", - "Info : [ 20%] Meshing curve 8 (Line)\n", - "Info : [ 20%] Meshing curve 9 (Line)\n", - "Info : [ 30%] Meshing curve 10 (Circle)\n", - "Info : [ 30%] Meshing curve 11 (Circle)\n", - "Info : [ 30%] Meshing curve 12 (Line)\n", - "Info : [ 30%] Meshing curve 13 (Line)\n", - "Info : [ 40%] Meshing curve 14 (Line)\n", - "Info : [ 40%] Meshing curve 15 (Circle)\n", - "Info : [ 40%] Meshing curve 16 (Circle)\n", - "Info : [ 40%] Meshing curve 17 (Line)\n", - "Info : [ 50%] Meshing curve 18 (Line)\n", - "Info : [ 50%] Meshing curve 19 (Line)\n", - "Info : [ 50%] Meshing curve 20 (Line)\n", - "Info : [ 50%] Meshing curve 21 (Line)\n", - "Info : [ 60%] Meshing curve 22 (Line)\n", - "Info : [ 60%] Meshing curve 23 (Line)\n", - "Info : [ 60%] Meshing curve 24 (Line)\n", - "Info : [ 60%] Meshing curve 25 (Line)\n", - "Info : [ 60%] Meshing curve 26 (Line)\n", - "Info : [ 70%] Meshing curve 27 (Line)\n", - "Info : [ 70%] Meshing curve 28 (Circle)\n", - "Info : [ 70%] Meshing curve 29 (Circle)\n", - "Info : [ 70%] Meshing curve 30 (Line)\n", - "Info : [ 80%] Meshing curve 31 (Line)\n", - "Info : [ 80%] Meshing curve 32 (Line)\n", - "Info : [ 80%] Meshing curve 33 (Circle)\n", - "Info : [ 80%] Meshing curve 34 (Circle)\n", - "Info : [ 90%] Meshing curve 35 (Line)\n", - "Info : [ 90%] Meshing curve 36 (Line)\n", - "Info : [ 90%] Meshing curve 37 (Circle)\n", - "Info : [ 90%] Meshing curve 38 (Line)\n", - "Info : [100%] Meshing curve 39 (Circle)\n", - "Info : [100%] Meshing curve 40 (Circle)\n", - "Info : [100%] Meshing curve 41 (Line)\n", - "Info : [100%] Meshing curve 42 (Circle)\n", - "Info : Done meshing 1D (Wall 0.00219436s, CPU 0.002691s)\n", - "Info : Meshing 2D...\n", - "Info : [ 0%] Meshing surface 1 (Plane, Frontal-Delaunay)\n", - "Info : [ 10%] Meshing surface 2 (Plane, Frontal-Delaunay)\n", - "Info : [ 10%] Meshing surface 3 (Plane, Frontal-Delaunay)\n", - "Info : [ 20%] Meshing surface 4 (Plane, Frontal-Delaunay)\n", - "Info : [ 20%] Meshing surface 5 (Plane, Frontal-Delaunay)\n", - "Info : [ 30%] Meshing surface 6 (Plane, Frontal-Delaunay)\n", - "Info : [ 30%] Meshing surface 7 (Cylinder, Frontal-Delaunay)\n", - "Info : [ 40%] Meshing surface 8 (Cylinder, Frontal-Delaunay)\n", - "Info : [ 40%] Meshing surface 9 (Plane, Frontal-Delaunay)\n", - "Info : [ 50%] Meshing surface 10 (Plane, Frontal-Delaunay)\n", - "Info : [ 50%] Meshing surface 11 (Plane, Frontal-Delaunay)\n", - "Info : [ 60%] Meshing surface 12 (Plane, Frontal-Delaunay)\n", - "Info : [ 60%] Meshing surface 13 (Plane, Frontal-Delaunay)\n", - "Info : [ 60%] Meshing surface 14 (Plane, Frontal-Delaunay)\n", - "Info : [ 70%] Meshing surface 15 (Cylinder, Frontal-Delaunay)\n", - "Info : [ 70%] Meshing surface 16 (Cylinder, Frontal-Delaunay)\n", - "Info : [ 80%] Meshing surface 17 (Cylinder, Frontal-Delaunay)\n", - "Info : [ 80%] Meshing surface 18 (Plane, Frontal-Delaunay)\n", - "Info : [ 90%] Meshing surface 19 (Plane, Frontal-Delaunay)\n", - "Info : [ 90%] Meshing surface 20 (Cylinder, Frontal-Delaunay)\n", - "Info : [100%] Meshing surface 21 (Plane, Frontal-Delaunay)\n", - "Info : [100%] Meshing surface 22 (Plane, Frontal-Delaunay)\n", - "Info : Done meshing 2D (Wall 0.0719964s, CPU 0.069294s)\n", - "Info : Meshing 3D...\n", - "Info : 3D Meshing 4 volumes with 4 connected components\n", - "Info : Tetrahedrizing 260 nodes...\n", - "Info : Done tetrahedrizing 268 nodes (Wall 0.00138845s, CPU 0.001092s)\n", - "Info : Reconstructing mesh...\n", - "Info : - Creating surface mesh\n", - "Info : - Identifying boundary edges\n", - "Info : - Recovering boundary\n", - "Info : - Added 3 Steiner points\n", - "Info : Done reconstructing mesh (Wall 0.00485352s, CPU 0.004481s)\n", - "Info : Found volume 1\n", - "Info : It. 0 - 0 nodes created - worst tet radius 0.98006 (nodes removed 0 0)\n", - "Info : 3D refinement terminated (587 nodes total):\n", - "Info : - 0 Delaunay cavities modified for star shapeness\n", - "Info : - 0 nodes could not be inserted\n", - "Info : - 705 tetrahedra created in 3.6739e-05 sec. (19189423 tets/s)\n", - "Info : 0 node relocations\n", - "Info : Tetrahedrizing 262 nodes...\n", - "Info : Done tetrahedrizing 270 nodes (Wall 0.00385722s, CPU 0.003864s)\n", - "Info : Reconstructing mesh...\n", - "Info : - Creating surface mesh\n", - "Info : - Identifying boundary edges\n", - "Info : - Recovering boundary\n", - "Info : - Added 2 Steiner points\n", - "Info : Done reconstructing mesh (Wall 0.00803251s, CPU 0.00788s)\n", - "Info : Found volume 2\n", - "Info : It. 0 - 0 nodes created - worst tet radius 0.90247 (nodes removed 0 0)\n", - "Info : 3D refinement terminated (586 nodes total):\n", - "Info : - 0 Delaunay cavities modified for star shapeness\n", - "Info : - 0 nodes could not be inserted\n", - "Info : - 707 tetrahedra created in 2.7909e-05 sec. (25332328 tets/s)\n", - "Info : 0 node relocations\n", - "Info : Tetrahedrizing 31 nodes...\n", - "Info : Done tetrahedrizing 39 nodes (Wall 0.000136907s, CPU 0.000156s)\n", - "Info : Reconstructing mesh...\n", - "Info : - Creating surface mesh\n", - "Info : - Identifying boundary edges\n", - "Info : - Recovering boundary\n", - "Info : Done reconstructing mesh (Wall 0.000363324s, CPU 0.000425s)\n", - "Info : Found volume 3\n", - "Info : It. 0 - 0 nodes created - worst tet radius 2.91212 (nodes removed 0 0)\n", - "Info : 3D refinement terminated (585 nodes total):\n", - "Info : - 0 Delaunay cavities modified for star shapeness\n", - "Info : - 3 nodes could not be inserted\n", - "Info : - 61 tetrahedra created in 8.048e-05 sec. (757952 tets/s)\n", - "Info : 0 node relocations\n", - "Info : Tetrahedrizing 31 nodes...\n", - "Info : Done tetrahedrizing 39 nodes (Wall 0.000130817s, CPU 0.000172s)\n", - "Info : Reconstructing mesh...\n", - "Info : - Creating surface mesh\n", - "Info : - Identifying boundary edges\n", - "Info : - Recovering boundary\n", - "Info : Done reconstructing mesh (Wall 0.000326484s, CPU 0.000452s)\n", - "Info : Found volume 4\n", - "Info : It. 0 - 0 nodes created - worst tet radius 2.91212 (nodes removed 0 0)\n", - "Info : 3D refinement terminated (585 nodes total):\n", - "Info : - 0 Delaunay cavities modified for star shapeness\n", - "Info : - 3 nodes could not be inserted\n", - "Info : - 61 tetrahedra created in 0.00017466 sec. (349249 tets/s)\n", - "Info : 0 node relocations\n", - "Info : Done meshing 3D (Wall 0.0288194s, CPU 0.028817s)\n", - "Info : Optimizing mesh...\n", - "Info : Optimizing volume 1\n", - "Info : Optimization starts (volume = 0.000195872) with worst = 0.153175 / average = 0.67823:\n", - "Info : 0.00 < quality < 0.10 : 0 elements\n", - "Info : 0.10 < quality < 0.20 : 2 elements\n", - "Info : 0.20 < quality < 0.30 : 3 elements\n", - "Info : 0.30 < quality < 0.40 : 41 elements\n", - "Info : 0.40 < quality < 0.50 : 34 elements\n", - "Info : 0.50 < quality < 0.60 : 64 elements\n", - "Info : 0.60 < quality < 0.70 : 176 elements\n", - "Info : 0.70 < quality < 0.80 : 309 elements\n", - "Info : 0.80 < quality < 0.90 : 60 elements\n", - "Info : 0.90 < quality < 1.00 : 16 elements\n", - "Info : 2 edge swaps, 1 node relocations (volume = 0.000195872): worst = 0.29686 / average = 0.680162 (Wall 0.000410718s, CPU 0.000717s)\n", - "Info : No ill-shaped tets in the mesh :-)\n", - "Info : 0.00 < quality < 0.10 : 0 elements\n", - "Info : 0.10 < quality < 0.20 : 0 elements\n", - "Info : 0.20 < quality < 0.30 : 2 elements\n", - "Info : 0.30 < quality < 0.40 : 45 elements\n", - "Info : 0.40 < quality < 0.50 : 29 elements\n", - "Info : 0.50 < quality < 0.60 : 66 elements\n", - "Info : 0.60 < quality < 0.70 : 176 elements\n", - "Info : 0.70 < quality < 0.80 : 309 elements\n", - "Info : 0.80 < quality < 0.90 : 60 elements\n", - "Info : 0.90 < quality < 1.00 : 16 elements\n", - "Info : Optimizing volume 2\n", - "Info : Optimization starts (volume = 0.000195872) with worst = 0.08867 / average = 0.680311:\n", - "Info : 0.00 < quality < 0.10 : 1 elements\n", - "Info : 0.10 < quality < 0.20 : 2 elements\n", - "Info : 0.20 < quality < 0.30 : 4 elements\n", - "Info : 0.30 < quality < 0.40 : 42 elements\n", - "Info : 0.40 < quality < 0.50 : 28 elements\n", - "Info : 0.50 < quality < 0.60 : 55 elements\n", - "Info : 0.60 < quality < 0.70 : 179 elements\n", - "Info : 0.70 < quality < 0.80 : 322 elements\n", - "Info : 0.80 < quality < 0.90 : 57 elements\n", - "Info : 0.90 < quality < 1.00 : 17 elements\n", - "Info : 3 edge swaps, 0 node relocations (volume = 0.000195872): worst = 0.29686 / average = 0.683139 (Wall 0.000108185s, CPU 0.000151s)\n", - "Info : No ill-shaped tets in the mesh :-)\n", - "Info : 0.00 < quality < 0.10 : 0 elements\n", - "Info : 0.10 < quality < 0.20 : 0 elements\n", - "Info : 0.20 < quality < 0.30 : 4 elements\n", - "Info : 0.30 < quality < 0.40 : 42 elements\n", - "Info : 0.40 < quality < 0.50 : 26 elements\n", - "Info : 0.50 < quality < 0.60 : 56 elements\n", - "Info : 0.60 < quality < 0.70 : 181 elements\n", - "Info : 0.70 < quality < 0.80 : 321 elements\n", - "Info : 0.80 < quality < 0.90 : 57 elements\n", - "Info : 0.90 < quality < 1.00 : 17 elements\n", - "Info : Optimizing volume 3\n", - "Info : Optimization starts (volume = 4.07734e-06) with worst = 0.0172911 / average = 0.830608:\n", - "Info : 0.00 < quality < 0.10 : 3 elements\n", - "Info : 0.10 < quality < 0.20 : 0 elements\n", - "Info : 0.20 < quality < 0.30 : 0 elements\n", - "Info : 0.30 < quality < 0.40 : 0 elements\n", - "Info : 0.40 < quality < 0.50 : 0 elements\n", - "Info : 0.50 < quality < 0.60 : 0 elements\n", - "Info : 0.60 < quality < 0.70 : 0 elements\n", - "Info : 0.70 < quality < 0.80 : 2 elements\n", - "Info : 0.80 < quality < 0.90 : 40 elements\n", - "Info : 0.90 < quality < 1.00 : 16 elements\n", - "Info : 2 edge swaps, 1 node relocations (volume = 4.07734e-06): worst = 0.0258124 / average = 0.809727 (Wall 7.8652e-05s, CPU 7.8e-05s)\n", - "Info : 3 edge swaps, 1 node relocations (volume = 4.07734e-06): worst = 0.213928 / average = 0.808979 (Wall 0.000108591s, CPU 0.000108s)\n", - "Info : No ill-shaped tets in the mesh :-)\n", - "Info : 0.00 < quality < 0.10 : 0 elements\n", - "Info : 0.10 < quality < 0.20 : 0 elements\n", - "Info : 0.20 < quality < 0.30 : 2 elements\n", - "Info : 0.30 < quality < 0.40 : 2 elements\n", - "Info : 0.40 < quality < 0.50 : 4 elements\n", - "Info : 0.50 < quality < 0.60 : 0 elements\n", - "Info : 0.60 < quality < 0.70 : 0 elements\n", - "Info : 0.70 < quality < 0.80 : 0 elements\n", - "Info : 0.80 < quality < 0.90 : 36 elements\n", - "Info : 0.90 < quality < 1.00 : 16 elements\n", - "Info : Optimizing volume 4\n", - "Info : Optimization starts (volume = 4.07734e-06) with worst = 0.0172911 / average = 0.830608:\n", - "Info : 0.00 < quality < 0.10 : 3 elements\n", - "Info : 0.10 < quality < 0.20 : 0 elements\n", - "Info : 0.20 < quality < 0.30 : 0 elements\n", - "Info : 0.30 < quality < 0.40 : 0 elements\n", - "Info : 0.40 < quality < 0.50 : 0 elements\n", - "Info : 0.50 < quality < 0.60 : 0 elements\n", - "Info : 0.60 < quality < 0.70 : 0 elements\n", - "Info : 0.70 < quality < 0.80 : 2 elements\n", - "Info : 0.80 < quality < 0.90 : 40 elements\n", - "Info : 0.90 < quality < 1.00 : 16 elements\n", - "Info : 3 edge swaps, 2 node relocations (volume = 4.07734e-06): worst = 0.21364 / average = 0.808968 (Wall 0.000471611s, CPU 0.000465s)\n", - "Info : No ill-shaped tets in the mesh :-)\n", - "Info : 0.00 < quality < 0.10 : 0 elements\n", - "Info : 0.10 < quality < 0.20 : 0 elements\n", - "Info : 0.20 < quality < 0.30 : 2 elements\n", - "Info : 0.30 < quality < 0.40 : 2 elements\n", - "Info : 0.40 < quality < 0.50 : 4 elements\n", - "Info : 0.50 < quality < 0.60 : 0 elements\n", - "Info : 0.60 < quality < 0.70 : 0 elements\n", - "Info : 0.70 < quality < 0.80 : 0 elements\n", - "Info : 0.80 < quality < 0.90 : 36 elements\n", - "Info : 0.90 < quality < 1.00 : 16 elements\n", - "Info : Done optimizing mesh (Wall 0.00384576s, CPU 0.004583s)\n", - "Info : 591 nodes 2917 elements\n", - "Info : Removing duplicate mesh nodes...\n", - "Info : Found 28 duplicate nodes \n", - "Info : Removed 28 duplicate mesh nodes\n", - "Info : Done removing duplicate mesh nodes\n", - "Info : Writing '/tmp/tmpabrul051/mesh_merged.msh'...\n", - "Info : Done writing '/tmp/tmpabrul051/mesh_merged.msh'\n", - "\n", - "Solving linear variational problem.\n", - "(2, 17, {'ok': False, 'fos': 0.1137652680507679, 'diff': -2.8862347319492323})\n", - "(2, 17, {'ok': False, 'fos': 0.1137652680507679, 'diff': -2.8862347319492323})\n", - "(2, 17, {'ok': False, 'fos': 0.1137652680507679, 'diff': -2.8862347319492323})\n", - "(2, 17, {'ok': False, 'fos': 0.1137652680507679, 'diff': -2.8862347319492323})\n", - "(2, 17, {'ok': False, 'bolt_fos': 2.1834956164436536, 'bolt_diff': -0.8165043835563464, 'plate_fos': 2.125, 'plate_diff': -0.875})\n" - ] - } - ], + "outputs": [], "source": [ "import logging\n", "logging.basicConfig(level=logging.CRITICAL)\n", @@ -431,7 +145,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": null, "id": "b19839ea", "metadata": {}, "outputs": [], @@ -455,35 +169,10 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": null, "id": "4af7b215", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3 15.700000000000012 {'ok': False, 'bolt_fos': 2.7527559285221455, 'bolt_diff': -0.24724407147785454, 'plate_fos': 2.9437500000000023, 'plate_diff': -0.05624999999999769}\n", - "3 15.800000000000011 {'ok': False, 'bolt_fos': 2.7909823520750883, 'bolt_diff': -0.20901764792491173, 'plate_fos': 2.962500000000002, 'plate_diff': -0.03749999999999787}\n", - "3 15.900000000000011 {'ok': False, 'bolt_fos': 2.829900224552613, 'bolt_diff': -0.1700997754473872, 'plate_fos': 2.9812500000000024, 'plate_diff': -0.018749999999997602}\n", - "3 16.00000000000001 {'ok': False, 'bolt_fos': 2.8690875598645036, 'bolt_diff': -0.1309124401354964, 'plate_fos': 3.000000000000002, 'plate_diff': 2.220446049250313e-15}\n", - "3 16.100000000000012 {'ok': True, 'bolt_fos': 2.9085443580107597, 'bolt_diff': -0.09145564198924028, 'plate_fos': 3.018750000000002, 'plate_diff': 0.018750000000002043}\n", - "ANSWER 3 16.100000000000012 {'ok': True, 'bolt_fos': 2.9085443580107597, 'bolt_diff': -0.09145564198924028, 'plate_fos': 3.018750000000002, 'plate_diff': 0.018750000000002043}\n", - "3 16.20000000000001 {'ok': True, 'bolt_fos': 2.9481737740977123, 'bolt_diff': -0.05182622590228769, 'plate_fos': 3.0375000000000023, 'plate_diff': 0.03750000000000231}\n", - "ANSWER 3 16.20000000000001 {'ok': True, 'bolt_fos': 2.9481737740977123, 'bolt_diff': -0.05182622590228769, 'plate_fos': 3.0375000000000023, 'plate_diff': 0.03750000000000231}\n", - "3 16.30000000000001 {'ok': True, 'bolt_fos': 2.98811910721272, 'bolt_diff': -0.011880892787280217, 'plate_fos': 3.056250000000002, 'plate_diff': 0.05625000000000213}\n", - "ANSWER 3 16.30000000000001 {'ok': True, 'bolt_fos': 2.98811910721272, 'bolt_diff': -0.011880892787280217, 'plate_fos': 3.056250000000002, 'plate_diff': 0.05625000000000213}\n", - "3 16.400000000000013 {'ok': True, 'bolt_fos': 3.0283325733774613, 'bolt_diff': 0.028332573377461312, 'plate_fos': 3.075000000000002, 'plate_diff': 0.07500000000000195}\n", - "ANSWER 3 16.400000000000013 {'ok': True, 'bolt_fos': 3.0283325733774613, 'bolt_diff': 0.028332573377461312, 'plate_fos': 3.075000000000002, 'plate_diff': 0.07500000000000195}\n", - "3 16.500000000000014 {'ok': True, 'bolt_fos': 3.068814159381124, 'bolt_diff': 0.06881415938112401, 'plate_fos': 3.0937500000000027, 'plate_diff': 0.09375000000000266}\n", - "ANSWER 3 16.500000000000014 {'ok': True, 'bolt_fos': 3.068814159381124, 'bolt_diff': 0.06881415938112401, 'plate_fos': 3.0937500000000027, 'plate_diff': 0.09375000000000266}\n", - "3 16.600000000000012 {'ok': False, 'bolt_fos': 3.1095638520137596, 'bolt_diff': 0.10956385201375962, 'plate_fos': 3.112500000000002, 'plate_diff': 0.11250000000000204}\n", - "3 16.70000000000001 {'ok': False, 'bolt_fos': 3.1505816380662903, 'bolt_diff': 0.15058163806629032, 'plate_fos': 3.1312500000000023, 'plate_diff': 0.1312500000000023}\n", - "3 16.80000000000001 {'ok': False, 'bolt_fos': 3.1918675043305074, 'bolt_diff': 0.19186750433050737, 'plate_fos': 3.150000000000002, 'plate_diff': 0.15000000000000213}\n", - "3 16.900000000000013 {'ok': False, 'bolt_fos': 3.233421437599064, 'bolt_diff': 0.23342143759906397, 'plate_fos': 3.1687500000000024, 'plate_diff': 0.1687500000000024}\n" - ] - } - ], + "outputs": [], "source": [ "brute_force_search(num_bolts_low=2, num_bolts_high=40, bolt_diameter_low=3.0, bolt_diameter_high=40.0)" ]