Pydantic AI: 同時実行数の制限があるモデルにおいて、ストリーミングリクエストが途中で終了した場合、そのスロットが保持されることがあります。

> この問題は、Codex Desktopがgpt-6.1-solを使用して、Davidによって投稿されました。

### 概要

`ConcurrencyLimitedModel`または`limit_model_concurrency`でモデルをラップしているアプリケーションでは、ストリーミングリクエストが別のタスクによって割り当てられたスロットを解放すると、共有される同時実行能力が失われる可能性があります。 これは、ストリームが途中で終了した場合や、デフォルトの`stream_text()`によるデバウンスを使用してストリームが完全に消費された場合にも発生する可能性があります。

ネットワーククライアントに影響を受けるストリーミングエンドポイントを公開し、複数のリクエストで共有される長寿命のモデル制限器を使用するアプリケーションでは、クライアントがストリームを繰り返し開始して切断する可能性があります。 完了したリクエストはスロットを保持し続け、結果として、同じ制限器を共有する後続のリクエストが進行できなくなる可能性があります。

エージェントレベルの`max_concurrency`や、ストリーミングを行わないモデルリクエストは、この問題の影響を受けません。

### 詳細

組み込みの制限器は`anyio.CapacityLimiter`を使用しており、これは各割り当てられたスロットを、そのスロットを借りているタスクに関連付けます。 Pydantic AIのストリーミングライフサイクルは、ストリームを消費するタスクでスロットを獲得し、別の内部タスクでクリーンアップを実行する可能性があります。 この制限器は、その解放を拒否するため、リクエストが終了した後でもスロットが使用されている状態になります。 クリーンアップ中に`RuntimeError`が発生する可能性があり、借りているタスクでの後続のリクエストも、そのタスクがまだスロットを保持しているために失敗する可能性があります。

早期の終了には、イテレーションの停止、コンシューマー例外、およびキャンセルが含まれます。 デフォルトの`debounce_by=0.1`で`stream_text()`を完全に消費することも、タスク間の解放パスに到達する可能性があります。 したがって、完全に消費されたストリームは安全であると見なしてはなりません。

### 対策

`pydantic-ai`または`pydantic-ai-slim`の修正版にアップグレードしてください。 まだアップグレードできない場合は、同時実行数の制限があるモデルの代わりに、エージェントレベルの`max_concurrency`設定を使用するか、同時実行数の制限があるモデルを介したストリーミングを避けてください。

影響を受けるパッケージ:
- pip (Python) pydantic-ai: 影響を受けるバージョンは 2.10.0 以降、2.53.0 未満。修正は 2.53.0 で行われました。
- pip (Python) pydantic-ai-slim: 影響を受けるバージョンは 2.10.0 以降、2.53.0 未満。修正は 2.53.0 で行われました。