> For a complete index of all SignalWire documentation pages, fetch https://signalwire.com/docs/llms.txt

# Signals

> Error and signal classes for controlling tool behavior and multi-agent handoffs.

[agent]: /docs/server-sdks/reference/typescript/agents/livewire/agent

LiveWire provides error and signal classes that tool handlers can throw or return
to control agent behavior.

## **StopResponse**

Extends `Error`. When thrown inside a tool handler, signals that the tool should
**not** trigger another LLM reply. Use this when the tool's side effect is the
final action and no further conversation is needed.

```typescript {8}
import { tool, StopResponse } from '@signalwire/sdk/livewire';

const endCall = tool({
  description: 'End the current call.',
  parameters: { reason: { type: 'string' } },
  execute: (params) => {
    // Perform cleanup...
    throw new StopResponse(`Call ended: ${params.reason}`);
  },
});
```

### Constructor

```typescript {1}
new StopResponse(message?: string)
```

**`message`** `string` — default: "StopResponse"

Optional error message. Defaults to `"StopResponse"`.

---

---

## **ToolError**

Extends `Error`. Signals a tool execution failure. Throw this when a tool
encounters a problem that should be reported back to the LLM so it can
communicate the issue to the user or retry.

```typescript {11}
import { tool, ToolError } from '@signalwire/sdk/livewire';

const transferFunds = tool<{ amount: number; toAccount: string }>({
  description: 'Transfer funds to another account.',
  parameters: {
    amount: { type: 'number' },
    toAccount: { type: 'string' },
  },
  execute: (params) => {
    if (params.amount <= 0) {
      throw new ToolError('Amount must be positive.');
    }
    return `Transferred $${params.amount} to ${params.toAccount}.`;
  },
});
```

### Constructor

```typescript {1}
new ToolError(message: string)
```

**`message`** `string` — required

Error message describing what went wrong. This is sent back to the LLM.

---

---

## **AgentHandoff**

A signal class for handing off a conversation to a different agent in multi-agent
scenarios. Created via the `handoff()` helper function.

```typescript {7-9}
import { Agent, handoff, tool } from '@signalwire/sdk/livewire';

const billingAgent = new Agent({
  instructions: 'You handle billing questions.',
});

const transferToBilling = handoff({
  agent: billingAgent,
  returns: 'Transferred to billing department.',
});
```

### Properties

**`agent`** `Agent`

The target [`Agent`][agent] for the handoff.

---

**`returns`** `string | undefined`

Optional return message for the handoff.

---

### handoff()

```typescript {1}
function handoff(options: { agent: Agent; returns?: string }): AgentHandoff
```

Factory function that creates an `AgentHandoff` instance.

**`agent`** `Agent` — required

The target agent to hand off to.

---

**`returns`** `string | undefined`

Optional return value for the handoff.

---

---

## **ChatContext**

A minimal class mirroring the LiveKit `ChatContext`. Stores an in-memory list
of chat messages. On SignalWire, the platform manages conversation history
for the active call — this class exists so that existing livekit-agents code
that references `ChatContext` compiles without errors, and so callers can
stage messages in prewarm code.

```typescript {4}
import { llm } from '@signalwire/sdk/livewire';

const chat = new llm.ChatContext();
chat.append({ role: 'system', text: 'You are a helpful agent.' });
```

### Properties

**`messages`** `Array<Record<string, string>>`

Appended chat messages. Each entry is stored as `{ role, content }`.

---

### append

```typescript {1}
append(options: { role?: string; text?: string }): this
```

Append a message to `messages`. The stored entry uses `content` (not `text`)
as the body key — `text` is renamed to match the on-wire message shape.

**`role`** `string` — default: "user"

The message role (`"user"`, `"assistant"`, `"system"`, etc.).

---

**`text`** `string` — default: ""

The message content.

---