public enum ConversationPersistMode
{
DeltaAppend, // Only append new items (default, most efficient)
FullSnapshot, // Replace all items on every update
}
var config = new AgentConfig
{
ConversationStore = ConversationStoreType.None
};
var config = new AgentConfig
{
ConversationStore = ConversationStoreType.LocalFile
};
using Glitch9.AIDevKit.Agents;
using Cysharp.Threading.Tasks;
public class LocalStorageExample
{
async void CreateLocalConversation()
{
var config = new AgentConfig
{
ConversationStore = ConversationStoreType.LocalFile
};
var agent = new Agent(config, settings);
await agent.InitializeAsync();
// Conversation is automatically saved to local file
await agent.SendAsync("Hello!");
// Load conversation in a new session
var conversations = await agent.conversationController.ListConversationsAsync();
if (conversations.Length > 0)
{
await agent.conversationController.LoadConversationAsync(conversations[0].Id);
}
}
}
var config = new AgentConfig
{
ConversationStore = ConversationStoreType.ThreadsApi,
ChatApi = ChatApiType.AssistantsApi // Required
};
using Glitch9.AIDevKit.Agents;
using Cysharp.Threading.Tasks;
public class ThreadsApiExample
{
async void CreateThreadConversation()
{
var config = new AgentConfig
{
ConversationStore = ConversationStoreType.ThreadsApi,
ChatApi = ChatApiType.AssistantsApi
};
var agent = new Agent(config, settings);
await agent.InitializeAsync();
// Creates a new thread on OpenAI
await agent.SendAsync("Hello!");
// Thread is accessible from any device
string threadId = agent.Conversation.Id;
// Later, load the same thread
await agent.conversationController.LoadConversationAsync(threadId);
}
}
var config = new AgentConfig
{
ConversationStore = ConversationStoreType.ConversationsApi,
ChatApi = ChatApiType.ResponsesApi // Required
};
sealed class ConversationsApiStore : IConversationStore
{
public ConversationStoreType StoreType => ConversationStoreType.ConversationsApi;
public ConversationPersistMode PersistMode { get; set; }
public async UniTask<Conversation> CreateAsync(string agentId, CancellationToken ct = default)
{
return await OpenAIClient.DefaultInstance.Conversations.CreateAsync(agentId, ct.ToRequestOptions());
}
public async UniTask<ConversationItem[]> UpdateItemsAsync(string agentId, string convId, ConversationItem[] items, CancellationToken ct = default)
{
if (items.IsNullOrEmpty()) return items;
var response = await OpenAIClient.DefaultInstance.Conversations.CreateItemsAsync(convId, items, ct.ToRequestOptions());
return response?.Data;
}
// ... other methods
}
using Glitch9.AIDevKit.Agents;
using Cysharp.Threading.Tasks;
public class ConversationsApiExample
{
async void CreateConversation()
{
var config = new AgentConfig
{
ConversationStore = ConversationStoreType.ConversationsApi,
ChatApi = ChatApiType.ResponsesApi
};
var agent = new Agent(config, settings);
await agent.InitializeAsync();
// Conversation created via Conversations API
await agent.SendAsync("Hello!");
// Items are persisted incrementally
await agent.SendAsync("How are you?");
// Load items
var items = await agent.conversationController.LoadConversationItemsAsync();
foreach (var item in items)
{
Debug.Log($"{item.Role}: {item.GetText()}");
}
}
}
var config = new AgentConfig
{
ConversationStore = ConversationStoreType.RealtimeApi,
ChatApi = ChatApiType.RealtimeApi // Required
};
using Glitch9.AIDevKit.Conversations;
using Cysharp.Threading.Tasks;
using System.Threading;
public class CloudConversationStore : IConversationStore
{
public ConversationStoreType StoreType => ConversationStoreType.Custom;
public ConversationPersistMode PersistMode { get; set; } = ConversationPersistMode.DeltaAppend;
private readonly ICloudStorageService cloudService;
public CloudConversationStore(ICloudStorageService cloudService)
{
this.cloudService = cloudService;
}
public async UniTask<Conversation> CreateAsync(string agentId, CancellationToken ct = default)
{
var conversation = new Conversation
{
Id = System.Guid.NewGuid().ToString(),
AgentId = agentId,
CreatedAt = System.DateTime.UtcNow
};
await cloudService.SaveAsync($"conversations/{agentId}/{conversation.Id}.json", conversation);
return conversation;
}
public async UniTask<Conversation> LoadAsync(string agentId, string convId, CancellationToken ct = default)
{
return await cloudService.LoadAsync<Conversation>($"conversations/{agentId}/{convId}.json");
}
public async UniTask<Conversation> UpdateAsync(Conversation conversation, CancellationToken ct = default)
{
await cloudService.SaveAsync($"conversations/{conversation.AgentId}/{conversation.Id}.json", conversation);
return conversation;
}
public async UniTask<bool> DeleteAsync(string agentId, string convId, CancellationToken ct = default)
{
return await cloudService.DeleteAsync($"conversations/{agentId}/{convId}.json");
}
public async UniTask<Conversation[]> ListAsync(string agentId, CancellationToken ct = default)
{
return await cloudService.ListAsync<Conversation>($"conversations/{agentId}/");
}
public async UniTask<ConversationItem[]> UpdateItemsAsync(string agentId, string convId, ConversationItem[] items, CancellationToken ct = default)
{
await cloudService.SaveAsync($"conversations/{agentId}/{convId}_items.json", items);
return items;
}
public async UniTask<ConversationItem[]> LoadItemsAsync(string agentId, string convId, CancellationToken ct = default)
{
return await cloudService.LoadAsync<ConversationItem[]>($"conversations/{agentId}/{convId}_items.json");
}
public async UniTask<ConversationItem> LoadItemAsync(string agentId, string convId, string itemId, CancellationToken ct = default)
{
var items = await LoadItemsAsync(agentId, convId, ct);
return items?.FirstOrDefault(i => i.Id == itemId);
}
public async UniTask<bool> DeleteItemAsync(string agentId, string convId, string itemId, CancellationToken ct = default)
{
var items = await LoadItemsAsync(agentId, convId, ct);
if (items == null) return false;
var newItems = items.Where(i => i.Id != itemId).ToArray();
await UpdateItemsAsync(agentId, convId, newItems, ct);
return true;
}
}
var customStore = new CloudConversationStore(myCloudService);
// Option 1: Pass during config creation
var config = new AgentConfig
{
ConversationStore = ConversationStoreType.Custom,
CustomConversationStore = customStore
};
// Option 2: Set on conversation controller
agent.conversationController.SetCustomStore(customStore);
var store = new ConversationsApiStore(ConversationPersistMode.DeltaAppend);
var store = new ConversationsApiStore(ConversationPersistMode.FullSnapshot);
// Choose store based on requirements
var config = new AgentConfig
{
ConversationStore = IsOnline() ? ConversationStoreType.ConversationsApi : ConversationStoreType.LocalFile
};
// Handle store errors gracefully
try
{
await agent.conversationController.LoadConversationAsync(convId);
}
catch (Exception ex)
{
Debug.LogError($"Failed to load conversation: {ex.Message}");
// Fall back to local storage or create new conversation
}
// Dispose agents properly
using (var agent = new Agent(config, settings))
{
// Use agent
}
// Store cleanup happens automatically
// Don't use API stores without internet
var config = new AgentConfig
{
ConversationStore = ConversationStoreType.ConversationsApi // ❌ Requires internet
};
// Don't forget migration when switching stores
// Conversations won't automatically transfer between stores
public async UniTask MigrateConversations(IConversationStore fromStore, IConversationStore toStore, string agentId)
{
// List all conversations
var conversations = await fromStore.ListAsync(agentId);
foreach (var conversation in conversations)
{
// Load items from old store
var items = await fromStore.LoadItemsAsync(agentId, conversation.Id);
// Create in new store
var newConv = await toStore.CreateAsync(agentId);
// Copy metadata
newConv.Title = conversation.Title;
newConv.Summary = conversation.Summary;
newConv.Metadata = conversation.Metadata;
await toStore.UpdateAsync(newConv);
// Copy items
await toStore.UpdateItemsAsync(agentId, newConv.Id, items);
Debug.Log($"Migrated: {conversation.Id} -> {newConv.Id}");
}
}