File size: 4,085 Bytes
a7ba1f0
50178ea
a7ba1f0
 
 
 
50178ea
a7ba1f0
 
 
50178ea
a7ba1f0
 
 
 
 
 
 
 
 
 
 
50178ea
a7ba1f0
 
50178ea
a7ba1f0
 
 
50178ea
a7ba1f0
 
 
 
 
 
 
 
 
 
50178ea
a7ba1f0
 
 
 
 
 
50178ea
a7ba1f0
 
 
50178ea
 
 
 
a7ba1f0
 
 
 
 
 
 
 
50178ea
a7ba1f0
 
 
50178ea
a7ba1f0
 
 
 
 
 
 
 
50178ea
a7ba1f0
 
50178ea
a7ba1f0
 
 
 
 
50178ea
a7ba1f0
 
 
 
 
 
 
 
 
 
50178ea
 
a7ba1f0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50178ea
e9720a2
 
a7ba1f0
 
50178ea
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import os
import math

import smolagents
import smolagents.tools


# Rectangular section properties tool
class RectSectionPropsTool(smolagents.tools.Tool):
    name = "rect_section_props"
    description = "Rectangular section properties."
    inputs = {
        "b": {"type": "number", "description": "Width in meters"},
        "h": {"type": "number", "description": "Height in meters"},
    }
    output_type = "object"

    def forward(self, b: float, h: float) -> dict:
        if b <= 0 or h <= 0:
            raise ValueError("b and h must be positive.")
        A = b * h
        I = b * (h**3) / 12.0
        S = I / (h / 2.0)  # = b*h^2/6
        return {"A": A, "I": I, "S": S}


# Circle section properties tool
class CircleSectionPropsTool(smolagents.tools.Tool):
    name = "circle_section_props"
    description = "Circular section properties."
    inputs = {
        "d": {"type": "number", "description": "Diameter in meters"},
    }
    output_type = "object"

    def forward(self, d: float) -> dict:
        if d <= 0:
            raise ValueError("d must be positive.")
        A = math.pi * (d**2) / 4.0
        I = math.pi * (d**4) / 64.0
        S = I / (d / 2.0)  # = π d^3 / 32
        return {"A": A, "I": I, "S": S}


# Mass tool
class BeamMassTool(smolagents.tools.Tool):
    name = "beam_mass"
    description = "Beam mass [kg]."
    inputs = {
        "L": {"type": "number", "description": "Length in meters"},
        "rho": {"type": "number", "description": "Material density in kg/m^3"},
        "A": {
            "type": "number",
            "description": "Cross-sectional area in m^2 (optional)",
        },
    }
    output_type = "number"

    def forward(self, L: float, rho: float, A: float) -> float:
        if L <= 0 or rho <= 0 or A <= 0:
            raise ValueError("L, rho, and A must be positive.")
        return rho * A * L


# Deflection tool
class BeamDeflectionTool(smolagents.tools.Tool):
    name = "beam_deflection"
    description = "Max deflection δ [m] for simple cases."
    inputs = {
        "P": {"type": "number", "description": "Point load in Newtons"},
        "L": {"type": "number", "description": "Span length in meters"},
        "E": {"type": "number", "description": "Young's modulus in Pascals"},
        "I": {"type": "number", "description": "Second moment in m^4 (optional)"},
    }
    output_type = "number"

    def forward(self, P: float, L: float, E: float, I: float) -> float:
        if any(x <= 0 for x in [P, L, E, I]):
            raise ValueError("P, L, E, I must be positive.")
        return P * (L**3) / (3.0 * E * I)


# Bending stress tool
class BeamBendingStressTool(smolagents.tools.Tool):
    name = "beam_bending_stress"
    description = "Max bending stress σ_max [Pa]."
    inputs = {
        "M": {"type": "number", "description": "Bending moment in N·m"},
        "I": {"type": "number", "description": "Second moment in m^4 (optional)"},
        "c": {"type": "number", "description": "Neutral axis distance in m (optional)"},
    }
    output_type = "number"

    def forward(self, M: float, I: float, c: float) -> float:
        if M <= 0:
            raise ValueError("M must be positive.")
        return M * c / I


def generate_beam_agent() -> smolagents.CodeAgent:
    # Define the agent with all of these tools.
    return smolagents.CodeAgent(
        tools=[
            BeamMassTool(),
            BeamDeflectionTool(),
            BeamBendingStressTool(),
            RectSectionPropsTool(),
            CircleSectionPropsTool(),
        ],
        model=smolagents.models.OpenAIServerModel(
            model_id=os.getenv("AGENT_MODEL", ""),
            api_base=os.getenv("UPSTREAM_OPENAI_BASE", "").rstrip("/"),
            api_key=os.getenv("OPENAI_API_KEY"),
        ),
        instructions="You are a beam design agent with custom tools to support that task. Use those tools whenever feasible.",
        name="beam_design_agent",
        description="Agent specialized in beam design calculations.",
        add_base_tools=False,
        max_steps=12,
    )