Skip to content

Conversation

DeagleGross
Copy link
Contributor

[heavy wip]

@DeagleGross DeagleGross self-assigned this Oct 10, 2025
@ReubenBond ReubenBond requested a review from Copilot October 13, 2025 16:22
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces an API for managing agent threads in hosting scenarios, enabling persistent storage and retrieval of conversation threads across HTTP requests and application restarts.

  • Introduces the IAgentThreadStore interface for persistent thread storage
  • Provides NoContextAgentThreadStore (no-op) and InMemoryAgentThreadStore implementations
  • Adds AIHostAgent wrapper that combines agents with thread persistence capabilities

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
IAgentThreadStore.cs Defines the interface contract for thread storage operations
NoContextAgentThreadStore.cs Provides a no-op implementation that returns null threads
InMemoryAgentThreadStore.cs Implements in-memory thread storage using ConcurrentDictionary
AIHostAgent.cs Wraps AIAgent with thread persistence capabilities
HostAgentBuilderExtensions.cs Extension methods for configuring thread stores with agents
AIAgentExtensions.cs Updates A2A messaging to support thread persistence
WebApplicationExtensions.cs Updates ASP.NET Core integration to use thread stores
Program.cs Sample showing in-memory thread store configuration

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

public ValueTask<JsonElement?> GetOrCreateThreadAsync(string conversationId, string agentId, CancellationToken cancellationToken = default)
{
// this is OK, Agents should be prepared to handle null threads.
return new ValueTask<JsonElement?>(result: null!);
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The null-forgiving operator ! is unnecessary here since null is already being explicitly passed. This should be return new ValueTask<JsonElement?>(result: null);

Suggested change
return new ValueTask<JsonElement?>(result: null!);
return new ValueTask<JsonElement?>(result: null);

Copilot uses AI. Check for mistakes.

CancellationToken cancellationToken = default)
{
var key = GetKey(conversationId, agentId);
var threadContent = this._threads.GetOrAdd(key, value: JsonDocument.Parse("{}").RootElement);
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating a new JsonDocument on every call to GetOrAdd is inefficient. Consider creating a static readonly instance of the empty JSON element to reuse across all calls.

Copilot uses AI. Check for mistakes.

var contextId = messageSendParams.Message.ContextId ?? Guid.NewGuid().ToString("N");
var parts = response.Messages.ToParts();

await hostAgent.SaveThreadAsync(contextId, thread!, cancellationToken).ConfigureAwait(false);
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The null-forgiving operator ! is used on thread but thread can be null from RestoreThreadAsync. This could cause a NullReferenceException. Check if thread is null before saving or handle the null case appropriately.

Suggested change
await hostAgent.SaveThreadAsync(contextId, thread!, cancellationToken).ConfigureAwait(false);
if (thread == null)
{
throw new InvalidOperationException("Failed to restore thread: thread is null.");
}
await hostAgent.SaveThreadAsync(contextId, thread, cancellationToken).ConfigureAwait(false);

Copilot uses AI. Check for mistakes.

@crickman crickman deleted the branch dmkorolev/workflow-extensions October 14, 2025 20:22
@crickman crickman closed this Oct 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants