Skip to content

UseFunctionCalling extension include whole previous chat history #7406

@msmolka

Description

@msmolka

Currently as far as I'm aware of, I'm not able use function calling with OpenAI responses api.
My issue is I believe, that function calling calls response from tool as single response:

Using functionCalling:

 [
  {
    "role": "system",
    "contents": [
      {
        "$type": "text",
        "text": "You are friendly assistant"
      }
    ]
  },
  {
    "role": "user",
    "contents": [
      {
        "$type": "text",
        "text": "Where is my package PKG00000012"
      }
    ]
  }
].

response contains call to mcp function and the call API:

 [
  {
    "role": "tool",
    "contents": [
      {
        "$type": "functionResult",
        "result": {
          "$type": "text",
          "text": "{\"ok\":true,\"packageid\":\"PKG00000012\",\"status\":\"unknown\",\"message\":\"No tracking data available for this package.\"}"
        },
        "callId": "call_erfK17HEAyoHlboIri5R4l7L"
      }
    ]
  }
]

then server responds with bad gateway exception.

I need to use my custom implementation:

            var response = await _chatClient.GetResponseAsync(input, chatOptions);

            _logger.LogDebug("Hub response: {Text}", response);
            input.AddRange(response.Messages);
            
            var calls = response.Messages
                .SelectMany(m => m.Contents)
                .OfType<FunctionCallContent>()
                .ToList();

            if (calls.Count > 0)
            {
                var results = new List<AIContent>();

                foreach (var call in calls)
                {
                    _logger.LogInformation("Calling tool {Name} with args {Args}", call.Name, call.Arguments);

                    try
                    {
                        // Call MCP tool directly — no broken IChatClient translation involved
                        var mcpArgs = call.Arguments?
                                          .ToDictionary(k => k.Key, v => v.Value)
                                      ?? [];

                        var mcpResult = await _mcpClient!.CallToolAsync(call.Name, mcpArgs);
                        var resultText = mcpResult.Content.FirstOrDefault()?.ToString() ?? "";

                        _logger.LogInformation("Tool {Name} result: {Result}", call.Name, resultText);
                        results.Add(new FunctionResultContent(call.CallId, mcpResult.Content));
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, "Tool {Name} failed", call.Name);
                        results.Add(new FunctionResultContent(call.CallId, $"Error: {ex.Message}"));
                    }
                }

                // Add tool results as a single tool-role message
                input.Add(new ChatMessage(ChatRole.Tool, results));

                return await RunInternalAsync(input, tools);

which produces following input

 [
  {
    "role": "system",
    "contents": [
      {
        "$type": "text",
        "text": "You are friendly assistant "
      }
    ]
  },
  {
    "role": "user",
    "contents": [
      {
        "$type": "text",
        "text": "Where is my package PKG00000012"
      }
    ]
  },
  {
    "createdAt": "2026-03-19T10:06:27+00:00",
    "role": "assistant",
    "contents": [
      {
        "$type": "reasoning",
        "text": "...",
        "protectedData": "..."
      },
      {
        "$type": "functionCall",
        "name": "get_package_status",
        "arguments": {
          "packageId": "PKG00000012"
        },
        "informationalOnly": false,
        "callId": "call_EwvsSSC2mQXbRUTn68OZAGty"
      }
    ]
  },
  {
    "role": "tool",
    "contents": [
      {
        "$type": "functionResult",
        "result": [
          {
            "type": "text",
            "text": "{\"ok\":true,\"packageid\":\"PKG00000012\",\"status\":\"unknown\",\"message\":\"No tracking data available for this package.\"}"
          }
        ],
        "callId": "call_EwvsSSC2mQXbRUTn68OZAGty"
      }
    ]
  }
]

and this one is properly consumed and gives success result:

I checked, package PKG00000012 shows status "unknown" - no tracking data available.

Is there any way to use build-in function calling without custom implementation?

Metadata

Metadata

Assignees

Labels

area-aiMicrosoft.Extensions.AI libraries

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions