> ## Documentation Index
> Fetch the complete documentation index at: https://docs.illa.io/llms.txt
> Use this file to discover all available pages before exploring further.

# IllaSDK

> High-level SDK facade for chat sessions, tool loops, and polling

`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

```ts theme={null}
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`](/sdk/api/chat), [`CoreApiProvider`](/sdk/api/providers/core-api-provider), and [`ContextManager`](/sdk/api/context-manager) directly.

## Constructor

```ts theme={null}
new IllaSDK(config, options?)
```

The constructor accepts API transport settings in `config` and context/cache customization in `options`.

### `config`

<ParamField body="apiKey" type="string" required>
  API key used as `x-api-key` for Core API requests.
</ParamField>

<ParamField body="baseURL" type="string">
  Optional Core API base URL override.
</ParamField>

<ParamField body="timeout" type="number">
  HTTP timeout in milliseconds.
</ParamField>

<ParamField body="headers" type="Record<string, string>">
  Extra headers merged into requests.
</ParamField>

<ParamField body="httpClientFactory" type="HttpClientFactory">
  Optional Axios client factory.
</ParamField>

<ParamField body="routes" type="CoreApiProviderRoutes">
  Optional route overrides (`chat`, `actionStatus`).
</ParamField>

### `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:

1. `sendMessage(...)` to start or continue a chat
2. inspect `response.data.pendingTools`
3. execute the returned tools in your app
4. `sendToolResults(...)` to continue the loop
5. use polling helpers if the action completes asynchronously

## Core methods

### `sendMessage`

```ts theme={null}
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`

```ts theme={null}
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`

```ts theme={null}
sendToolResult(chatId: string, toolResult: IllaToolOutcomeJSON): Promise<SendMessageResult>
```

Sends one tool outcome.

### `sendToolResults`

```ts theme={null}
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

```ts theme={null}
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

```ts theme={null}
subscribeToToolStatus(
  params: { toolName: string; protocol: string; descriptor: BaseLongPollingArgs },
  callbacks: AsyncCheckerEvents,
  config?: Partial<PollingConfig>,
): EventSubscription
```

```ts theme={null}
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

```ts theme={null}
getResponseMetadata(result: SendMessageResult): ResponseMetadata
static createNewContextManager(cache: ICache, options: ContextManagerOptions): ContextManager
```

## Tool loop example

```ts theme={null}
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

* [Chat](/sdk/api/chat)
* [AsyncToolChecker](/sdk/api/async-tool-checker)
* [Handling Tool Execution](/sdk/guides/handling-tool-execution)
