Skip to content

Threads ​

Overview ​

Threads represent conversation sessions with assistants in LlmTornado. They maintain message history and context across multiple interactions, making it easy to build stateful conversations. Threads work together with Assistants to provide a complete conversational AI experience.

Quick Start ​

csharp
using LlmTornado;
using LlmTornado.Threads;

TornadoApi api = new TornadoApi("your-api-key");

// Create a thread
HttpCallResult<TornadoThread> thread = await api.Threads.CreateThread();
Console.WriteLine($"Thread ID: {thread.Data.Id}");

// Add a message to the thread
HttpCallResult<AssistantMessage> message = await api.Threads.CreateMessage(
    thread.Data.Id,
    new CreateMessageRequest("Hello, can you help me?"));

Console.WriteLine($"Message added: {message.Data.Id}");

Prerequisites ​

  • The LlmTornado package installed
  • A valid API key with threads access
  • Understanding of Assistants
  • Familiarity with conversation patterns

Basic Usage ​

Create a Thread ​

csharp
HttpCallResult<TornadoThread> thread = await api.Threads.CreateThread();
Console.WriteLine($"Created thread: {thread.Data.Id}");

Create Thread with Initial Messages ​

csharp
HttpCallResult<TornadoThread> thread = await api.Threads.CreateThread(
    new CreateThreadRequest
    {
        Messages = new List<CreateMessageRequest>
        {
            new CreateMessageRequest("Hello!"),
            new CreateMessageRequest("I need help with programming.")
        }
    });

Retrieve a Thread ​

csharp
HttpCallResult<TornadoThread> thread = await api.Threads.RetrieveThread("thread_id");
Console.WriteLine($"Thread metadata: {thread.Data.Metadata}");

Modify a Thread ​

csharp
HttpCallResult<TornadoThread> updated = await api.Threads.ModifyThread(
    "thread_id",
    new ModifyThreadRequest
    {
        Metadata = new Dictionary<string, string>
        {
            {"user_id", "12345"},
            {"session", "active"}
        }
    });

Delete a Thread ​

csharp
HttpCallResult<bool> deleted = await api.Threads.DeleteThread("thread_id");
Console.WriteLine($"Thread deleted: {deleted.Data}");

Working with Messages ​

Add a Message ​

csharp
HttpCallResult<AssistantMessage> message = await api.Threads.CreateMessage(
    "thread_id",
    new CreateMessageRequest("What is the weather today?"));

List Messages ​

csharp
HttpCallResult<ListResponse<AssistantMessage>> messages = 
    await api.Threads.ListMessages("thread_id");

foreach (AssistantMessage message in messages.Data.Items)
{
    Console.WriteLine($"{message.Role}: {message.Content}");
}

Retrieve a Specific Message ​

csharp
HttpCallResult<AssistantMessage> message = 
    await api.Threads.RetrieveMessage("thread_id", "message_id");

Console.WriteLine($"Content: {message.Data.Content}");

Modify a Message ​

csharp
HttpCallResult<AssistantMessage> updated = await api.Threads.ModifyMessage(
    "thread_id",
    "message_id",
    new ModifyMessageRequest
    {
        Metadata = new Dictionary<string, string>
        {
            {"edited", "true"}
        }
    });

Delete a Message ​

csharp
HttpCallResult<bool> deleted = await api.Threads.DeleteMessage(
    "thread_id", 
    "message_id");

Running Assistants on Threads ​

Create and Run ​

csharp
// Create a run to get assistant response
HttpCallResult<TornadoRun> run = await api.Threads.CreateRun(
    "thread_id",
    new CreateRunRequest("assistant_id")
    {
        Model = ChatModel.OpenAi.Gpt4.O241120,
        Instructions = "You are a helpful assistant."
    });

// Wait for completion
while (run.Data.Status == "queued" || run.Data.Status == "in_progress")
{
    await Task.Delay(1000);
    run = await api.Threads.RetrieveRun("thread_id", run.Data.Id);
}

// Get the assistant's response
HttpCallResult<ListResponse<AssistantMessage>> messages = 
    await api.Threads.ListMessages("thread_id");

Stream Run Results ​

csharp
await api.Threads.StreamRun(
    "thread_id",
    new CreateRunRequest("assistant_id"),
    async (chunk) =>
    {
        Console.Write(chunk);
    });

Advanced Usage ​

Complete Conversation Flow ​

csharp
// 1. Create thread
HttpCallResult<TornadoThread> thread = await api.Threads.CreateThread();

// 2. Add user message
await api.Threads.CreateMessage(
    thread.Data.Id,
    new CreateMessageRequest("Explain quantum computing"));

// 3. Run assistant
HttpCallResult<TornadoRun> run = await api.Threads.CreateRun(
    thread.Data.Id,
    new CreateRunRequest("assistant_id"));

// 4. Wait for completion
while (run.Data.Status == "in_progress")
{
    await Task.Delay(1000);
    run = await api.Threads.RetrieveRun(thread.Data.Id, run.Data.Id);
}

// 5. Get response
HttpCallResult<ListResponse<AssistantMessage>> messages = 
    await api.Threads.ListMessages(thread.Data.Id);

AssistantMessage lastMessage = messages.Data.Items.First();
Console.WriteLine($"Assistant: {lastMessage.Content}");

Multi-Turn Conversation ​

csharp
string threadId = (await api.Threads.CreateThread()).Data.Id;
string assistantId = "your_assistant_id";

async Task<string> SendMessage(string text)
{
    // Add user message
    await api.Threads.CreateMessage(
        threadId,
        new CreateMessageRequest(text));
    
    // Run assistant
    HttpCallResult<TornadoRun> run = await api.Threads.CreateRun(
        threadId,
        new CreateRunRequest(assistantId));
    
    // Wait for completion
    while (run.Data.Status == "in_progress")
    {
        await Task.Delay(1000);
        run = await api.Threads.RetrieveRun(threadId, run.Data.Id);
    }
    
    // Get latest message
    HttpCallResult<ListResponse<AssistantMessage>> messages = 
        await api.Threads.ListMessages(threadId);
    
    return messages.Data.Items.First().Content;
}

// Have a conversation
string response1 = await SendMessage("What is machine learning?");
Console.WriteLine($"AI: {response1}");

string response2 = await SendMessage("Can you give me an example?");
Console.WriteLine($"AI: {response2}");

Best Practices ​

  1. Thread Lifecycle - Clean up old threads regularly
  2. Metadata Usage - Tag threads with user/session info
  3. Error Handling - Handle run failures gracefully
  4. Pagination - Use pagination for long message histories
  5. Rate Limiting - Respect API rate limits

Common Issues ​

Run Stuck in Progress ​

  • Solution: Implement timeout and retry logic
  • Prevention: Monitor run status and set reasonable timeouts

Messages Out of Order ​

  • Solution: Use message timestamps to sort
  • Prevention: Always fetch latest messages after runs

Thread Context Lost ​

  • Solution: Retrieve thread before continuing conversation
  • Prevention: Store thread IDs persistently

API Reference ​

TornadoThread ​

  • string Id - Thread identifier
  • Dictionary<string, string> Metadata - Custom metadata
  • long CreatedAt - Creation timestamp

AssistantMessage ​

  • string Id - Message identifier
  • string ThreadId - Parent thread
  • string Role - Message role (user/assistant)
  • string Content - Message content
  • List<Attachment> Attachments - File attachments

CreateRunRequest ​

  • string AssistantId - Assistant to use
  • ChatModel Model - Optional model override
  • string Instructions - Optional instruction override
  • List<AssistantTool> Tools - Optional tool override