.NET: Change thread_id from entity ID to GUID (#2260)

This commit is contained in:
Chris Gillum
2025-11-17 11:30:45 -08:00
committed by GitHub
Unverified
parent e413c5a285
commit 77247a304e
5 changed files with 39 additions and 18 deletions
@@ -47,7 +47,7 @@ curl -X POST http://localhost:7071/api/agents/Joker/run \
To continue a conversation, include the `thread_id` in the query string or JSON body:
```bash
curl -X POST "http://localhost:7071/api/agents/Joker/run?thread_id=@dafx-joker@your-thread-id" \
curl -X POST "http://localhost:7071/api/agents/Joker/run?thread_id=your-thread-id" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"message": "Tell me another one."}'
@@ -64,7 +64,7 @@ The expected `application/json` output will look something like:
```json
{
"status": 200,
"thread_id": "@dafx-joker@your-thread-id",
"thread_id": "ee6e47a0-f24b-40b1-ade8-16fcebb9eb40",
"response": {
"Messages": [
{
@@ -52,7 +52,7 @@ The response will be a text string that looks something like the following, indi
```http
HTTP/1.1 200 OK
Content-Type: text/plain
x-ms-thread-id: @publisher@351ec855-7f4d-4527-a60d-498301ced36d
x-ms-thread-id: 351ec855-7f4d-4527-a60d-498301ced36d
```
@@ -83,12 +83,13 @@ internal static class BuiltInFunctions
string? threadIdValue = threadIdFromBody ?? threadIdFromQuery;
// If no session ID is provided, use a new one based on the function name and invocation ID.
// This may be better than a random one because it can be correlated with the function invocation.
// Specifying a session ID is how the caller correlates multiple calls to the same agent session.
// The thread_id is treated as a session key (not a full session ID).
// If no session key is provided, use the function invocation ID as the session key
// to help correlate the session with the function invocation.
string agentName = GetAgentName(context);
AgentSessionId sessionId = string.IsNullOrEmpty(threadIdValue)
? new AgentSessionId(GetAgentName(context), context.InvocationId)
: AgentSessionId.Parse(threadIdValue);
? new AgentSessionId(agentName, context.InvocationId)
: new AgentSessionId(agentName, threadIdValue);
if (string.IsNullOrWhiteSpace(message))
{
@@ -110,7 +111,7 @@ internal static class BuiltInFunctions
}
}
AIAgent agentProxy = client.AsDurableAgentProxy(context, GetAgentName(context));
AIAgent agentProxy = client.AsDurableAgentProxy(context, agentName);
DurableAgentRunOptions options = new() { IsFireAndForget = !waitForResponse };
@@ -126,7 +127,7 @@ internal static class BuiltInFunctions
req,
context,
HttpStatusCode.OK,
sessionId.ToString(),
sessionId.Key,
agentResponse);
}
@@ -140,7 +141,7 @@ internal static class BuiltInFunctions
return await CreateAcceptedResponseAsync(
req,
context,
sessionId.ToString());
sessionId.Key);
}
public static async Task<string?> RunMcpToolAsync(
@@ -75,9 +75,9 @@ public sealed class SamplesValidation(ITestOutputHelper outputHelper) : IAsyncLi
// The response headers should include the agent thread ID, which can be used to continue the conversation.
string? threadId = response.Headers.GetValues("x-ms-thread-id")?.FirstOrDefault();
Assert.NotNull(threadId);
Assert.NotEmpty(threadId);
this._outputHelper.WriteLine($"Agent thread ID: {threadId}");
Assert.StartsWith("@dafx-joker@", threadId);
// Wait for up to 30 seconds to see if the agent response is available in the logs
await this.WaitForConditionAsync(
@@ -289,7 +289,7 @@ public sealed class SamplesValidation(ITestOutputHelper outputHelper) : IAsyncLi
startResponse.Headers.TryGetValues("x-ms-thread-id", out IEnumerable<string>? agentIdValues);
string? threadId = agentIdValues?.FirstOrDefault();
Assert.NotNull(threadId);
Assert.StartsWith("@dafx-publisher@", threadId);
Assert.NotEmpty(threadId);
// Wait for the orchestration to report that it's waiting for human approval
await this.WaitForConditionAsync(
@@ -18,20 +18,40 @@ Follow the common setup steps in `../README.md` to install tooling, configure Az
Send a prompt to the Joker agent:
Bash (Linux/macOS/WSL):
```bash
curl -X POST http://localhost:7071/api/agents/Joker/run \
-H "Content-Type: text/plain" \
curl -i -X POST http://localhost:7071/api/agents/Joker/run \
-d "Tell me a short joke about cloud computing."
```
PowerShell:
```powershell
Invoke-RestMethod -Method Post -Uri http://localhost:7071/api/agents/Joker/run `
-Body "Tell me a short joke about cloud computing."
```
The agent responds with a JSON payload that includes the generated joke.
> **Note:** To return immediately with an HTTP 202 response instead of waiting for the agent output, set the `x-ms-wait-for-response` header or include `"wait_for_response": false` in the request body. The default behavior waits for the response.
> [!TIP]
> To return immediately with an HTTP 202 response instead of waiting for the agent output, set the `x-ms-wait-for-response` header or include `"wait_for_response": false` in the request body. The default behavior waits for the response.
## Expected Output
When you send a POST request with plain-text input, the Functions host responds with an HTTP 202 and queues the request for the durable agent entity. A typical response body looks like the following:
Expected HTTP 202 payload:
The default plain-text response looks like the following:
```http
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
x-ms-thread-id: 4f205157170244bfbd80209df383757e
```
When you specify the `x-ms-wait-for-response` header or include `"wait_for_response": false` in the request body, the Functions host responds with an HTTP 202 and queues the request to run in the background. A typical response body looks like the following:
```json
{
"status": "accepted",
"response": "Agent request accepted",
"message": "Tell me a short joke about cloud computing.",