# Transactions and Tools

The Transaction Protocol in the Persona Chat SDK is designed to handle structured interactions between the client and the Persona API. It allows you to define and execute specific operations (tools) in response to function calls.

## How It Works

1. **Transaction Handling**: The protocol listens for incoming transactions and invokes the appropriate tool based on the function call.
2. **Session Management**: It shares the same session as other protocols, ensuring consistency.
3. **Custom Logic**: You can define custom tools to handle specific function calls.

## Usage Example

To enable the Transaction Protocol, include it in the `protocols` configuration of the `PersonaRuntimeProvider`:

```tsx
<PersonaRuntimeProvider
  dev
  logger={logger}
  protocols={{
    transaction: async (transaction) => {
      await transaction.invoke({
        get_user_agent: () => navigator.userAgent || 'unknown',
        get_client_date: () => ({ date: new Date().toISOString() }),
      });
    },
  }}
  session="your-session-id"
  apiKey="your-api-key"
  agentId="your-agent-id"
>
  <YourComponent />
</PersonaRuntimeProvider>
```

---

## Managing Tools

### Using the `tools` Prop in PersonaRuntimeProvider

The `tools` prop allows you to define custom tools that the Transaction Protocol can invoke in response to function calls.

#### 1. As an Object (Legacy, Backward Compatible)

> **Important:** When using the legacy object format, your agent configuration must also include the tool schema for each tool. If the schema is missing, the configured tools will not work as expected. This is not required when using the array format with `createTool`.

```tsx
<PersonaRuntimeProvider
  tools={{
    get_user_agent: () => navigator.userAgent || 'unknown',
    get_client_date: () => ({ date: new Date().toISOString() }),
  }}
  ...otherProps
/>
```

#### 2. As an Array of Tool Instances (Recommended)

For better type safety, schema support, and documentation, you can define tools using the `createTool` utility:

```tsx
import { createTool } from '@applica-software-guru/persona-chat-sdk';

const tools = [
  createTool({
    name: 'sum',
    title: 'Sum two numbers',
    description: 'Sums two numbers and returns the result.',
    parameters: {
      a: { type: 'number', description: 'First number to sum', required: true },
      b: { type: 'number', description: 'Second number to sum', required: true },
    },
    output: {
      result: { type: 'number', description: 'Sum of the two numbers' },
    },
    implementation: async (a: number, b: number) => {
      return { result: a + b };
    },
  }),
];

<PersonaRuntimeProvider
  tools={tools}
  ...otherProps
/>
```

---

## Advanced Transaction Handling

You can manage transactions manually by inspecting the function call and executing the `complete` or `fail` methods.

```tsx
<PersonaRuntimeProvider
  protocols={{
    transaction: async (transaction) => {
      const { functionCall, persistable } = transaction;

      try {
        if (functionCall.name === 'get_user_agent') {
          const result = navigator.userAgent || 'unknown';
          await persistable.complete(result);
        } else {
          throw new Error(`Unknown function call: ${functionCall.name}`);
        }
      } catch (error) {
        await persistable.fail({ error: error.message });
      }
    },
  }}
  ...
/>
```

## Best Practices

1. **Tool Naming**: Use descriptive names.
2. **Error Handling**: Handle errors gracefully.
3. **Testing**: Test tools thoroughly.
4. **Security**: Avoid exposing sensitive data.
