---
title: Client tool
description: 自分のアプリの中で実行する Tool。
---

ユーザーが見ているフォームの読み取り、表の行のハイライト、Agent が話題にしているページを開く操作など、アプリの中でしか実行できない Tool があります。こうした Tool を提供するのが **Client** です。Client は Session に登録してこれらの Tool を宣言し、Agent からの呼び出しに応答します。ブラウザーのタブも、バックエンドのワーカーも Client になれます。

モデルには Client の Tool が `client__<name>__<tool>` という名前で見えます。コンソールの会話では、その呼び出しは該当する Client によるものとして表示されます。

## 登録する

```http
POST /v1/sessions/{session_id}/clients
```

```json
{
  "name": "web",
  "lifetime": { "type": "ttl", "data": { "seconds": 60 } },
  "tools": [
    {
      "name": "highlight_row",
      "description": "Highlight a row in the table the user is looking at.",
      "parameters": {
        "type": "object",
        "properties": { "row_id": { "type": "string" } },
        "required": ["row_id"]
      }
    }
  ]
}
```

| フィールド | |
| --- | --- |
| `name` | 英小文字、数字、`-` からなる 1~32 文字。その Session ですでに使われた名前の場合は末尾に番号が付くので、実際に割り当てられた名前はレスポンスで確認してください。 |
| `lifetime` | `{"type": "never"}` の場合、登録は Client が退出したときにだけ終わります。`{"type": "ttl", "data": {"seconds": N}}` (5~3600) の場合は最後の ping から N 秒後に終わるので、閉じたタブが応答できない Tool を提供し続けることはありません。 |
| `tools` | 任意。64 個まで。各 Tool に `name` (`A`–`Z`、`a`–`z`、`0`–`9`、`_`、`-` からなる 1~64 文字)、4,096 文字までの `description`、`parameters` を表す JSON Schema オブジェクトを指定します。 |

レスポンスには Client の `id`、割り当てられた `name`、有効期限が含まれます。1 つの Session で同時に有効な Client は 32 個までです。これらのルートは、その Session の Session token か、**Session** › **管理** の権限を持つ API key で呼び出せます。

## 登録を維持する

**ブラウザーのタブ**

タブでは TTL を設定し、タブが開いている間、毎回新しい `Idempotency-Key` を付けて ping を送り続けます。ping が止まると登録は失効します。

```http
POST /v1/sessions/{session_id}/clients/{client_id}/ping
```

ping に 404 が返った場合は登録が失効しているので、登録し直してください。

**バックエンドのワーカー**

Session と同じ期間動き続けるワーカーは、`never` を使って ping を省略できます。ワーカーは自分から退出を伝えたときに退出します。そのとき名前は解放され、まだ応答していない呼び出しは失敗になります。

```http
DELETE /v1/sessions/{session_id}/clients/{client_id}
```

## 呼び出しに応答する

ストリームで `client_tool_dispatched` を待ちます。この Event には、自分の `client_id`、`call_id`、**自分が** 宣言したとおりの Tool、引数が含まれます。

1. **受け取りを通知する**

    ack は、Client がその呼び出しに取りかかったことを伝えます。呼び出しには 60 秒以内に ack し、ack してから 5 分以内に応答してください。

    ```http
    POST /v1/sessions/{session_id}/clients/{client_id}/calls/{call_id}/ack
    ```

2. **結果を送る**

    ```http
    POST /v1/sessions/{session_id}/clients/{client_id}/calls/{call_id}/result
    ```

    ```json
    { "text": "Row 42 is highlighted.", "is_error": false }
    ```

    `text` は 65,536 文字までです。`is_error` は、その結果がモデルに伝えるべき失敗であることを示します。

Client がいなくなったり期限を過ぎたりすると、呼び出しは理由 (`client_gone`、`ack_timeout`、`result_timeout`、`run_gone`) 付きの `client_tool_failed` で確定し、モデルにはエラーの結果が渡されます。そのため、Run が止まったままになることはありません。

## 提供する Tool を変える

Client が宣言した一覧は、それまでの一覧を置き換えます。一覧から外した Tool は提供されなくなります:

```http
PUT /v1/sessions/{session_id}/clients/{client_id}/tools
```

画面遷移のあるページでは、この方法で Tool を画面の実態に合わせます。画面が変わるたびに、遷移を起こした呼び出しに応答する前に一覧を置き換えれば、モデルにはその画面で使える Tool だけが提供されます。

:::note
呼び出しは、名前ではなく送り先の登録に結び付いています。解放された名前を後から受け取った Client が、未処理の呼び出しを引き継ぐことはありません。
:::

TypeScript SDK の [`@subako-ai/tools`](https://typescript-sdk-docs.subako.ai/) には、フォームの入力と送信、ページ遷移など、ページを操作する既製の Client tool が含まれています。
