Overview
The @standardagents/client package provides the core client library for Standard Agents. It’s a framework-agnostic foundation that @standardagents/react and @standardagents/vue build upon.
Key Features
HTTP client for all API operations
WebSocket connection management with auto-reconnection
File upload handling with thumbnail generation
Utility functions for workblocks and attachments
Zero framework dependencies
Installation
npm install @standardagents/client
pnpm add @standardagents/client
yarn add @standardagents/client
Most users should use @standardagents/react or @standardagents/vue instead, which re-export everything from this package with additional framework-specific features.
AgentBuilderClient
HTTP client for all Standard Agents API operations.
import { AgentBuilderClient } from '@standardagents/client'
const client = new AgentBuilderClient ({
endpoint: 'https://your-api.com' ,
token: 'your-auth-token' ,
})
// Create a thread
const thread = await client . createThread ({
agentId: 'support-agent' ,
})
// Send a message
const message = await client . sendMessage ( thread . id , {
role: 'user' ,
content: 'Hello!' ,
})
// Get message history
const messages = await client . getMessages ( thread . id , { limit: 50 })
Methods
Method Description createThread(payload)Create a new thread getThread(threadId)Fetch thread metadata getMessages(threadId, options?)Fetch message history sendMessage(threadId, payload)Send a user message stopExecution(threadId)Cancel in-flight execution uploadFile(threadId, file, path?)Upload a file to thread filesystem listFiles(threadId, path?)List files in thread filesystem getFile(threadId, path)Download a file deleteFile(threadId, path)Delete a file
Configuration
interface AgentBuilderConfig {
endpoint : string // API endpoint URL
token ?: string // Optional auth token
}
ThreadConnectionManager
Manages WebSocket connections with automatic reconnection and heartbeat.
import { ThreadConnectionManager } from '@standardagents/client'
const manager = new ThreadConnectionManager ({
endpoint: 'https://your-api.com' ,
threadId: 'thread-123' ,
token: 'your-auth-token' ,
onMessage : ( message ) => console . log ( 'Message:' , message ),
onChunk : ( chunk ) => console . log ( 'Chunk:' , chunk ),
onStatusChange : ( status ) => console . log ( 'Status:' , status ),
onError : ( error ) => console . error ( 'Error:' , error ),
})
// Connect to both message and log WebSockets
manager . connect ()
// Disconnect when done
manager . disconnect ()
Connection Features
Auto-reconnection : Exponential backoff (1s → 2s → 4s → … → 30s max)
Heartbeat : Ping every 30 seconds to keep connection alive
Status tracking : connecting, connected, reconnecting, disconnected
Options
interface ThreadConnectionOptions {
endpoint : string
threadId : string
token ?: string
onMessage ?: ( message : Message ) => void
onChunk ?: ( chunk : MessageChunkEvent ) => void
onLog ?: ( log : LogDataEvent ) => void
onCustomEvent ?: ( event : CustomEvent ) => void
onStatusChange ?: ( status : ConnectionStatus ) => void
onError ?: ( error : Error ) => void
}
FileUploadManager
Handles file uploads with thumbnail generation and progress tracking.
import { FileUploadManager } from '@standardagents/client'
const uploader = new FileUploadManager ({
endpoint: 'https://your-api.com' ,
threadId: 'thread-123' ,
token: 'your-auth-token' ,
})
// Upload with progress callback
const result = await uploader . upload ( file , {
path: '/uploads/image.png' ,
onProgress : ( progress ) => console . log ( ` ${ progress } %` ),
})
Features
Thumbnail generation : Automatic for image files
Progress tracking : Callbacks for upload progress
Deferred uploads : Returns pending refs before upload completes
Utility Functions
Groups tool calls with their results for UI rendering.
import { transformToWorkblocks } from '@standardagents/client'
const messages = await client . getMessages ( threadId )
const workblocks = transformToWorkblocks ( messages )
// Workblocks group consecutive tool calls:
// [assistant with tool_calls, tool result, tool result, assistant]
// becomes:
// [workblock { workItems: [...] }, assistant]
parseAttachments
Extract attachment references from message content.
import { parseAttachments } from '@standardagents/client'
const attachments = parseAttachments ( message . attachments )
// Returns: AttachmentRef[]
Image Processing
import {
generateImageThumbnail ,
canGenerateThumbnails ,
} from '@standardagents/client'
// Check if thumbnails are supported (requires Canvas API)
if ( canGenerateThumbnails ()) {
const thumbnail = await generateImageThumbnail ( file , {
maxWidth: 200 ,
maxHeight: 200 ,
})
}
File Helpers
import {
generatePendingFileId ,
readFileAsDataUrl ,
isImageMimeType ,
messagesToFiles ,
} from '@standardagents/client'
// Generate unique ID for pending uploads
const id = generatePendingFileId ()
// Read file as data URL
const dataUrl = await readFileAsDataUrl ( file )
// Check if MIME type is an image
isImageMimeType ( 'image/png' ) // true
// Extract files from messages
const files = messagesToFiles ( messages )
Type Exports
The package exports all types needed for building clients:
import type {
// Core message types
Message ,
WorkMessage ,
WorkItem ,
ThreadMessage ,
Thread ,
// Attachment types
AttachmentRef ,
ThreadFile ,
PendingAttachment ,
AttachmentPayload ,
// Configuration
AgentBuilderConfig ,
// Request/Response types
GetMessagesOptions ,
SendMessagePayload ,
CreateThreadPayload ,
// WebSocket event types
MessageDataEvent ,
MessageChunkEvent ,
ErrorEvent ,
ThreadEvent ,
MessageStreamEvent ,
LogDataEvent ,
CustomEvent ,
StoppedByUserEvent ,
LogStreamEvent ,
// Callback types
MessageWebSocketCallbacks ,
LogWebSocketCallbacks ,
ThreadConnectionCallbacks ,
// Connection status
ConnectionStatus ,
} from '@standardagents/client'
Key Types
Message:
interface Message {
id : string
role : 'system' | 'user' | 'assistant' | 'tool'
content : string | null
name ?: string | null
tool_calls ?: string | null
tool_call_id ?: string | null
created_at : number
status ?: 'pending' | 'completed' | 'failed'
attachments ?: string | null
}
PendingAttachment:
interface PendingAttachment {
id : string
file : File
name : string
mimeType : string
size : number
isImage : boolean
previewUrl : string | null
width ?: number
height ?: number
}
AttachmentRef:
interface AttachmentRef {
id : string
type : 'file'
path : string
name : string
mimeType : string
size : number
width ?: number
height ?: number
description ?: string
}
ConnectionStatus:
type ConnectionStatus = 'connecting' | 'connected' | 'reconnecting' | 'disconnected'
Authentication
The client reads auth tokens from localStorage:
// Token is read from this key
const token = localStorage . getItem ( 'agentbuilder_auth_token' )
// Included in requests as:
// Authorization: Bearer {token}
You can also pass the token directly to the client:
const client = new AgentBuilderClient ({
endpoint: 'https://your-api.com' ,
token: 'your-auth-token' ,
})
Building Custom Integrations
Use @standardagents/client directly when:
Building for a framework without an official SDK
Creating custom tooling or CLI applications
Building server-side integrations
Needing fine-grained control over connections
import {
AgentBuilderClient ,
ThreadConnectionManager ,
transformToWorkblocks ,
} from '@standardagents/client'
class CustomChatClient {
private client : AgentBuilderClient
private connection : ThreadConnectionManager | null = null
private messages : Message [] = []
constructor ( endpoint : string , token : string ) {
this . client = new AgentBuilderClient ({ endpoint , token })
}
async connect ( threadId : string ) {
// Load existing messages
this . messages = await this . client . getMessages ( threadId )
// Set up live connection
this . connection = new ThreadConnectionManager ({
endpoint: this . client . endpoint ,
threadId ,
token: this . client . token ,
onMessage : ( msg ) => {
this . messages . push ( msg )
this . onUpdate ?.( transformToWorkblocks ( this . messages ))
},
})
this . connection . connect ()
}
async send ( content : string ) {
await this . client . sendMessage ( this . threadId , {
role: 'user' ,
content ,
})
}
onUpdate ?: ( workblocks : ThreadMessage []) => void
}
Next Steps