IllaSDK is the main SDK client. Use it when you want one object to manage chat sessions, tool-result loops, and async action polling.
Typical usage
import { IllaSDK } from '@illalabs/sdk'
const sdk = new IllaSDK({
apiKey: process.env.ILLA_API_KEY!,
})
const result = await sdk.sendMessage(
'Swap 1 ETH to USDC on Base',
{ userContext: { address: '0x1234...' } },
)
When to use IllaSDK
Use IllaSDK if your integration needs:
- a high-level chat client
- chat ID management
- helper methods for returning tool results
- polling utilities for long-running actions
If you need lower-level control over transport or context storage, use Chat, CoreApiProvider, and ContextManager directly.
Constructor
new IllaSDK(config, options?)
The constructor accepts API transport settings in config and context/cache customization in options.
config
API key used as x-api-key for Core API requests.
Optional Core API base URL override.
HTTP timeout in milliseconds.
Extra headers merged into requests.
Optional Axios client factory.
Optional route overrides (chat, actionStatus).
options
Provide either:
cache + optional contextManagerOptions, or
contextManager (custom implementation)
Property
chatIds: string[]
List of active chat IDs managed by the instance.
Core workflow
Most integrations use IllaSDK in this order:
sendMessage(...) to start or continue a chat
- inspect
response.data.pendingTools
- execute the returned tools in your app
sendToolResults(...) to continue the loop
- use polling helpers if the action completes asynchronously
Core methods
sendMessage
sendMessage(
msg: string | Prompt,
context: { chatId: string } | { userContext: UserContext },
chatOptions?: Omit<ChatOptions, 'userContext'>,
options?: { signal?: AbortSignal; onRequestId?: (requestId: string) => void },
): Promise<SendMessageResult>
Starts or continues a chat turn.
When creating a new chat via { userContext }, you can include signerWallet
for smart-account flows where a separate EOA signs transactions/messages.
This is the main entry point for non-streaming chat requests.
sendMessageStreaming
sendMessageStreaming(
msg: string | Prompt,
context: { chatId: string } | { userContext: UserContext },
options?: SendMessageStreamingOptions,
chatOptions?: Omit<ChatOptions, 'userContext'>,
): Promise<void>
Streams telemetry and final result via a single SSE request.
Use this when you want streaming events and the final assistant response from a single request.
sendToolResult(chatId: string, toolResult: IllaToolOutcomeJSON): Promise<SendMessageResult>
Sends one tool outcome.
sendToolResults(chatId: string, toolResults: IllaToolOutcomeJSON[]): Promise<SendMessageResult>
Sends multiple tool outcomes in one request.
Throws SdkEmptyToolsResultsError if toolResults is empty.
The returned SendMessageResult can include:
- Final assistant text (
response.data.text)
- Additional
pendingTools (for multi-step tool loops)
Use sendToolResults for the common case. It reduces request overhead and keeps the tool loop explicit.
Chat and context methods
getMessages(chatId: string): Promise<MessageHistoryType>
appendMessages(chatId: string, messages: MessageHistoryType): Promise<void>
clearContext(chatId: string): Promise<void>
deleteChat(chatId: string): Promise<void>
createChat(options: ChatOptions, contextManager?: ContextManager): Chat
getChat(chatId: string): Chat
getChatIds(): string[]
Use these methods when you need direct access to stored conversation state or want to manage chat instances manually.
Polling methods
subscribeToToolStatus(
params: { toolName: string; protocol: string; descriptor: BaseLongPollingArgs },
callbacks: AsyncCheckerEvents,
config?: Partial<PollingConfig>,
): EventSubscription
awaitAction(
chatId: string,
descriptor: { toolName: string; protocol: string; args: BaseLongPollingArgs },
): Promise<AwaitActionResult>
Polling config units are seconds.
Use polling after you have already submitted a transaction or other long-running tool action and want status updates.
Utilities
getResponseMetadata(result: SendMessageResult): ResponseMetadata
static createNewContextManager(cache: ICache, options: ContextManagerOptions): ContextManager
import { IllaSDK } from '@illalabs/sdk'
import { IllaToolError, IllaToolOutcome } from '@illalabs/interfaces'
const sdk = new IllaSDK({ apiKey: process.env.ILLA_API_KEY! })
const first = await sdk.sendMessage(
'Swap 1 ETH to USDC on Base',
{
userContext: {
address: '0x1234...',
// Optional signer EOA for smart-account flows
// signerWallet: '0x5678...'
},
},
)
if (first.response.isError) {
throw new Error(first.response.error.message)
}
let pendingTools = [...(first.response.data.pendingTools ?? [])]
while (pendingTools.length > 0) {
const outcomes = await Promise.all(
pendingTools.map(async (tool) => {
try {
const executionResult = await executeTool(tool)
return IllaToolOutcome.success(tool.toolCallId, tool.toolName, executionResult).toJSON()
} catch (error) {
return IllaToolOutcome.error(
tool.toolCallId,
tool.toolName,
IllaToolError.execution(
tool.toolCallId,
tool.toolName,
error instanceof Error ? error.message : 'Execution failed',
),
).toJSON()
}
}),
)
const followUp = await sdk.sendToolResults(first.chatId, outcomes)
if (followUp.response.isError) {
throw new Error(followUp.response.error.message)
}
pendingTools = [...(followUp.response.data.pendingTools ?? [])]
}
Related pages