ccm commited on
Commit
a7ba1f0
·
1 Parent(s): 7e34bee

Added new beam design agent

Browse files
agent_server/chat_completions.py CHANGED
@@ -21,6 +21,10 @@ from agents.json_tool_calling_agents import (
21
  generate_tool_calling_agent_with_search_and_code,
22
  )
23
 
 
 
 
 
24
  MODEL_NAME = os.getenv("MODEL_NAME", "Qwen/Qwen3-1.7B")
25
 
26
 
@@ -79,6 +83,8 @@ def agent_for_model(model_name: str):
79
  return generate_tool_calling_agent_with_search_and_code()
80
  if model_name == "generator-with-managed-critic":
81
  return generate_generator_with_managed_critic()
 
 
82
  raise ValueError(f"Unknown model id: {model_name}")
83
 
84
 
 
21
  generate_tool_calling_agent_with_search_and_code,
22
  )
23
 
24
+ from agents.agent_with_custom_beam_design_tools import generate_beam_agent
25
+
26
+
27
+ # Model name from env
28
  MODEL_NAME = os.getenv("MODEL_NAME", "Qwen/Qwen3-1.7B")
29
 
30
 
 
83
  return generate_tool_calling_agent_with_search_and_code()
84
  if model_name == "generator-with-managed-critic":
85
  return generate_generator_with_managed_critic()
86
+ if model_name == "custom-agent-with-beam-design-tools":
87
+ return generate_beam_agent()
88
  raise ValueError(f"Unknown model id: {model_name}")
89
 
90
 
agent_server/models.py CHANGED
@@ -12,6 +12,12 @@ def models_payload() -> dict:
12
  return {
13
  "object": "list",
14
  "data": [
 
 
 
 
 
 
15
  {
16
  "id": "generator-with-managed-critic",
17
  "object": "model",
 
12
  return {
13
  "object": "list",
14
  "data": [
15
+ {
16
+ "id": "custom-agent-with-beam-design-tools",
17
+ "object": "model",
18
+ "created": now,
19
+ "owned_by": "you",
20
+ },
21
  {
22
  "id": "generator-with-managed-critic",
23
  "object": "model",
agents/agent_with_custom_beam_design_tools.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ import smolagents
4
+ import smolagents.tools
5
+
6
+ # Rectangular section properties tool
7
+ class RectSectionPropsTool(smolagents.tools.Tool):
8
+ name = "rect_section_props"
9
+ description = (
10
+ "Rectangular section properties."
11
+ )
12
+ inputs = {
13
+ "b": {"type": "number", "description": "Width in meters"},
14
+ "h": {"type": "number", "description": "Height in meters"},
15
+ }
16
+ output_type = "object"
17
+
18
+ def forward(self, b: float, h: float) -> dict:
19
+ if b <= 0 or h <= 0:
20
+ raise ValueError("b and h must be positive.")
21
+ A = b * h
22
+ I = b * (h**3) / 12.0
23
+ S = I / (h / 2.0) # = b*h^2/6
24
+ return {"A": A, "I": I, "S": S}
25
+
26
+ # Circle section properties tool
27
+ class CircleSectionPropsTool(smolagents.tools.Tool):
28
+ name = "circle_section_props"
29
+ description = (
30
+ "Circular section properties."
31
+ )
32
+ inputs = {
33
+ "d": {"type": "number", "description": "Diameter in meters"},
34
+ }
35
+ output_type = "object"
36
+
37
+ def forward(self, d: float) -> dict:
38
+ if d <= 0:
39
+ raise ValueError("d must be positive.")
40
+ A = math.pi * (d**2) / 4.0
41
+ I = math.pi * (d**4) / 64.0
42
+ S = I / (d / 2.0) # = π d^3 / 32
43
+ return {"A": A, "I": I, "S": S}
44
+
45
+
46
+ # Mass tool
47
+ class BeamMassTool(smolagents.tools.Tool):
48
+ name = "beam_mass"
49
+ description = (
50
+ "Beam mass [kg]."
51
+ )
52
+ inputs = {
53
+ "L": {"type": "number", "description": "Length in meters"},
54
+ "rho": {"type": "number", "description": "Material density in kg/m^3"},
55
+ "A": {"type": "number", "description": "Cross-sectional area in m^2 (optional)"},
56
+ }
57
+ output_type = "number"
58
+
59
+ def forward(self, L: float, rho: float, A: float) -> float:
60
+ if L <= 0 or rho <= 0 or A <= 0:
61
+ raise ValueError("L, rho, and A must be positive.")
62
+ return rho * A * L
63
+
64
+ # Deflection tool
65
+ class BeamDeflectionTool(smolagents.tools.Tool):
66
+ name = "beam_deflection"
67
+ description = (
68
+ "Max deflection δ [m] for simple cases."
69
+ )
70
+ inputs = {
71
+ "P": {"type": "number", "description": "Point load in Newtons"},
72
+ "L": {"type": "number", "description": "Span length in meters"},
73
+ "E": {"type": "number", "description": "Young's modulus in Pascals"},
74
+ "I": {"type": "number", "description": "Second moment in m^4 (optional)"},
75
+ "bc": {"type": "string", "description": "Boundary case: 'cantilever_end' or 'ss_center'"},
76
+ }
77
+ output_type = "number"
78
+
79
+ def forward(self, P: float, L: float, E: float, bc: str, I: float) -> float:
80
+ if any(x <= 0 for x in [P, L, E, I]):
81
+ raise ValueError("P, L, E, I must be positive.")
82
+ key = str(bc).lower().strip()
83
+ if key in ["cantilever", "cantilever_end", "cantilver_end", "cantilever-tip", "cantilever_tip"]:
84
+ return P * (L**3) / (3.0 * E * I)
85
+ elif key in ["ss", "ss_center", "simply_supported_center", "simply supported center", "simply_supported"]:
86
+ return P * (L**3) / (48.0 * E * I)
87
+ else:
88
+ raise ValueError("Unsupported bc. Use 'cantilever_end' or 'ss_center'.")
89
+
90
+
91
+
92
+ # Bending stress tool
93
+ class BeamBendingStressTool(smolagents.tools.Tool):
94
+ name = "beam_bending_stress"
95
+ description = (
96
+ "Max bending stress σ_max [Pa]."
97
+ )
98
+ inputs = {
99
+ "M": {"type": "number", "description": "Bending moment in N·m"},
100
+ "I": {"type": "number", "description": "Second moment in m^4 (optional)"},
101
+ "c": {"type": "number", "description": "Neutral axis distance in m (optional)"},
102
+ }
103
+ output_type = "number"
104
+
105
+ def forward(self, M: float, I: float, c: float) -> float:
106
+ if M <= 0:
107
+ raise ValueError("M must be positive.")
108
+ return M *c/I
109
+
110
+ def generate_beam_agent() -> smolagents.CodeAgent:
111
+ # Define the agent with all of these tools.
112
+ return smolagents.CodeAgent(
113
+ tools=[
114
+ BeamMassTool(),
115
+ BeamDeflectionTool(),
116
+ BeamBendingStressTool(),
117
+ RectSectionPropsTool(),
118
+ CircleSectionPropsTool(),
119
+ ],
120
+ model=smolagents.models.OpenAIServerModel(
121
+ model_id=os.getenv("AGENT_MODEL", ""),
122
+ api_base=os.getenv("UPSTREAM_OPENAI_BASE", "").rstrip("/"),
123
+ api_key=os.getenv("OPENAI_API_KEY"),
124
+ ),
125
+ name="BeamAgent",
126
+ add_base_tools=False,
127
+ max_steps=12,
128
+ )
agents/code_writing_agents.py CHANGED
@@ -8,7 +8,7 @@ def generate_code_writing_agent_with_tools(
8
  tools=None, name: str = "code_writing_agent_without_tools"
9
  ):
10
  """
11
- Create a code-writing agent without any extra tools.
12
  """
13
  if tools is None:
14
  tools = []
@@ -37,7 +37,7 @@ def generate_code_writing_agent_without_tools():
37
 
38
  def generate_code_writing_agent_with_search():
39
  """
40
- Create a code-writing agent without any extra tools.
41
  """
42
  tools = [smolagents.WebSearchTool(max_results=5)]
43
  return generate_code_writing_agent_with_tools(
 
8
  tools=None, name: str = "code_writing_agent_without_tools"
9
  ):
10
  """
11
+ Create a code-writing agent wwith a specific set of tools (defaults to none)
12
  """
13
  if tools is None:
14
  tools = []
 
37
 
38
  def generate_code_writing_agent_with_search():
39
  """
40
+ Create a code-writing agent with search tools.
41
  """
42
  tools = [smolagents.WebSearchTool(max_results=5)]
43
  return generate_code_writing_agent_with_tools(
agents/generator_and_critic.py CHANGED
@@ -3,12 +3,13 @@ from __future__ import annotations
3
  import os
4
 
5
  import smolagents.models
6
- from smolagents import CodeAgent, ToolCallingAgent
7
 
8
  # ---------------- Agent Prompts ----------------
9
  GENERATOR_INSTRUCTIONS = """
10
  You are the Generator. Your goal is to produce a concise draft that strictly satisfies the caller's constraints.
11
  Use the managed agent named "critic_agent" to iteratively improve your draft.
 
12
  """
13
 
14
  CRITIC_INSTRUCTIONS = """
 
3
  import os
4
 
5
  import smolagents.models
6
+ from smolagents import ToolCallingAgent
7
 
8
  # ---------------- Agent Prompts ----------------
9
  GENERATOR_INSTRUCTIONS = """
10
  You are the Generator. Your goal is to produce a concise draft that strictly satisfies the caller's constraints.
11
  Use the managed agent named "critic_agent" to iteratively improve your draft.
12
+ When the draft is complete and ready, return it to the user with the final answer tool.
13
  """
14
 
15
  CRITIC_INSTRUCTIONS = """