Issues with cylindrical bending API on CompositesAI

It seems that the json it passes from CompositesAI to the API is incorrect (missing material properties or fiber orientation in the inputs) and doesn’t seem to understand my command. I tested on my own custom GPT on ChatGPT and didn’t encounter the same problem. Is it because the instructions, like schema, is missing on CompositesAI? If so, how to make clear instructions for CompositesAI to better understand user’s instructions?

Refer to one of the chats I did on CompositesAI. The plots are incorrect and it seems it is using incorrect material properties and layup (plots show 2 layers while I have one layer).
:nut_and_bolt: Cylindrical Bending Analysi… | CompositesAI
@banghuazhao

@Haodong @Avinash Have you encountered issues like this?

Are you able to access knowledge->tools? Currently, it seems that tool accessible by @Haodong. He might be able to grant you access so that you can test.

@Haodong I saw that tool is created by you. Is it possible to share that tool with @SichenLiu?

import requests


class Tools:
    def __init__(self):
        self.base_url = (
            "https://composites-ai-tools-api-a88cb33feb62.herokuapp.com/api/v1/"
        )

    def cylindrical_bending_analysis(
        self,
        L: float = 4.0,
        h: float = 1.0,
        q0: float = 1_000_000,
        layer_angles: list = None,
        material_props: dict = None,
        disp_x1: list = None,
        strain_x1: list = None,
        stress_x1: list = None,
        probe_x1: list = None,
        probe_x3: list = None,
        plots: list = None,
    ) -> dict:
        """
        Perform a cylindrical bending laminate analysis and obtain generated figures and numerical probe results.

        :param L: Length of the laminate [default: 4.0]
        :param h: Thickness of the laminate [default: 1.0]
        :param q0: Applied load [default: 1_000_000]
        :param layer_angles: List of angles in degrees for each layer [default: [0, 45]]
        :param material_props: Dictionary of material properties (E1, E2, E3, G12, G13, G23, nu12, nu13, nu23).
                              [default: {E1=1.4e11, E2=E3=1e10, G12=G13=7e9, G23=3.36e9, nu12=0.3, nu13=0.3, nu23=0.49}]
        :param disp_x1: x1 coordinates for displacement plots [default: [0, 0, 2]]
        :param strain_x1: x1 coordinates for strain field plots [default: [2, 2, 0, 0, 2]]
        :param stress_x1: x1 coordinates for stress field plots [default: [2,2,2,0,0,2]]
        :param probe_x1: x1 coordinates for probing (optional)
        :param probe_x3: x3 coordinates for probing (optional)
        :param plots: List of plot types to generate [default: ["2d_combined", "3d"]]
        :return: Dictionary containing URLs for generated figures and any probed results.
        """
        url = self.base_url + "cylindrical-bending-analysis"

        if layer_angles is None:
            layer_angles = [0, 45]
        if material_props is None:
            material_props = {
                "E1": 140_000_000_000,
                "E2": 10_000_000_000,
                "E3": 10_000_000_000,
                "G12": 7_000_000_000,
                "G13": 7_000_000_000,
                "G23": 3_360_000_000,
                "nu12": 0.3,
                "nu13": 0.3,
                "nu23": 0.49,
            }
        if disp_x1 is None:
            disp_x1 = [0, 0, 2]
        if strain_x1 is None:
            strain_x1 = [2, 2, 0, 0, 2]
        if stress_x1 is None:
            stress_x1 = [2, 2, 2, 0, 0, 2]
        if plots is None:
            plots = ["2d_combined", "3d"]

        payload = {
            "L": L,
            "h": h,
            "q0": q0,
            "layer_angles": layer_angles,
            "material_props": material_props,
            "disp_x1": disp_x1,
            "strain_x1": strain_x1,
            "stress_x1": stress_x1,
            "plots": plots,
        }
        if probe_x1 is not None:
            payload["probe_x1"] = probe_x1
        if probe_x3 is not None:
            payload["probe_x3"] = probe_x3

        headers = {"Content-Type": "application/json"}
        response = requests.post(url, json=payload, headers=headers)
        try:
            response.raise_for_status()
            return response.json()
        except Exception as e:
            return {
                "error": str(e),
                "status_code": response.status_code,
                "text": response.text,
            }

There is no way to share access to tools. @SichenLiu

Looking at the code, it seems that compositesAI is using the default material properties and layup angle, and that explains why my prompt says single layer and isotropic material but the results I got are clearly for orthrotropic 2 layers. The API gets [0, 45] and {E1=1.4e11, E2=E3=1e10, G12=G13=7e9, G23=3.36e9, nu12=0.3, nu13=0.3, nu23=0.49} no matter what inputs I have. My guess is that, since the inputs (json) failed to include material properties and layup angles, the code you shared, specifically this:
if layer_angles is None:
layer_angles = [0, 45]
if material_props is None:
material_props = {
“E1”: 140_000_000_000,
“E2”: 10_000_000_000,
“E3”: 10_000_000_000,
“G12”: 7_000_000_000,
“G13”: 7_000_000_000,
“G23”: 3_360_000_000,
“nu12”: 0.3,
“nu13”: 0.3,
“nu23”: 0.49,
}
Assigned the default values because in the inputs they are both “None” (aka they are undefined). That is why I was getting the wrong results. But I think there is nothing wrong with having default values, it is just that we need to always include material properties and layup angles in the inputs so it overrides the default values when they are specified (in other words, material properties and layup angles are not “None”).
Also for probing, it says optional, but when you say you want to get values for a specific point, you need both x1 and x3, not x1, or x3. In other words, both are required when the user asks to probe values. What happened is that it only passes x1 or x3 in my chat which throws an error because the other value is missing.
However, it is hard to teach compositesAI how to prepare the inputs (json) for the API because simple description is not sufficient. For example, the meaning of result type “2d_combined” is not explained in the code, so in my experiments on compositesAI, it just tries to guess what kind of plots I want. “2d_combined” means all displacements (same for strain and stress components) plotted in one single plot, hence why it is called combined. The definition of this string “2d_combined” is defined in my instructions I uploaded to my custom GPT. The instructions also include details of the problem, like how the coordinate is defined etc. Therefore, we need to find a way to add such instructions so compositesAI can pass the correct inputs to the API.
Let me know if there is any way that we can achieve this @Haodong @banghuazhao @Wenbin

At this point, you might want to create your own tool to play with it to see what best it can do without the document.

Hi @SichenLiu , AFAIK there is schema is composites ai tools. You need to change the comments in the tools to fine tune the input and output format.

@banghuazhao the tool seems to be managed by @Haodong , do I need to create my own tool? By “comments” do you mean the descriptions in the code that Haodong shared (e.g., :param L: Length of the laminate [default: 4.0])?

Yes, the schema is represented by the descriptions in the code that Haodong shared (e.g., :param L: Length of the laminate [default: 4.0])

@banghuazhao
I edited the code that @Haodong shared based on my instructions. I deleted the default values because CompositesAI seem to ignore user inputs and only use the default values. Hope this works.

import requests

class Tools:
    def __init__(self):
        self.base_url = (
            "https://composites-ai-tools-api-a88cb33feb62.herokuapp.com/api/v1/"
        )

    def cylindrical_bending_analysis(
        self,
        L: float = None,
        h: float = None,
        q0: float = None,
        layer_angles: list = None,
        material_props: dict = None,
        disp_x1: list = None,
        strain_x1: list = None,
        stress_x1: list = None,
        probe_x1: list = None,
        probe_x3: list = None,
        plots: list = None,
    ) -> dict:
        """
        Perform a cylindrical bending laminate analysis and obtain generated figures and numerical probe results. If required inputs are missing, prompt the user to provide them.

        :param L: Length of the laminate in meters.
                  Example: 4.0

        :param h: Thickness of the laminate in meters.
                  Example: 1.0

        :param q0: Applied transverse load in Pascals.
                   Example: 1_000_000

        :param layer_angles: List of fiber orientation angles (in degrees) from bottom to top for each laminate layer.
                             Example: [0, 45, -45, 90]

        :param material_props: Dictionary of material properties for orthotropic materials. If the input describes an isotropic or transversely isotropic material,
                               the following engineering constants must be automatically computed based on given inputs:
                               - E1, E2, E3: Young’s moduli
                               - G12, G13, G23: Shear moduli
                               - nu12, nu13, nu23: Poisson’s ratios
                               
                               Example:
                               {
                                   "E1": 1.4e11,
                                   "E2": 1e10,
                                   "E3": 1e10,
                                   "G12": 7e9,
                                   "G13": 7e9,
                                   "G23": 3.36e9,
                                   "nu12": 0.3,
                                   "nu13": 0.3,
                                   "nu23": 0.49
                               }

        :param disp_x1: x₁ coordinates for extracting displacement components [U, V, W].
                        Must lie within the laminate: 0 ≤ x₁ ≤ L.
                        Example: [0, 0, 2] means U and V at x₁ = 0; W at x₁ = 2
                        
        :param strain_x1: x₁ coordinates for extracting strain components [ε₁₁, ε₃₃, γ₂₃, γ₁₃, γ₁₂].
                          Must lie within the laminate: 0 ≤ x₁ ≤ L.
                          Example: [2, 2, 0, 0, 2] means ε₁₁, γ₁₂ at x₁ = 2; γ₂₃, γ₁₃ at x₁ = 0; ε₃₃ at x₁ = 2

        :param stress_x1: x₁ coordinates for extracting stress components [σ₁₁, σ₂₂, σ₃₃, σ₂₃, σ₁₃, σ₁₂].
                          Must lie within the laminate length: 0 ≤ x₁ ≤ L.
                          Example: [2, 2, 2, 0, 0, 2] means σ₁₁, σ₂₂, σ₃₃, σ₁₂ at x₁ = 2; σ₂₃, σ₁₃ at x₁ = 0

        :param probe_x1: x₁ coordinate for probing a specific point.
                         Must satisfy: 0 ≤ x₁ ≤ L.
                         Required if "probe" is included in `plots`.
                         Example: 2.0

        :param probe_x3: x₃ coordinate through the laminate thickness for probing.
                         Must satisfy: -h/2 ≤ x₃ ≤ h/2.
                         Required if "probe" is included in `plots`.
                         Example: 0.0

        :param plots: List of plots/numerical values for output. Must choose the option(s) below (do not specify options not listed below in this parameter):
                      - "2d_combined": Generates three 2D plots at the specified x₁. One plot for all displacement components, one for all strain components, and one for all stress components. 
                      The x axis is x₁ and the y axis is displacements/strains/stresses in SI unit.
                      - "2d_standalone": Separate plots for each displacement, strain, and stress component. The x axis is x₁ and the y axis is displacement/strain/stress component in SI unit.
                      - "3d": 3D plots with the x axis being x₁, the y axis being x₃, and the z axis being displacement/strain/stress component in SI unit.
                      - "probe": Get the numerical values of displacements, strains, and stresses at a specific (x₁, x₃) location inside the laminate.
                      Examples: 
                      ["2d_combined", "3d"] means 2D plots where all displacements, strain components, and stress components are plotted together and 3D plots are requested
                      ["2d_standalone", "probe"] means separate 2D plots and values at specific point specified are requested

        :return: Dictionary containing URLs to generated plots and numerical results for probing if specified.
        """

        url = self.base_url + "cylindrical-bending-analysis"

        payload = {
            "L": L,
            "h": h,
            "q0": q0,
            "layer_angles": layer_angles,
            "material_props": material_props,
            "disp_x1": disp_x1,
            "strain_x1": strain_x1,
            "stress_x1": stress_x1,
            "plots": plots,
        }
        if probe_x1 is not None and probe_x3 is not None:
            payload["probe_x1"] = probe_x1
            payload["probe_x3"] = probe_x3

        headers = {"Content-Type": "application/json"}
        response = requests.post(url, json=payload, headers=headers)
        try:
            response.raise_for_status()
            return response.json()
        except Exception as e:
            return {
                "error": str(e),
                "status_code": response.status_code,
                "text": response.text,
            }

@SichenLiu It might be more convenient/straightforward for you to create a tool to test it yourself? I de-selected the tool @Haodong created. You can create a new tool via workspace->tools. Then you can create a new model via workspace->model, select CompositesAI as your base model, and select the tool you just created to test the performance.

@Haodong @banghuazhao
I tested CompositesAI but it seems with the updated description it still cannot get the correct inputs. Specifically material properties and plots (specify what kind of output the user wants) even with detailed instructions.

Do you have any insights what could go wrong?

@SichenLiu please try again. Have you already tested your model in workspace
Cylindrical Bending API
to see whether it works as expected. If yes, we just need to change the access of your tool to be public, and integrate with CompositesAI, the public model. Which I just did.

Yes I was using the tool that I created with updated code, and I tried different instructions that explicitly mentioned in the comments how to write inputs for material properties and plots requested by the user but it seems that CompositesAI still does not follow the instructions. I was wondering what could be wrong with the code.

For others to debug, please show screenshot from ChatGPT and CompositesAI side by side.

OK. I will have a try.

Material properties should be specified in the inputs, which seem to be missing using CompositesAI:
CompositesAI:


ChatGPT:

That’s weird. It could be default values. But it should not be possible they miss the values completely.

It is indeed very strange, but I used the updated code I’ve posted before and the material properties entry is clearly specified. In the chat that I shared, even after I explicitly tell CompositesAI to include material properties, it still fails to include them.
The only way to include all the necessary inputs is when I directly give it the right inputs in the right format, but the user will have no idea how to prepare input files.
I deleted the default values because they keep messing with my new inputs.