Skip to content

Chat API ​

AI conversation with streaming responses and agentic tool calling.

Endpoints ​

MethodEndpointDescription
GET/api/agents/{id}/chatGet message history
POST/api/agents/{id}/chatSend message
DELETE/api/agents/{id}/chatClear all history
GET/api/agents/{id}/chat/modelsList available models
GET/api/agents/{id}/chat/toolsList available tools
GET/api/agents/{id}/chat/conversationsList conversations
POST/api/agents/{id}/chat/conversationsCreate conversation
DELETE/api/agents/{id}/chat/conversations/{conversationId}Delete conversation
DELETE/api/agents/{id}/chat/messages/{messageId}Delete message
POST/api/agents/{id}/chat/messages/{messageId}/regenerateRegenerate response
GET/api/agents/{id}/tasks?conversationId=&includeClosed=1Open tasks of a conversation — see Tasks
PATCH/api/agents/{id}/tasks/{taskId}Change a task's status ({ status, note? })
GET/api/agents/{id}/jev-decisions?kind=&limit=Typed-decision log — see Diagnostics

Send Message ​

bash
POST /api/agents/{id}/chat
Content-Type: application/json

Request Body ​

json
{
  "content": "What's the weather like?",
  "conversationId": "conv-123",
  "model": "llama-4-scout",
  "enableTools": true,
  "autoRag": true,
  "stream": false
}

Request Parameters ​

ParameterTypeRequiredDescription
contentstringYesThe message content
conversationIdstringNoContinue existing conversation
modelstringNoModel to use (defaults to agent setting)
enableToolsbooleanNoEnable tool calling (default: true)
autoRagbooleanNoEnable automatic RAG context (default: true)
streambooleanNoEnable streaming response (default: false)

Non-Streaming Response ​

json
{
  "userMessage": {
    "id": "msg_abc123",
    "role": "user",
    "content": "What's the weather like?",
    "conversationId": "conv-123",
    "createdAt": "2024-12-15T10:00:00Z"
  },
  "assistantMessage": {
    "id": "msg_def456",
    "role": "assistant",
    "content": "I don't have access to real-time weather data...",
    "conversationId": "conv-123",
    "toolCalls": null,
    "toolResults": null,
    "metadata": {
      "model": "llama-4-scout"
    },
    "createdAt": "2024-12-15T10:00:01Z"
  }
}

With Tool Calls ​

json
{
  "userMessage": { ... },
  "assistantMessage": {
    "id": "msg_def456",
    "role": "assistant",
    "content": "The weather in Tokyo is currently 22°C and sunny.",
    "toolCalls": [
      {
        "id": "tc_abc123",
        "name": "get_weather",
        "arguments": {"location": "Tokyo"}
      }
    ],
    "toolResults": [
      {
        "toolCallId": "tc_abc123",
        "name": "get_weather",
        "result": {"temperature": 22, "condition": "sunny"}
      }
    ]
  }
}

Streaming Response ​

For real-time streaming, set stream: true:

bash
POST /api/agents/{id}/chat
Content-Type: application/json

{
  "content": "Tell me a story",
  "stream": true
}

SSE Event Types ​

The streaming response uses Server-Sent Events with the following event types:

message_start ​

Sent when streaming begins.

event: message
data: {"type": "message_start", "userMessageId": "msg_abc123", "model": "llama-4-scout"}

thinking ​

Sent when the model is processing (for each agentic loop iteration).

event: message
data: {"type": "thinking", "iteration": 1}

tool_call ​

Sent when a tool is being called.

event: message
data: {"type": "tool_call", "id": "tc_abc123", "name": "search_knowledge", "arguments": {"query": "React tutorials"}}

tool_result ​

Sent when a tool execution completes.

event: message
data: {"type": "tool_result", "toolCallId": "tc_abc123", "name": "search_knowledge", "success": true, "result": [...], "resultPreview": "Found 5 results..."}

For errors:

event: message
data: {"type": "tool_result", "toolCallId": "tc_abc123", "name": "search_knowledge", "success": false, "error": "Search failed"}

content_delta ​

Sent for each chunk of the response text.

event: message
data: {"type": "content_delta", "delta": "Once upon a time", "index": 0}

message_complete ​

Sent when streaming finishes.

event: message
data: {"type": "message_complete", "assistantMessageId": "msg_def456", "toolCalls": [...], "toolResults": [...]}

error ​

Sent if an error occurs.

event: message
data: {"type": "error", "message": "Model request failed"}

Streaming Example ​

javascript
const response = await fetch('/api/agents/{id}/chat', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    content: 'Tell me a story',
    stream: true
  })
})

const reader = response.body.getReader()
const decoder = new TextDecoder()
let buffer = ''

while (true) {
  const { done, value } = await reader.read()
  if (done) break

  buffer += decoder.decode(value, { stream: true })
  const lines = buffer.split('\n')
  buffer = lines.pop() // Keep incomplete line in buffer

  for (const line of lines) {
    if (line.startsWith('data: ')) {
      const data = JSON.parse(line.slice(6))

      switch (data.type) {
        case 'message_start':
          console.log('Started:', data.model)
          break
        case 'thinking':
          console.log('Thinking... iteration', data.iteration)
          break
        case 'tool_call':
          console.log(`Calling: ${data.name}`)
          break
        case 'tool_result':
          if (data.success) {
            console.log(`Result: ${data.resultPreview}`)
          } else {
            console.log(`Error: ${data.error}`)
          }
          break
        case 'content_delta':
          process.stdout.write(data.delta)
          break
        case 'message_complete':
          console.log('\nDone!')
          break
        case 'error':
          console.error('Error:', data.message)
          break
      }
    }
  }
}

Aborting Streams ​

Use AbortController to cancel streaming:

javascript
const controller = new AbortController()

const response = await fetch('/api/agents/{id}/chat', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ content: 'Tell me a story', stream: true }),
  signal: controller.signal
})

// Later, to abort:
controller.abort()

Get Messages ​

bash
GET /api/agents/{id}/chat?limit=50&conversationId=conv-123

Query Parameters ​

ParameterTypeDescription
limitnumberMax messages (default: 50)
conversationIdstringFilter by conversation
beforestringMessages before ID
afterstringMessages after ID

Response ​

json
{
  "messages": [
    {
      "id": "msg_abc123",
      "role": "user",
      "content": "Hello!",
      "conversationId": "conv-123",
      "createdAt": "2024-12-15T10:00:00Z"
    },
    {
      "id": "msg_def456",
      "role": "assistant",
      "content": "Hi there! How can I help you?",
      "conversationId": "conv-123",
      "toolCalls": null,
      "toolResults": null,
      "metadata": {
        "model": "llama-4-scout"
      },
      "createdAt": "2024-12-15T10:00:01Z"
    }
  ],
  "meta": {
    "total": 100,
    "hasMore": true
  }
}

Clear History ​

bash
DELETE /api/agents/{id}/chat

Query Parameters ​

ParameterTypeDescription
conversationIdstringClear specific conversation only

Response ​

json
{
  "success": true,
  "deleted": 150
}

List Available Models ​

bash
GET /api/agents/{id}/chat/models

Response ​

json
{
  "models": [
    {
      "id": "llama-4-scout",
      "name": "Llama 4 Scout",
      "provider": "workers-ai",
      "contextWindow": 131072,
      "supportsTools": true,
      "supportsStreaming": true
    },
    {
      "id": "gpt-4o",
      "name": "GPT-4o",
      "provider": "openai",
      "contextWindow": 128000,
      "supportsTools": true,
      "supportsStreaming": true
    },
    {
      "id": "claude-opus-4-5",
      "name": "Claude Opus 4.5",
      "provider": "anthropic",
      "contextWindow": 200000,
      "supportsTools": true,
      "supportsStreaming": true
    },
    {
      "id": "gemini-2.5-flash",
      "name": "Gemini 2.5 Flash",
      "provider": "google",
      "contextWindow": 1000000,
      "supportsTools": true,
      "supportsStreaming": true
    }
  ]
}

List Available Tools ​

bash
GET /api/agents/{id}/chat/tools

Response ​

json
{
  "tools": [
    {
      "name": "search_knowledge",
      "description": "Search the knowledge base for relevant information",
      "parameters": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search query"
          }
        },
        "required": ["query"]
      }
    },
    {
      "name": "browse_url",
      "description": "Fetch and read content from a URL",
      "parameters": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "URL to browse"
          }
        },
        "required": ["url"]
      }
    },
    {
      "name": "execute_sql",
      "description": "Execute a SQL query against the database",
      "parameters": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "SQL query to execute"
          }
        },
        "required": ["query"]
      }
    }
  ]
}

Conversations API ​

List Conversations ​

bash
GET /api/agents/{id}/chat/conversations

Response ​

json
{
  "conversations": [
    {
      "id": "conv-123",
      "title": "Product Questions",
      "messageCount": 15,
      "lastMessageAt": "2024-12-15T10:30:00Z",
      "createdAt": "2024-12-15T10:00:00Z"
    },
    {
      "id": "conv-456",
      "title": "Technical Support",
      "messageCount": 8,
      "lastMessageAt": "2024-12-14T15:20:00Z",
      "createdAt": "2024-12-14T15:00:00Z"
    }
  ]
}

Create Conversation ​

bash
POST /api/agents/{id}/chat/conversations
Content-Type: application/json

{
  "title": "New Chat"
}

Response ​

json
{
  "id": "conv-789",
  "title": "New Chat",
  "messageCount": 0,
  "createdAt": "2024-12-15T11:00:00Z"
}

Delete Conversation ​

bash
DELETE /api/agents/{id}/chat/conversations/{conversationId}

Response ​

json
{
  "success": true,
  "deleted": 1
}

Message Management ​

Delete Message ​

bash
DELETE /api/agents/{id}/chat/messages/{messageId}

Response ​

json
{
  "success": true
}

Regenerate Response ​

Regenerate the assistant's response for a message.

bash
POST /api/agents/{id}/chat/messages/{messageId}/regenerate
Content-Type: application/json

{
  "model": "gpt-4o",
  "enableTools": true,
  "stream": true
}

The response format matches the standard message response (streaming or non-streaming based on the stream parameter).

Message Format ​

ChatMessage ​

typescript
interface ChatMessage {
  id: string
  role: "user" | "assistant" | "system" | "tool"
  content: string
  conversationId?: string
  toolCalls?: ToolCall[]
  toolResults?: ToolResult[]
  metadata?: {
    model?: string
    toolCalls?: ToolCall[]
    toolResults?: ToolResult[]
  }
  createdAt: string
}

ToolCall ​

typescript
interface ToolCall {
  id: string          // 9-character alphanumeric ID
  name: string        // Tool name
  arguments: Record<string, unknown>  // Tool parameters
}

ToolResult ​

typescript
interface ToolResult {
  toolCallId: string  // References ToolCall.id
  name: string        // Tool name
  result: unknown     // Tool output
  error?: string      // Error message if failed
}

Errors ​

CodeDescription
400Invalid message or parameters
404Conversation or message not found
409Conversation locked (concurrent request)
429Rate limited
500AI service error

Error Response ​

json
{
  "error": "Conversation is currently being processed",
  "code": "CONVERSATION_LOCKED"
}

Context Window Management ​

The API automatically manages context:

  • Token estimation: ~4 characters = 1 token
  • Reserved tokens: ~20K for system prompt, tools, RAG, and response
  • Automatic trimming: Older messages removed when approaching limits
  • System prompt: Always included in context

Agentic Loop ​

When tools are enabled, the API uses an agentic loop:

  1. Maximum 8 tool call iterations per message
  2. Loop detection prevents repeated calls with same arguments
  3. Tool results are added to conversation for context
  4. Large results (like screenshots) are truncated

Examples ​

Simple Chat ​

bash
curl -X POST https://your-domain.com/api/agents/{id}/chat \
  -H "Content-Type: application/json" \
  -d '{"content": "Hello!"}'

Chat with Model Selection ​

bash
curl -X POST https://your-domain.com/api/agents/{id}/chat \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Explain quantum computing",
    "model": "gpt-4o"
  }'

Streaming with Tools ​

bash
curl -X POST https://your-domain.com/api/agents/{id}/chat \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Search for recent news about AI",
    "enableTools": true,
    "stream": true
  }'

Continue Conversation ​

bash
curl -X POST https://your-domain.com/api/agents/{id}/chat \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Tell me more about that",
    "conversationId": "conv-123"
  }'