lmstudio-ai / lmstudio-bug-tracker

Bug tracking for the LM Studio desktop application
10 stars 3 forks source link

calling function doesn't work with nemo #139

Open AlainAsist opened 1 month ago

AlainAsist commented 1 month ago

i use this model: bartowski/Mistral-Nemo-Instruct-2407-GGUF

lmstudio Version 0.3.3 (Build 1)

i apply the jinja template:

{%- if messages[0]["role"] == "system" %}
{%- set system_message = messages[0]["content"] %}
{%- set loop_messages = messages[1:] %}
{%- else %}
    {%- set loop_messages = messages %}
{%- endif %}
{%- if not tools is defined %}
    {%- set tools = none %}
{%- endif %}
{%- set user_messages = loop_messages | selectattr("role", "equalto", "user") | list %}
{#- This block checks for alternating user/assistant messages, skipping tool calling messages #}
{%- set ns = namespace() %}
{%- set ns.index = 0 %}
{%- for message in loop_messages %}
    {%- if not (message.role == "tool" or message.role == "tool_results" or (message.tool_calls is defined and message.tool_calls is not none)) %}
        {%- if (message["role"] == "user") != (ns.index % 2 == 0) %}
            {{- raise_exception("After the optional system message, conversation roles must alternate user/assistant/user/assistant/...") }}
        {%- endif %}
        {%- set ns.index = ns.index + 1 %}
    {%- endif %}
{%- endfor %}
{{- bos_token }}
{%- for message in loop_messages %}
    {%- if message["role"] == "user" %}
        {%- if tools is not none and (message == user_messages[-1]) %}
            {{- "[AVAILABLE_TOOLS][" }}
            {%- for tool in tools %}
                {%- set tool = tool.function %}
                {{- '{"type": "function", "function": {' }}
                {%- for key, val in tool.items() if key != "return" %}
                    {%- if val is string %}
                        {{- '"' + key + '": "' + val + '"' }}
                    {%- else %}
                        {{- '"' + key + '": ' + val|tojson }}
                    {%- endif %}
                    {%- if not loop.last %}
                        {{- ", " }}
                    {%- endif %}
                {%- endfor %}
                {{- "}}" }}
                {%- if not loop.last %}
                    {{- ", " }}
                {%- else %}
                    {{- "]" }}
                {%- endif %}
            {%- endfor %}
            {{- "[/AVAILABLE_TOOLS]" }}
            {%- endif %}
        {%- if loop.last and system_message is defined %}
            {{- "[INST]" + system_message + "\n\n" + message["content"] + "[/INST]" }}
        {%- else %}
            {{- "[INST]" + message["content"] + "[/INST]" }}
        {%- endif %}
    {%- elif (message.tool_calls is defined and message.tool_calls is not none) %}
        {{- "[TOOL_CALLS][" }}
        {%- for tool_call in message.tool_calls %}
            {%- set out = tool_call.function|tojson %}
            {{- out[:-1] }}
            {%- if not tool_call.id is defined or tool_call.id|length != 9 %}
                {{- raise_exception("Tool call IDs should be alphanumeric strings with length 9!") }}
            {%- endif %}
            {{- ', "id": "' + tool_call.id + '"}' }}
            {%- if not loop.last %}
                {{- ", " }}
            {%- else %}
                {{- "]" + eos_token }}
            {%- endif %}
        {%- endfor %}
    {%- elif message["role"] == "assistant" %}
        {{- message["content"] + eos_token}}
    {%- elif message["role"] == "tool_results" or message["role"] == "tool" %}
        {%- if message.content is defined and message.content.content is defined %}
            {%- set content = message.content.content %}
        {%- else %}
            {%- set content = message.content %}
        {%- endif %}
        {{- '[TOOL_RESULTS]{"content": ' + content|string + ", " }}
        {%- if not message.tool_call_id is defined or message.tool_call_id|length != 9 %}
            {{- raise_exception("Tool call IDs should be alphanumeric strings with length 9!") }}
        {%- endif %}
        {{- '"call_id": "' + message.tool_call_id + '"}[/TOOL_RESULTS]' }}
    {%- else %}
        {{- raise_exception("Only user and assistant roles are supported, with the exception of an initial optional system message!") }}
    {%- endif %}
{%- endfor %}

The parsing is OK

i post this message:

  Received POST request to /v1/chat/completions with body: {
    "messages": [
      {
        "content": "\nYou are an intelligent assistant specialized in retrieving and analyzing metrics for the spaces the client has access to. Use the available functions and tools to identify relevant metrics (environmental statistics, occupancy, etc.) that the client can obtain. When necessary, call the appropriate functions to perform calculations, retrieve data, or generate detailed reports on the relevant spaces. Ensure that you provide accurate, contextualized, and actionable responses.\n\n\nCurrent user:\n<User>\n{'possible_namespaces': ['workcafe', 'openSpace', 'mediumOffice', 'infraSystem_etage1']}\n</User>\n\nCurrent time: 2024-10-04 10:00:56.273088.\n                ",
        "role": "system"
      },
      {
        "content": "donnes moi la liste des espaces auquel j'ai droit",
        "role": "user"
      },
      {
        "content": "Bien sûr, voici la liste des espaces auxquels vous avez accès :\n\n* workcafe\n* openSpace\n* mediumOffice\n* infraSystem_etage1",
        "role": "assistant"
      },
      {
        "content": "donnes moi la liste des espaces auquel j'ai droit",
        "role": "user"
      },
      {
        "content": "Bien sûr, voici la liste des espaces auxquels vous avez accès :\n\n* workcafe\n* openSpace\n* mediumOffice\n* infraSystem_etage1",
        "role": "assistant"
      },
      {
        "content": "quelles sont les statistiques dans l'espace workcafe du 01/07/2024 au 02/07/2024",
        "role": "user"
      }
    ],
    "model": "gpt-3.5-turbo",
    "n": 1,
    "stream": false,
    "temperature": 0.7,
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "tavily_search_results_json",
          "description": "A search engine optimized for comprehensive, accurate, and trusted results. Useful for when you need to answer questions about current events. Input should be a search query.",
          "parameters": {
            "properties": {
              "query": {
                "description": "search query to look up",
                "type": "string"
              }
            },
            "required": [
              "query"
            ],
            "type": "object"
          }
        }
      },
      {
        "type": "function",
        "function": {
          "name": "fetch_metrics_list_for_namespace",
          "description": "retreived an available metrics list for a namespace\n\nArgs:\n    namespace (str): a namespace.\n    values_number (int): number of records to extract . Defaults to 20.\n\n\nReturns:\n    list[str]: A list of metrics names.",
          "parameters": {
            "properties": {
              "namespace": {
                "type": "string"
              },
              "values_number": {
                "default": 20,
                "type": "integer"
              }
            },
            "required": [
              "namespace"
            ],
            "type": "object"
          }
        }
      },
      {
        "type": "function",
        "function": {
          "name": "fetch_statistics_for_metrics_for_namespace",
          "description": "get the statistics about metrics from a namespace for a date range.\n    the statistics are min, max, mean and count values for each metric.\n\nArgs:\n    namespace (str): a namespace.\n    end_date (datetime): start of the date range. example: \"2024-07-01T00:00:00Z\".\n    start_date (datetime):  end of the date range. example: \"2024-07-02T00:00:00Z\".\n\nReturns:\n    dict: A dictionary of statistics values by metric.",
          "parameters": {
            "properties": {
              "namespace": {
                "type": "string"
              },
              "start_date": {
                "format": "date-time",
                "type": "string"
              },
              "end_date": {
                "format": "date-time",
                "type": "string"
              }
            },
            "required": [
              "namespace",
              "start_date",
              "end_date"
            ],
            "type": "object"
          }
        }
      }
    ]
  }

The model can't ffound the function and the answer is bad.

The answer with ollama is correct! What is bad with lmstudio?

yagil commented 1 week ago

We're about to start a beta for this. If you're interested, please fill out this google form: https://docs.google.com/forms/d/e/1FAIpQLSfqpRunKgv2ui4_CWyeQ88gFtOG6CEqFSbpRrHWgJjs2mIodw/viewform?usp=sf_link