TypeScript/JavaScript SDK for interacting with the LangGraph REST API server
The ThreadsClient provides comprehensive thread lifecycle management for conversation handling, state management, and history tracking in LangGraph applications. Threads represent conversation sessions that maintain state across multiple run executions, enabling persistent conversational experiences with full state management capabilities.
The ThreadsClient supports:
class ThreadsClient<TStateType = DefaultValues, TUpdateType = TStateType> extends BaseClient {
/**
* Get thread by ID with optional type parameter for state values
* @param threadId - Unique thread identifier
* @returns Promise resolving to thread with typed values
*/
get<ValuesType = TStateType>(threadId: string): Promise<Thread<ValuesType>>;
/**
* Create a new thread with optional configuration
* @param payload - Thread creation configuration
* @returns Promise resolving to newly created thread
*/
create(payload?: CreateThreadPayload): Promise<Thread<TStateType>>;
/**
* Copy an existing thread to create a new thread with same configuration
* @param threadId - Source thread ID to copy
* @returns Promise resolving to copied thread
*/
copy(threadId: string): Promise<Thread<TStateType>>;
/**
* Update thread metadata and configuration
* @param threadId - Thread ID to update
* @param payload - Update configuration
* @returns Promise resolving to updated thread
*/
update(threadId: string, payload?: UpdateThreadPayload): Promise<Thread>;
/**
* Delete thread permanently
* @param threadId - Thread ID to delete
* @returns Promise resolving when deletion completes
*/
delete(threadId: string): Promise<void>;
/**
* Search threads with flexible criteria and pagination
* @param query - Search parameters and filters
* @returns Promise resolving to array of matching threads
*/
search<ValuesType = TStateType>(query?: ThreadSearchQuery): Promise<Thread<ValuesType>[]>;
/**
* Get current thread state at specific checkpoint with optional subgraph data
* @param threadId - Thread ID
* @param checkpoint - Specific checkpoint ID or checkpoint object (optional)
* @param options - Additional options for subgraph inclusion
* @returns Promise resolving to thread state
*/
getState<ValuesType = TStateType>(
threadId: string,
checkpoint?: Checkpoint | string,
options?: { subgraphs?: boolean }
): Promise<ThreadState<ValuesType>>;
/**
* Update thread state with new values and configuration
* @param threadId - Thread ID to update
* @param options - State update configuration
* @returns Promise resolving to updated configuration
*/
updateState<ValuesType = TUpdateType>(
threadId: string,
options: UpdateStateOptions
): Promise<Pick<Config, "configurable">>;
/**
* Patch thread metadata without affecting state values
* @param threadIdOrConfig - Thread ID or full config object
* @param metadata - Metadata to patch
* @returns Promise resolving when patch completes
*/
patchState(threadIdOrConfig: string | Config, metadata: Metadata): Promise<void>;
/**
* Get complete thread state history across all checkpoints
* @param threadId - Thread ID
* @param options - History retrieval options
* @returns Promise resolving to array of historical states
*/
getHistory<ValuesType = TStateType>(
threadId: string,
options?: GetHistoryOptions
): Promise<ThreadState<ValuesType>[]>;
}interface Thread<ValuesType = DefaultValues> {
/** Unique thread identifier */
thread_id: string;
/** Thread creation timestamp */
created_at: string;
/** Thread last update timestamp */
updated_at: string;
/** Thread metadata for custom data */
metadata: Metadata;
/** Current thread status */
status: ThreadStatus;
/** Current thread state values */
values: ValuesType;
}
type ThreadStatus = "idle" | "busy" | "interrupted" | "error";
interface Metadata {
[key: string]: any;
}interface ThreadState<ValuesType = DefaultValues> {
/** Thread state values */
values: ValuesType;
/** Associated checkpoint information */
checkpoint: Checkpoint;
/** Thread metadata */
metadata: Metadata;
/** Thread creation timestamp */
created_at: string;
/** Parent checkpoint ID if applicable */
parent_checkpoint?: string | null;
/** Current thread tasks */
tasks: ThreadTask[];
}
interface Checkpoint {
/** Unique checkpoint identifier */
checkpoint_id: string;
/** Checkpoint thread ID */
thread_id: string;
/** Parent checkpoint ID */
parent_checkpoint_id?: string | null;
/** Checkpoint type */
type: "checkpoint";
/** Checkpoint metadata */
checkpoint: {
ts: string;
id: string;
version: number;
};
}
interface ThreadTask {
/** Task ID */
id: string;
/** Task name */
name: string;
/** Task path in execution graph */
path: string[];
/** Task error information if failed */
error?: string;
/** Task interrupts */
interrupts: Interrupt[];
}interface CreateThreadPayload {
/** Optional thread metadata */
metadata?: Metadata;
/** Initial thread state values */
values?: Record<string, any>;
/** If true, create as a copy of another thread */
if_exists?: "raise" | "do_nothing";
}
interface UpdateThreadPayload {
/** Updated thread metadata */
metadata?: Metadata;
/** Updated thread values */
values?: Record<string, any>;
}
interface UpdateStateOptions {
/** New state values to set */
values?: Record<string, any>;
/** Update configuration */
config?: Config;
/** Update mode configuration */
as_node?: string;
/** Interrupt configuration */
interrupt_after?: string[];
/** Interrupt before configuration */
interrupt_before?: string[];
}interface ThreadSearchQuery {
/** Metadata filters for search */
metadata?: Record<string, any>;
/** Thread status filter */
status?: ThreadStatus;
/** Pagination limit */
limit?: number;
/** Pagination offset */
offset?: number;
/** Created after timestamp filter */
created_after?: string;
/** Created before timestamp filter */
created_before?: string;
}
interface GetHistoryOptions {
/** Maximum number of historical states to return */
limit?: number;
/** Include checkpoint data */
checkpoints?: boolean;
/** Metadata filters */
metadata?: Record<string, any>;
/** Get history before specific checkpoint */
before?: Checkpoint | string;
/** Get history after specific checkpoint */
after?: Checkpoint | string;
}import { Client } from "@langchain/langgraph-sdk";
const client = new Client({
apiUrl: "https://api.langgraph.example.com",
apiKey: "your-api-key"
});
// Create a new thread
const thread = await client.threads.create({
metadata: {
user_id: "user123",
conversation_type: "support"
},
values: {
messages: [],
context: "customer support session"
}
});
console.log("Created thread:", thread.thread_id);
// Get thread information
const retrievedThread = await client.threads.get(thread.thread_id);
console.log("Thread status:", retrievedThread.status);
console.log("Thread values:", retrievedThread.values);
// Update thread metadata
const updatedThread = await client.threads.update(thread.thread_id, {
metadata: {
...retrievedThread.metadata,
priority: "high",
last_activity: new Date().toISOString()
}
});
// Copy thread to create a duplicate
const copiedThread = await client.threads.copy(thread.thread_id);
console.log("Copied thread ID:", copiedThread.thread_id);// Get current thread state
const state = await client.threads.getState(thread.thread_id);
console.log("Current values:", state.values);
console.log("Checkpoint:", state.checkpoint.checkpoint_id);
// Get state at specific checkpoint
const historicalState = await client.threads.getState(
thread.thread_id,
"checkpoint_abc123"
);
// Update thread state
await client.threads.updateState(thread.thread_id, {
values: {
messages: [
...state.values.messages,
{ role: "user", content: "Hello!" }
]
},
config: {
configurable: {
temperature: 0.7
}
}
});
// Patch thread metadata only
await client.threads.patchState(thread.thread_id, {
session_duration: "45m",
interaction_count: 12
});// Search threads with filters
const threads = await client.threads.search({
metadata: { user_id: "user123" },
status: "idle",
limit: 50,
created_after: "2024-01-01T00:00:00Z"
});
console.log(`Found ${threads.length} matching threads`);
// Get complete thread history
const history = await client.threads.getHistory(thread.thread_id, {
limit: 100,
checkpoints: true
});
console.log("Thread history:");
history.forEach((state, index) => {
console.log(`${index + 1}. Checkpoint: ${state.checkpoint.checkpoint_id}`);
console.log(` Created: ${state.created_at}`);
console.log(` Values: ${JSON.stringify(state.values, null, 2)}`);
});
// Get history within date range
const recentHistory = await client.threads.getHistory(thread.thread_id, {
limit: 20,
metadata: { interaction_type: "chat" },
after: "checkpoint_start123"
});interface CustomState {
messages: Array<{
role: string;
content: string;
timestamp: string;
}>;
user_context: {
preferences: Record<string, any>;
history: string[];
};
session_data: {
start_time: string;
activity_count: number;
};
}
// Create typed thread
const typedThread = await client.threads.create({
metadata: { type: "conversation" },
values: {
messages: [],
user_context: {
preferences: { theme: "dark", language: "en" },
history: []
},
session_data: {
start_time: new Date().toISOString(),
activity_count: 0
}
} as CustomState
});
// Get typed state
const typedState = await client.threads.getState<CustomState>(
typedThread.thread_id
);
// Update with type safety
await client.threads.updateState<CustomState>(typedThread.thread_id, {
values: {
messages: [
...typedState.values.messages,
{
role: "user",
content: "Hello!",
timestamp: new Date().toISOString()
}
],
session_data: {
...typedState.values.session_data,
activity_count: typedState.values.session_data.activity_count + 1
}
}
});try {
// Attempt thread operations with error handling
const thread = await client.threads.create({
metadata: { user_id: "user456" },
if_exists: "raise" // Fail if thread already exists
});
// Perform operations...
const state = await client.threads.getState(thread.thread_id);
// Update state with validation
await client.threads.updateState(thread.thread_id, {
values: {
validated_data: true,
last_update: new Date().toISOString()
},
config: {
tags: ["validated", "active"]
}
});
} catch (error) {
console.error("Thread operation failed:", error);
// Handle specific error types
if (error.status === 404) {
console.log("Thread not found");
} else if (error.status === 409) {
console.log("Thread already exists");
}
} finally {
// Cleanup if needed
if (thread && thread.thread_id) {
// Optional: Delete thread after use
// await client.threads.delete(thread.thread_id);
}
}The ThreadsClient provides complete thread management capabilities with type safety, comprehensive state handling, and flexible search operations, making it ideal for building conversational applications with persistent state management.
Install with Tessl CLI
npx tessl i tessl/npm-langchain--langgraph-sdk