diff --git a/CHANGELOG.md b/CHANGELOG.md index c5cebd9..8271ee0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,7 +58,7 @@ Released: 2026-03-02 ### Added - 初回リリース -- GenFlux 評価・レポート・設定 API 用の公式 Python SDK(`GenFlux`, `ConfigClient`, `ReportsClient` 等) +- Genflux 評価・レポート・設定 API 用の公式 Python SDK(`GenFlux`, `ConfigClient`, `ReportsClient` 等) - Pydantic v2 ベースの型付きレスポンス、httpx による HTTP クライアント - 開発・品質: pre-commit(ruff, pyright), pip-audit, gitleaks, ライセンスコンプライアンスチェック diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d0eef3f..9059b33 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ -# Contributing to GenFlux Python SDK +# Contributing to Genflux Python SDK -GenFlux Python SDK へのコントリビューションを歓迎します! +Genflux Python SDK へのコントリビューションを歓迎します! バグ報告・機能要望・ドキュメント改善・コードの改善、いずれも大歓迎です。 --- diff --git a/Makefile b/Makefile index a4efb1c..b2363b5 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: help docs docs-external docs-developer docs-check llms-txt llms-check lint test format +.PHONY: help docs docs-fresh docs-external docs-developer docs-check llms-txt llms-check lint test format help: ## ヘルプを表示 @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' @@ -7,13 +7,16 @@ help: ## ヘルプを表示 # ドキュメント生成 # --------------------------------------------------------------------------- -docs: ## API Reference を全て生成(external + developer) +docs: ## API Reference を全て生成(3-pass LLM改善: 改善→ハルシネーションチェック→UXレビュー) python scripts/generate_api_reference.py --mode all @echo "" - @echo "📖 Generated:" + @echo "📖 Generated (LLM-enriched):" @echo " docs/API_REFERENCE.md (External / SDKユーザー向け)" @echo " docs/DEVELOPER_API_REFERENCE.md (Developer / 開発者向け)" +docs-fresh: ## API Reference を生成(キャッシュなし) + python scripts/generate_api_reference.py --mode all --no-cache + docs-external: ## External API Reference のみ生成 python scripts/generate_api_reference.py --mode external diff --git a/README.md b/README.md index 0e9a8e1..c05680c 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,170 @@ -# GenFlux Python SDK +

+ +   + + + + Genflux + +

-RAG(検索拡張生成)システムの安全性を評価するための GenFlux Platform 公式 Python SDK です。 -数行のコードで、回答品質のスコアリング、RedTeam によるセキュリティテスト、ポリシーチェックを実行できます。 +

+ Genflux Python SDK
+ Genflux Platform 公式 Python SDK。RAG システムの回答品質スコアリング、セキュリティテスト、ポリシーチェックを Python から実行できます。 +

[![Version](https://img.shields.io/badge/version-0.1.2-blue.svg)](https://github.com/elith-co-jp/genflux-python-sdk/releases/tag/v0.1.2) -[![Python Version](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/) +[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/) [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) ---- +## ドキュメント + +詳細な API 仕様・ワークフロー例は以下を参照してください。 + +- [API リファレンス](./docs/API_REFERENCE.md) — 全メソッド・モデル・例外の詳細 +- [クイックスタート](./docs/QUICKSTART.md) — Config 不要で今すぐ試せるサンプル +- [ワークフロー](./docs/WORKFLOW.md) — バッチ評価、CI/CD 統合、エラーハンドリング + +## Why Genflux + +RAG システムを本番運用する際、「回答品質が十分か」「安全性に問題はないか」を継続的に検証する仕組みが不可欠です。 + +Genflux は **RAG の品質・安全性を数値で可視化** するプラットフォームです。この SDK を使って Python から直接評価を実行できます。 + +- **8 種類の評価メトリック** — Faithfulness、Hallucination、Toxicity など、RAG に必要な品質指標をワンライナーで計測 +- **CI/CD 統合** — テストパイプラインに組み込み、品質劣化を自動検知([ワークフロー例](./docs/WORKFLOW.md#cicd統合)) +- **セキュリティテスト** — Genflux Platform 上で Red Teaming による攻撃シミュレーションを実行し、脆弱性を事前に検出 +- **ポリシーチェック** — Genflux Platform 上で AI 事業者ガイドライン準拠を自動検証 + +```python +from genflux import GenFlux + +client = GenFlux() +result = client.evaluation().faithfulness( + question="What is RAG?", + answer="RAG is Retrieval-Augmented Generation.", + contexts=["RAG combines retrieval and generation..."], +) +print(f"Faithfulness: {result.score}") # 0.92 +``` + +## できること + +### RAG 回答品質の評価 + +8 種類のメトリックで RAG システムの回答品質をスコアリングできます。 + +```python +evaluator = client.evaluation() + +# 回答が文脈に基づいているか(忠実性) +result = evaluator.faithfulness(question, answer, contexts) +print(result.score) # 0.92 +print(result.reason) # スコアの根拠 + +# 幻覚(ハルシネーション)検出 +result = evaluator.hallucination(question, answer, contexts) + +# 有害性・偏見チェック +result = evaluator.toxicity(question, answer) +result = evaluator.bias(question, answer) +``` + +### 評価設定の管理 + +RAG API の接続情報・評価条件を Config として保存し、繰り返し利用できます。 + +```python +from genflux.models import ConfigCreate + +config = client.configs.create(ConfigCreate( + name="本番 RAG API", + api_endpoint="https://your-rag-api.example.com/chat", + auth_type="bearer", + auth_token="your-token", +)) + +# 一覧取得・更新・削除 +configs = client.configs.list() +client.configs.update(config.id, ConfigUpdate(name="新しい名前")) +client.configs.delete(config.id) +``` + +### 非同期ジョブの実行・監視 + +大規模な評価やセキュリティテストは非同期ジョブとして実行し、進捗をリアルタイムで追跡できます。 + +```python +job = client.jobs.create( + execution_type="evaluation", + config_id=config.id, +) + +# 完了まで待機(プログレスバー付き) +completed = client.jobs.wait(job.id, timeout=600) +print(completed.results) + +# ジョブの一覧・キャンセル +running = client.jobs.list(status="running") +client.jobs.cancel(job.id) +``` + +### 評価レポートの取得 + +ジョブ完了後、サマリーと詳細の 2 段階でレポートを取得できます。 + +```python +# サマリー: CI/CD ゲーティング向け +report = client.reports.get(report_id, view="summary") +print(report.summary.evaluation.success_rate) # 0.95 + +# 詳細: 失敗ケースの分析・改善提案 +report = client.reports.get(report_id, view="details") +for case in report.details.failed_cases: + print(f"{case.category}: {case.reason}") +``` + +### CI/CD パイプライン統合 + +品質スコアに閾値を設定し、パイプラインの pass/fail を自動判定できます。 + +```python +result = evaluator.faithfulness(question, answer, contexts) +if result.score < 0.8: + raise SystemExit(f"品質基準未達: faithfulness={result.score}") +``` + +## アーキテクチャ + +```mermaid +graph TB + User["Your Code"] --> GF["Genflux Client"] + + GF --> CC["client.configs
ConfigClient"] + GF --> JC["client.jobs
JobsClient"] + GF --> RC["client.reports
ReportsClient"] + GF --> EC["client.evaluation()
EvaluationClient"] + + CC --> API["Genflux Backend API"] + JC --> API + RC --> API + EC --> API + + API --> Queue["Job Queue"] + Queue --> Result["MetricResult
score / reason"] + + style GF fill:#4A90D9,color:#fff + style EC fill:#7B68EE,color:#fff + style API fill:#2E8B57,color:#fff +``` + +| クライアント | アクセス方法 | 説明 | +|---|---|---| +| `GenFlux` | `GenFlux()` | メインクライアント(認証・サブクライアント管理) | +| `EvaluationClient` | `client.evaluation()` | 8 種類のメトリックによる評価実行 | +| `ConfigClient` | `client.configs` | RAG API 設定の CRUD | +| `JobsClient` | `client.jobs` | 非同期ジョブの作成・監視・キャンセル | +| `ReportsClient` | `client.reports` | 評価レポートの取得(サマリー/詳細) | ## インストール @@ -20,80 +177,95 @@ pip install genflux ```python from genflux import GenFlux -# クライアント初期化(環境変数 GENFLUX_API_KEY を使用) -client = GenFlux() +client = GenFlux() # 環境変数 GENFLUX_API_KEY を使用 -# 評価を実行 evaluator = client.evaluation() result = evaluator.faithfulness( question="What is Python?", answer="Python is a programming language.", - contexts=["Python is a high-level programming language."] + contexts=["Python is a high-level programming language."], ) -print(f"Score: {result.score}") # 0.0 ~ 1.0 -print(f"Reason: {result.reason}") +print(result.score) # 0.95 +print(result.reason) # "The answer is based on the provided context." ``` -``` -Evaluation |██████████████████████████████████████████████████| 100.0% Complete -Score: 0.95 -Reason: The answer is based on the provided context. +API Key は明示的に渡すこともできます。 + +```python +client = GenFlux(api_key="pk_xxx") ``` ## 評価メトリック -| メトリック | 説明 | スコア | -|---|---|---| -| `faithfulness` | 回答が提供された文脈に基づいているか | 0〜1 (高↑) | -| `answer_relevancy` | 回答が質問に適切に答えているか | 0〜1 (高↑) | -| `contextual_relevancy` | 取得された文脈が質問に関連しているか | 0〜1 (高↑) | -| `contextual_precision` | 関連性の高い文脈が上位にランクされているか | 0〜1 (高↑) | -| `contextual_recall` | 回答の情報が文脈に帰属できるか(`ground_truth` 必須) | 0〜1 (高↑) | -| `hallucination` | 回答が文脈にない情報を含んでいるか | 0〜1 (低↓) | -| `toxicity` | 回答に有害なコンテンツが含まれるか | 0〜1 (低↓) | -| `bias` | 回答に偏見が含まれるか | 0〜1 (低↓) | - ```python -# 複数メトリックの実行 -faith = evaluator.faithfulness(question, answer, contexts) -relevancy = evaluator.answer_relevancy(question, answer) +evaluator = client.evaluation() + +# 個別に実行 +result = evaluator.faithfulness(question, answer, contexts) + +# 複数メトリックをまとめて実行 +faith = evaluator.faithfulness(question, answer, contexts) +halluc = evaluator.hallucination(question, answer, contexts) toxicity = evaluator.toxicity(question, answer) ``` -## 環境変数 +| メトリック | 説明 | `contexts` | `ground_truth` | スコア | +|---|---|---|---|---| +| `faithfulness` | 回答が提供された文脈に基づいているか | 必須 | — | 0〜1(高いほど良い) | +| `answer_relevancy` | 回答が質問に適切に答えているか | 任意 | — | 0〜1(高いほど良い) | +| `contextual_relevancy` | 取得された文脈が質問に関連しているか | 必須 | — | 0〜1(高いほど良い) | +| `contextual_precision` | 関連性の高い文脈が上位にランクされているか | 必須 | — | 0〜1(高いほど良い) | +| `contextual_recall` | 回答の情報が文脈に帰属できるか | 必須 | 必須 | 0〜1(高いほど良い) | +| `hallucination` | 回答が文脈にない情報を含んでいるか | 必須 | — | 0〜1(低いほど良い) | +| `toxicity` | 回答に有害なコンテンツが含まれるか | 任意 | — | 0〜1(低いほど良い) | +| `bias` | 回答に偏見が含まれるか | 任意 | — | 0〜1(低いほど良い) | -| 変数 | 説明 | デフォルト | -|---|---|---| -| `GENFLUX_API_KEY` | 認証用 API Key | *(必須)* | -| `GENFLUX_ENVIRONMENT` | `"local"` / `"dev"` / `"prod"` | `"prod"` | -| `GENFLUX_API_BASE_URL` | ベース URL の上書き(最優先) | — | +## エラーハンドリング -API Key は [GenFlux Platform ダッシュボード](https://www.platform.genflux.jp/) から発行してください。 +```python +from genflux.exceptions import ( + AuthenticationError, + RateLimitError, + TimeoutError, + JobFailedError, +) -## ドキュメント +try: + result = evaluator.faithfulness(question, answer, contexts) +except AuthenticationError: + # API Key が無効または未設定 + pass +except RateLimitError as e: + # レート制限。e.retry_after 秒後にリトライ + pass +except TimeoutError: + # ジョブがタイムアウト + pass +except JobFailedError as e: + # ジョブ実行失敗。e.error_message で詳細を確認 + pass +``` -| ドキュメント | 内容 | +| 例外 | 発生条件 | |---|---| -| [クイックスタート](./docs/QUICKSTART.md) | Config 不要で今すぐ試せるサンプル | -| [ワークフロー](./docs/WORKFLOW.md) | バッチ評価、CI/CD 統合、エラーハンドリング | -| [API リファレンス](./docs/API_REFERENCE.md) | 全メソッド・モデル・例外の詳細仕様 | - -## トラブルシューティング +| `AuthenticationError` | API Key が無効・未設定 | +| `RateLimitError` | リクエスト制限超過 | +| `ValidationError` | パラメータ不正 | +| `NotFoundError` | リソースが見つからない | +| `TimeoutError` | ジョブのタイムアウト | +| `JobFailedError` | ジョブ実行の失敗 | +| `ConfigNotFoundError` | 指定した Config が存在しない | -### `AuthenticationError: Invalid API Key` +## 設定 -環境変数 `GENFLUX_API_KEY` に有効な API Key を設定してください。 - -```bash -export GENFLUX_API_KEY="your_api_key_here" -``` - -### `ModuleNotFoundError: No module named 'genflux'` +| 環境変数 | 説明 | デフォルト | +|---|---|---| +| `GENFLUX_API_KEY` | 認証用 API Key | *(必須)* | +| `GENFLUX_ENVIRONMENT` | `"local"` / `"dev"` / `"prod"` | `"prod"` | +| `GENFLUX_API_BASE_URL` | ベース URL の上書き(最優先) | — | -```bash -pip install genflux -``` +API Key は [Genflux Platform](https://www.platform.genflux.jp/) から発行してください。 ## サポート @@ -102,4 +274,4 @@ pip install genflux ## ライセンス -MIT License - 詳細は [LICENSE](LICENSE) を参照してください。 +MIT License — 詳細は [LICENSE](LICENSE) を参照してください。 diff --git a/assets/GENFLUX_logomark.png b/assets/GENFLUX_logomark.png new file mode 100644 index 0000000..f5eb269 Binary files /dev/null and b/assets/GENFLUX_logomark.png differ diff --git a/assets/GENFLUX_logotype.png b/assets/GENFLUX_logotype.png new file mode 100644 index 0000000..dc51449 Binary files /dev/null and b/assets/GENFLUX_logotype.png differ diff --git a/assets/GENFLUX_logotype_w.png b/assets/GENFLUX_logotype_w.png new file mode 100644 index 0000000..c854621 Binary files /dev/null and b/assets/GENFLUX_logotype_w.png differ diff --git a/assets/favicon.png b/assets/favicon.png new file mode 100644 index 0000000..fc285e9 Binary files /dev/null and b/assets/favicon.png differ diff --git a/docs/API_REFERENCE.md b/docs/API_REFERENCE.md index 0e83f36..24e025c 100644 --- a/docs/API_REFERENCE.md +++ b/docs/API_REFERENCE.md @@ -1,10 +1,10 @@ - + -# GenFlux Python SDK - API Reference +# Genflux Python SDK - API Reference -GenFlux Python SDK の完全な API リファレンスです。 +Genflux Python SDK の完全な API リファレンスです。 このドキュメントはソースコードの docstring・型ヒントから**自動生成**されています。 > ⚠️ **このファイルは自動生成物です。直接編集しないでください。** @@ -13,123 +13,108 @@ GenFlux Python SDK の完全な API リファレンスです。 --- -## 📋 目次 +## 目次 -- [機能全体像](#機能全体像) -- [GenFlux クライアント](#genflux-1) -- [ConfigClient](#configclient) -- [JobsClient](#jobsclient) -- [ReportsClient](#reportsclient) -- [EvaluationClient](#evaluationclient) -- [モデル](#モデル) -- [例外](#例外) -- [ユーティリティ](#ユーティリティ) +- [1. 概要](#1-概要) +- [2. クライアント](#2-クライアント) + - [2.1 GenFlux](#21-genflux) + - [2.2 ConfigClient](#22-configclient) + - [2.3 JobsClient](#23-jobsclient) + - [2.4 ReportsClient](#24-reportsclient) + - [2.5 EvaluationClient](#25-evaluationclient) +- [3. モデル](#3-モデル) +- [4. 例外](#4-例外) +- [5. ユーティリティ](#5-ユーティリティ) --- -## 機能全体像 - -GenFlux SDK は、RAG システムの評価を簡単に実行するための包括的な機能を提供します。 - -### アーキテクチャ概要 - -``` -┌─────────────────────────────────────────────────────────────┐ -│ GenFlux Client │ -│ (メインエントリーポイント) │ -└────────────────┬────────────────────────────────────────────┘ - │ - ┌──────────┼──────────┬──────────┬──────────┐ - │ │ │ │ │ - ▼ ▼ ▼ ▼ ▼ -┌──────────┐┌──────────┐┌──────────┐┌──────────┐┌──────────┐ -│ Config ││ Jobs ││ Reports ││Evaluation││ Progress │ -│ Client ││ Client ││ Client ││ Client ││ Display │ -└──────────┘└──────────┘└──────────┘└──────────┘└──────────┘ - │ │ │ │ │ - └───────────┴───────────┴───────────┴───────────┘ - │ - ▼ - ┌──────────────────┐ - │ Backend API │ - │ (Job Queue) │ - └──────────────────┘ -``` - -### 主要コンポーネント - -| コンポーネント | 説明 | -|---|---| -| **GenFlux Client** | メインエントリーポイント。認証管理・サブクライアント初期化 | -| **ConfigClient** | RAG API 設定の CRUD 管理 | -| **JobsClient** | 非同期ジョブの作成・監視・キャンセル | -| **EvaluationClient** | 12 種類のメトリックによる評価実行 | -| **ReportsClient** | 評価レポートの取得(サマリー/詳細) | - -### サポートされる評価メトリック - -| メトリック | 説明 | スコア範囲 | -|---|---|---| -| **Faithfulness** | 回答が提供された文脈に基づいているか | 0.0 ~ 1.0 (高↑) | -| **Answer Relevancy** | 回答が質問に対して適切に答えているか | 0.0 ~ 1.0 (高↑) | -| **Contextual Relevancy** | 取得された文脈が質問に関連しているか | 0.0 ~ 1.0 (高↑) | -| **Contextual Precision** | 関連性の高い文脈が上位にランクされているか | 0.0 ~ 1.0 (高↑) | -| **Contextual Recall** | 回答の情報が文脈に帰属できるか | 0.0 ~ 1.0 (高↑) | -| **Hallucination** | 回答が文脈にない情報を含んでいるか | 0.0 ~ 1.0 (低↓) | -| **Toxicity** | 回答に有害なコンテンツが含まれるか | 0.0 ~ 1.0 (低↓) | -| **Bias** | 回答に偏見が含まれるか | 0.0 ~ 1.0 (低↓) | - -### 典型的な使用パターン +## 1. 概要 ```python from genflux import GenFlux -# 1. クライアント初期化 -client = GenFlux(api_key="pk_xxx") +client = GenFlux() # GENFLUX_API_KEY 環境変数を使用 +evaluator = client.evaluation() -# 2. 評価実行(シンプル) -evaluator = client.evaluation(config_id="config_123") result = evaluator.faithfulness( question="What is Python?", answer="Python is a programming language.", contexts=["Python is a high-level programming language..."], ) print(f"Score: {result.score}") # 0.0 ~ 1.0 +``` + +### アーキテクチャ + +```mermaid +graph TB + User["Your Code"] --> GF["Genflux Client"] + + GF --> CC["client.configs
ConfigClient"] + GF --> JC["client.jobs
JobsClient"] + GF --> RC["client.reports
ReportsClient"] + GF --> EC["client.evaluation()
EvaluationClient"] -# 3. 複数メトリック -faith = evaluator.faithfulness(question, answer, contexts) -relevancy = evaluator.answer_relevancy(question, answer) -toxicity = evaluator.toxicity(question, answer) + CC --> API["Genflux Backend API"] + JC --> API + RC --> API + EC --> API -# 4. CI/CD 統合 -if result.score < 0.8: - sys.exit(1) # テスト失敗 + API --> Queue["Job Queue"] + Queue --> Result["MetricResult
score / reason"] + + style GF fill:#4A90D9,color:#fff + style EC fill:#7B68EE,color:#fff + style API fill:#2E8B57,color:#fff ``` +### クライアント構成 + +| クライアント | アクセス方法 | 説明 | +|---|---|---| +| [`GenFlux`](#genflux-1) | `GenFlux()` | メインクライアント(認証・サブクライアント管理) | +| [`EvaluationClient`](#evaluationclient) | `client.evaluation()` | 8 種類のメトリックによる評価実行 | +| [`ConfigClient`](#configclient) | `client.configs` | RAG API 設定の CRUD | +| [`JobsClient`](#jobsclient) | `client.jobs` | 非同期ジョブの作成・監視・キャンセル | +| [`ReportsClient`](#reportsclient) | `client.reports` | 評価レポートの取得(サマリー/詳細) | + +### 評価メトリック + +| メトリック | メソッド | `contexts` | `ground_truth` | スコア | +|---|---|---|---|---| +| Faithfulness | `evaluator.faithfulness()` | 必須 | — | 0〜1(高いほど良い) | +| Answer Relevancy | `evaluator.answer_relevancy()` | 任意 | — | 0〜1(高いほど良い) | +| Contextual Relevancy | `evaluator.contextual_relevancy()` | 必須 | — | 0〜1(高いほど良い) | +| Contextual Precision | `evaluator.contextual_precision()` | 必須 | — | 0〜1(高いほど良い) | +| Contextual Recall | `evaluator.contextual_recall()` | 必須 | 必須 | 0〜1(高いほど良い) | +| Hallucination | `evaluator.hallucination()` | 必須 | — | 0〜1(低いほど良い) | +| Toxicity | `evaluator.toxicity()` | 任意 | — | 0〜1(低いほど良い) | +| Bias | `evaluator.bias()` | 任意 | — | 0〜1(低いほど良い) | + --- -## クライアント +## 2. クライアント -### `GenFlux` +### 2.1 `GenFlux` -GenFlux API Client. +GenFlux APIクライアント。 #### 属性 | 属性 | 型 | 説明 | |---|---|---| -| `api_key` | `str | None` | (default: None) | -| `base_url` | `str | None` | (default: None) | -| `environment` | `str | None` | (default: None) | +| `api_key` | `str \| None` | (default: None) | +| `base_url` | `str \| None` | (default: None) | +| `environment` | `str \| None` | (default: None) | | `timeout` | `float` | (default: 60.0) | #### コンストラクタパラメータ -| パラメータ | 型 | 説明 | -|---|---|---| -| `api_key` | | API key for authentication. If not provided, uses GENFLUX_API_KEY env var. | -| `base_url` | | Base URL for the GenFlux API. If not provided, uses GENFLUX_API_BASE_URL env var or constructs from environment setting. | -| `environment` | | Environment name ("local", "dev", or "prod"). Uses GENFLUX_ENVIRONMENT env var if not provided. Defaults to "prod". | -| `timeout` | | Request timeout in seconds (default: 60) | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `api_key` | `str \| None` | No | API key for authentication. If not provided, uses GENFLUX_API_KEY env var. | +| `base_url` | `str \| None` | No | Base URL for the GenFlux API. If not provided, uses GENFLUX_API_BASE_URL env var or constructs from environment setting. | +| `environment` | `str \| None` | No | Environment name ("local", "dev", or "prod"). Uses GENFLUX_ENVIRONMENT env var if not provided. Defaults to "prod". | +| `timeout` | `float` | No | Request timeout in seconds (default: 60.0) | #### 使用例 @@ -150,13 +135,13 @@ client = GenFlux(api_key="dev_test_key", environment="local") #### `evaluation(config_id: str | None = None) -> EvaluationClient` -Create an evaluation client for the given config. +指定された設定で評価クライアントを作成します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `config_id` | | Config ID to use for evaluations (optional, uses default if not provided) | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `config_id` | `str \| None` | No | Config ID to use for evaluations (optional, uses default if not provided) | **戻り値:** EvaluationClient instance @@ -181,25 +166,23 @@ result = evaluator.faithfulness( ) ``` ---- - -### `ConfigClient` +### 2.2 `ConfigClient` *継承:* `BaseClient` -Client for managing evaluation configs. +評価設定管理用クライアント。 #### メソッド #### `create(config: ConfigCreate) -> Config` -Create a new config. +新しい設定を作成します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `config` | | Config creation parameters | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `config` | `ConfigCreate` | **Yes** | Config creation parameters | **戻り値:** Created config @@ -235,13 +218,13 @@ print(f"Created config: {config.id}") #### `delete(config_id: str | UUID) -> bool` -Delete config. +設定を削除します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `config_id` | | Config ID | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `config_id` | `str \| UUID` | **Yes** | Config ID | **戻り値:** True if deleted successfully @@ -261,13 +244,13 @@ print(f"Deleted: {success}") #### `get(config_id: str | UUID) -> Config` -Get config by ID. +IDで設定を取得します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `config_id` | | Config ID | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `config_id` | `str \| UUID` | **Yes** | Config ID | **戻り値:** Config object @@ -287,14 +270,14 @@ print(f"Config name: {config.name}") #### `list(limit: int = 100, offset: int = 0) -> ConfigListResponse` -List all configs. +すべての設定を一覧取得します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `limit` | | Maximum number of configs to return | -| `offset` | | Number of configs to skip | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `limit` | `int` | No | Maximum number of configs to return | +| `offset` | `int` | No | Number of configs to skip | **戻り値:** List of configs @@ -314,14 +297,14 @@ for config in configs.configs: #### `update(config_id: str | UUID, config_update: ConfigUpdate) -> Config` -Update config. +設定を更新します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `config_id` | | Config ID | -| `config_update` | | Config update parameters | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `config_id` | `str \| UUID` | **Yes** | Config ID | +| `config_update` | `ConfigUpdate` | **Yes** | Config update parameters | **戻り値:** Updated config @@ -346,23 +329,21 @@ updated_config = client.update( print(f"Updated: {updated_config.name}") ``` ---- - -### `JobsClient` +### 2.3 `JobsClient` -Client for Job (Execution) management. +ジョブ(実行)管理用クライアント。 #### メソッド #### `cancel(job_id: str) -> Job` -Cancel a running job. +実行中のジョブをキャンセルします。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `job_id` | | Job ID to cancel | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `job_id` | `str` | **Yes** | Job ID to cancel | **戻り値:** Cancelled Job object @@ -384,15 +365,15 @@ print(job.status) #### `create(execution_type: str, config_id: str | None = None, data: dict[str, Any] | None = None) -> Job` -Create a new job. +新しいジョブを作成します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `execution_type` | | Execution type (e.g., 'quick_evaluate', 'evaluation') | -| `config_id` | | Config ID (optional, uses default if not provided) | -| `data` | | Additional data for the job (for quick_evaluate) | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `execution_type` | `str` | **Yes** | Execution type (e.g., 'quick_evaluate', 'evaluation') | +| `config_id` | `str \| None` | No | Config ID (optional, uses default if not provided) | +| `data` | `dict[str, Any] \| None` | No | Additional data for the job (for quick_evaluate) | **戻り値:** Created Job object @@ -422,13 +403,13 @@ job = client.jobs.create( #### `get(job_id: str) -> Job` -Get job by ID. +IDでジョブを取得します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `job_id` | | Job ID | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `job_id` | `str` | **Yes** | Job ID | **戻り値:** Job object @@ -449,15 +430,15 @@ print(job.status) #### `list(status: str | None = None, execution_type: str | None = None, limit: int = 100) -> list[Job]` -List jobs. +ジョブ一覧を取得します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `status` | | Filter by status (e.g., 'completed', 'running', 'failed') | -| `execution_type` | | Filter by execution type (e.g., 'quick_evaluate', 'redteam_static', 'oss') | -| `limit` | | Maximum number of jobs to return (not yet implemented in backend) | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `status` | `str \| None` | No | Filter by status (e.g., 'completed', 'running', 'failed') | +| `execution_type` | `str \| None` | No | Filter by execution type (e.g., 'quick_evaluate', 'redteam_static', 'oss') | +| `limit` | `int` | No | Maximum number of jobs to return (not yet implemented in backend) | **戻り値:** List of Job objects @@ -482,16 +463,16 @@ redteam_jobs = client.jobs.list(execution_type="redteam_static") #### `wait(job_id: str, timeout: int = 600, poll_interval: float = 5.0, callback: Union[Callable[Job, None], None] = None) -> Job` -Wait for job completion. +ジョブの完了を待機します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `job_id` | | Job ID to wait for | -| `timeout` | | Maximum wait time in seconds (default: 600) | -| `poll_interval` | | Polling interval in seconds (default: 5.0) | -| `callback` | | Optional callback function called on each poll with Job object | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `job_id` | `str` | **Yes** | Job ID to wait for | +| `timeout` | `int` | No | Maximum wait time in seconds (default: 600) | +| `poll_interval` | `float` | No | Polling interval in seconds (default: 5.0) | +| `callback` | `Union[Callable[Job, None], None]` | No | Optional callback function called on each poll with Job object | **戻り値:** Completed Job object @@ -514,26 +495,24 @@ job = client.jobs.wait( ) ``` ---- - -### `ReportsClient` +### 2.4 `ReportsClient` *継承:* `BaseClient` -Client for Reports API. +レポートAPI用クライアント。 #### メソッド #### `get(report_id: str | UUID, view: Literal[summary, details] = "summary") -> Report` -Get a report by ID. +IDでレポートを取得します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `report_id` | | Report ID (= Job ID) | -| `view` | | View level - "summary": CI判定用の指標のみ - "details": 失敗ケース上位N件 + カテゴリ別集計 | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `report_id` | `str \| UUID` | **Yes** | Report ID (= Job ID) | +| `view` | `Literal[summary, details]` | No | View level - "summary": CI判定用の指標のみ - "details": 失敗ケース上位N件 + カテゴリ別集計 | **戻り値:** Report object @@ -564,29 +543,27 @@ for failed_case in report.details.failed_cases: print(f"Failed: {failed_case.reason}") ``` ---- - -### `EvaluationClient` +### 2.5 `EvaluationClient` -Client for evaluation operations. +評価操作用クライアント。 -Provides a synchronous-style interface for evaluations, -internally using Job-based async execution. +同期スタイルのインターフェースを提供し、 +内部的にJobベースの非同期実行を使用します。 #### メソッド #### `answer_relevancy(question: str, answer: str, contexts: list[str] | None = None, timeout: int = 300) -> MetricResult` -Evaluate answer relevancy (answer addresses the question). +回答の関連性を評価します(回答が質問に対応しているか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts (optional) | -| `timeout` | | Maximum wait time in seconds | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str] \| None` | No | Context/retrieval texts (optional) | +| `timeout` | `int` | No | Maximum wait time in seconds | **戻り値:** MetricResult with answer relevancy score @@ -603,16 +580,16 @@ result = evaluator.answer_relevancy( #### `bias(question: str, answer: str, contexts: list[str] | None = None, timeout: int = 300) -> MetricResult` -Evaluate bias (answer contains biased content). +バイアスを評価します(回答に偏りのあるコンテンツが含まれているか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts (optional) | -| `timeout` | | Maximum wait time in seconds | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str] \| None` | No | Context/retrieval texts (optional) | +| `timeout` | `int` | No | Maximum wait time in seconds | **戻り値:** MetricResult with bias score (lower is better) @@ -620,16 +597,16 @@ Evaluate bias (answer contains biased content). #### `contextual_precision(question: str, answer: str, contexts: list[str], timeout: int = 300) -> MetricResult` -Evaluate contextual precision (relevant contexts ranked higher). +コンテキストの精度を評価します(関連するコンテキストが上位にランクされているか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts (order matters) | -| `timeout` | | Maximum wait time in seconds | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str]` | **Yes** | Context/retrieval texts (order matters) | +| `timeout` | `int` | No | Maximum wait time in seconds | **戻り値:** MetricResult with contextual precision score @@ -637,17 +614,17 @@ Evaluate contextual precision (relevant contexts ranked higher). #### `contextual_recall(question: str, answer: str, contexts: list[str], ground_truth: str, timeout: int = 300) -> MetricResult` -Evaluate contextual recall (answer can be attributed to contexts). +コンテキストの再現率を評価します(回答がコンテキストに帰属できるか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts | -| `ground_truth` | | Ground truth answer (required for contextual_recall) | -| `timeout` | | Maximum wait time in seconds | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str]` | **Yes** | Context/retrieval texts | +| `ground_truth` | `str` | **Yes** | Ground truth answer (required for contextual_recall) | +| `timeout` | `int` | No | Maximum wait time in seconds | **戻り値:** MetricResult with contextual recall score @@ -655,16 +632,16 @@ Evaluate contextual recall (answer can be attributed to contexts). #### `contextual_relevancy(question: str, answer: str, contexts: list[str], timeout: int = 300) -> MetricResult` -Evaluate contextual relevancy (contexts are relevant to question). +コンテキストの関連性を評価します(コンテキストが質問に関連しているか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts | -| `timeout` | | Maximum wait time in seconds | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str]` | **Yes** | Context/retrieval texts | +| `timeout` | `int` | No | Maximum wait time in seconds | **戻り値:** MetricResult with contextual relevancy score @@ -682,23 +659,23 @@ result = evaluator.contextual_relevancy( #### `evaluate(metric: str, question: str, answer: str, contexts: list[str] | None = None, ground_truth: str | None = None, timeout: int = 300, callback: Union[Callable[Job, None], None] = None, show_progress: bool = True) -> MetricResult` -Evaluate a single question-answer pair. +単一の質問-回答ペアを評価します。 -This method provides a synchronous-style API that internally -creates a job, waits for completion, and returns the result. +このメソッドは内部的にジョブを作成し、完了を待機して結果を返す +同期スタイルのAPIを提供します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `metric` | | Metric name (e.g., 'faithfulness', 'answer_relevancy') | -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts (optional) | -| `ground_truth` | | Ground truth answer (required for contextual_recall) | -| `timeout` | | Maximum wait time in seconds (default: 300) | -| `callback` | | Optional progress callback (overrides show_progress) | -| `show_progress` | | Show progress bar (default: True, ignored if callback is provided) | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `metric` | `str` | **Yes** | Metric name to evaluate. Valid values - 'faithfulness', 'answer_relevancy', 'context_relevancy', 'llm_context_precision', 'context_recall', 'hallucination', 'toxicity', 'bias'. (メソッド名と内部メトリック名の対応: contextual_relevancy() → 'context_relevancy', contextual_precision() → 'llm_context_precision', contextual_recall() → 'context_recall') | +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str] \| None` | No | Context/retrieval texts (optional) | +| `ground_truth` | `str \| None` | No | Ground truth answer (required for contextual_recall) | +| `timeout` | `int` | No | Maximum wait time in seconds (default: 300) | +| `callback` | `Union[Callable[Job, None], None]` | No | Optional progress callback (overrides show_progress) | +| `show_progress` | `bool` | No | Show progress bar (default: True, ignored if callback is provided) | **戻り値:** MetricResult with score and reason @@ -727,17 +704,17 @@ print(f"Score: {result.score}, Reason: {result.reason}") #### `faithfulness(question: str, answer: str, contexts: list[str], timeout: int = 300, on_progress: Union[Callable[Job, None], None] = None) -> MetricResult` -Evaluate faithfulness (answers based on contexts). +忠実性を評価します(回答がコンテキストに基づいているか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts | -| `timeout` | | Maximum wait time in seconds | -| `on_progress` | | Optional progress callback | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str]` | **Yes** | Context/retrieval texts | +| `timeout` | `int` | No | Maximum wait time in seconds | +| `on_progress` | `Union[Callable[Job, None], None]` | No | Optional progress callback | **戻り値:** MetricResult with faithfulness score @@ -755,16 +732,16 @@ result = evaluator.faithfulness( #### `hallucination(question: str, answer: str, contexts: list[str], timeout: int = 300) -> MetricResult` -Evaluate hallucination (answer contains information not in contexts). +ハルシネーションを評価します(回答にコンテキストにない情報が含まれているか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts | -| `timeout` | | Maximum wait time in seconds | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str]` | **Yes** | Context/retrieval texts | +| `timeout` | `int` | No | Maximum wait time in seconds | **戻り値:** MetricResult with hallucination score (lower is better) @@ -772,30 +749,28 @@ Evaluate hallucination (answer contains information not in contexts). #### `toxicity(question: str, answer: str, contexts: list[str] | None = None, timeout: int = 300) -> MetricResult` -Evaluate toxicity (answer contains toxic content). +有害性を評価します(回答に有害なコンテンツが含まれているか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts (optional) | -| `timeout` | | Maximum wait time in seconds | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str] \| None` | No | Context/retrieval texts (optional) | +| `timeout` | `int` | No | Maximum wait time in seconds | **戻り値:** MetricResult with toxicity score (lower is better) --- ---- - -## モデル +## 3. モデル -### `Config` +### 3.1 `Config` *継承:* `BaseModel` -Complete config object. +完全な設定オブジェクト。 #### 属性 @@ -805,80 +780,80 @@ Complete config object. | `tenant_id` | `UUID` | | | `user_id` | `UUID` | | | `name` | `str` | | -| `description` | `str | None` | | +| `description` | `str \| None` | | | `locale` | `str` | | -| `api_settings` | `ApiSettings | None` | | -| `rag_quality_config` | `RagQualityConfig | None` | | -| `redteam_config` | `RedteamConfig | None` | | -| `policy_check_config` | `PolicyCheckConfig | None` | | +| `api_settings` | `ApiSettings \| None` | | +| `rag_quality_config` | `RagQualityConfig \| None` | | +| `redteam_config` | `RedteamConfig \| None` | | +| `policy_check_config` | `PolicyCheckConfig \| None` | | | `created_at` | `datetime` | | | `updated_at` | `datetime` | | -### `ConfigCreate` +### 3.2 `ConfigCreate` *継承:* `BaseModel` -Request model for creating a config. +設定作成用のリクエストモデル。 #### 属性 | 属性 | 型 | 説明 | |---|---|---| | `name` | `str` | Config name | -| `description` | `str | None` | Config description | +| `description` | `str \| None` | Config description | | `locale` | `str` | Locale (ja/en) | | `api_endpoint` | `str` | API endpoint URL | | `auth_type` | `str` | Authentication type | -| `auth_header` | `str | None` | Auth header name | -| `auth_token` | `str | None` | Auth token | -| `request_format` | `dict[str, Any] | None` | Request format | -| `response_format` | `dict[str, Any] | None` | Response format | -| `evaluation_metrics` | `dict[str, Any] | None` | Evaluation metrics | -| `total_prompt_count` | `int | None` | Total prompt count | -| `prompt_category_ratios` | `dict[str, Any] | None` | Category ratios | -| `manual_prompts` | `list[str] | None` | Manual prompts | -| `evaluation_success_rate_threshold` | `float | None` | Success rate threshold (%) | -| `redteam_objectives` | `list[str] | None` | RedTeam objectives | -| `redteam_max_turns` | `int | None` | Max turns | -| `redteam_defense_rate_threshold` | `float | None` | Defense rate threshold (%) | -| `compliance_frameworks` | `list[str] | None` | Compliance frameworks | -| `policy_compliance_rate_threshold` | `float | None` | Compliance rate threshold (%) | - -### `ConfigUpdate` +| `auth_header` | `str \| None` | Auth header name | +| `auth_token` | `str \| None` | Auth token | +| `request_format` | `dict[str, Any] \| None` | Request format | +| `response_format` | `dict[str, Any] \| None` | Response format | +| `evaluation_metrics` | `dict[str, Any] \| None` | Evaluation metrics | +| `total_prompt_count` | `int \| None` | Total prompt count | +| `prompt_category_ratios` | `dict[str, Any] \| None` | Category ratios | +| `manual_prompts` | `list[str] \| None` | Manual prompts | +| `evaluation_success_rate_threshold` | `float \| None` | Success rate threshold (%) | +| `redteam_objectives` | `list[str] \| None` | RedTeam objectives | +| `redteam_max_turns` | `int \| None` | Max turns | +| `redteam_defense_rate_threshold` | `float \| None` | Defense rate threshold (%) | +| `compliance_frameworks` | `list[str] \| None` | Compliance frameworks | +| `policy_compliance_rate_threshold` | `float \| None` | Compliance rate threshold (%) | + +### 3.3 `ConfigUpdate` *継承:* `BaseModel` -Request model for updating a config. +設定更新用のリクエストモデル。 #### 属性 | 属性 | 型 | 説明 | |---|---|---| -| `name` | `str | None` | | -| `description` | `str | None` | | -| `locale` | `str | None` | | -| `api_endpoint` | `str | None` | | -| `auth_type` | `str | None` | | -| `auth_header` | `str | None` | | -| `auth_token` | `str | None` | | -| `request_format` | `dict[str, Any] | None` | | -| `response_format` | `dict[str, Any] | None` | | -| `evaluation_metrics` | `dict[str, Any] | None` | | -| `total_prompt_count` | `int | None` | | -| `prompt_category_ratios` | `dict[str, Any] | None` | | -| `manual_prompts` | `list[str] | None` | | -| `evaluation_success_rate_threshold` | `float | None` | | -| `redteam_objectives` | `list[str] | None` | | -| `redteam_max_turns` | `int | None` | | -| `redteam_defense_rate_threshold` | `float | None` | | -| `compliance_frameworks` | `list[str] | None` | | -| `policy_compliance_rate_threshold` | `float | None` | | - -### `ConfigListResponse` +| `name` | `str \| None` | | +| `description` | `str \| None` | | +| `locale` | `str \| None` | | +| `api_endpoint` | `str \| None` | | +| `auth_type` | `str \| None` | | +| `auth_header` | `str \| None` | | +| `auth_token` | `str \| None` | | +| `request_format` | `dict[str, Any] \| None` | | +| `response_format` | `dict[str, Any] \| None` | | +| `evaluation_metrics` | `dict[str, Any] \| None` | | +| `total_prompt_count` | `int \| None` | | +| `prompt_category_ratios` | `dict[str, Any] \| None` | | +| `manual_prompts` | `list[str] \| None` | | +| `evaluation_success_rate_threshold` | `float \| None` | | +| `redteam_objectives` | `list[str] \| None` | | +| `redteam_max_turns` | `int \| None` | | +| `redteam_defense_rate_threshold` | `float \| None` | | +| `compliance_frameworks` | `list[str] \| None` | | +| `policy_compliance_rate_threshold` | `float \| None` | | + +### 3.4 `ConfigListResponse` *継承:* `BaseModel` -Response model for listing configs. +設定一覧取得用のレスポンスモデル。 #### 属性 @@ -887,11 +862,11 @@ Response model for listing configs. | `configs` | `list[Config]` | | | `total` | `int` | | -### `ApiSettings` +### 3.5 `ApiSettings` *継承:* `BaseModel` -API settings configuration. +API設定。 #### 属性 @@ -899,57 +874,57 @@ API settings configuration. |---|---|---| | `api_endpoint` | `str` | | | `auth_type` | `str` | | -| `auth_header` | `str | None` | | -| `auth_token` | `str | None` | | -| `request_format` | `dict[str, Any] | None` | | -| `response_format` | `dict[str, Any] | None` | | +| `auth_header` | `str \| None` | | +| `auth_token` | `str \| None` | | +| `request_format` | `dict[str, Any] \| None` | | +| `response_format` | `dict[str, Any] \| None` | | -### `RagQualityConfig` +### 3.6 `RagQualityConfig` *継承:* `BaseModel` -RAG Quality evaluation configuration. +RAG品質評価の設定。 #### 属性 | 属性 | 型 | 説明 | |---|---|---| | `evaluation_metrics` | `dict[str, Any]` | | -| `total_prompt_count` | `int | None` | | -| `prompt_category_ratios` | `dict[str, Any] | None` | | -| `manual_prompts` | `list[str] | None` | | -| `evaluation_success_rate_threshold` | `float | None` | | +| `total_prompt_count` | `int \| None` | | +| `prompt_category_ratios` | `dict[str, Any] \| None` | | +| `manual_prompts` | `list[str] \| None` | | +| `evaluation_success_rate_threshold` | `float \| None` | | -### `RedteamConfig` +### 3.7 `RedteamConfig` *継承:* `BaseModel` -RedTeam evaluation configuration. +RedTeam評価の設定。 #### 属性 | 属性 | 型 | 説明 | |---|---|---| -| `redteam_objectives` | `list[str] | None` | | -| `redteam_max_turns` | `int | None` | | -| `redteam_defense_rate_threshold` | `float | None` | | +| `redteam_objectives` | `list[str] \| None` | | +| `redteam_max_turns` | `int \| None` | | +| `redteam_defense_rate_threshold` | `float \| None` | | -### `PolicyCheckConfig` +### 3.8 `PolicyCheckConfig` *継承:* `BaseModel` -Policy check configuration. +ポリシーチェックの設定。 #### 属性 | 属性 | 型 | 説明 | |---|---|---| -| `compliance_frameworks` | `list[str] | None` | | -| `policy_compliance_rate_threshold` | `float | None` | | +| `compliance_frameworks` | `list[str] \| None` | | +| `policy_compliance_rate_threshold` | `float \| None` | | -### `Job` +### 3.9 `Job` -Job (Execution) model. +ジョブ(実行)モデル。 #### 属性 @@ -961,28 +936,29 @@ Job (Execution) model. | `config_id` | `str` | | | `execution_type` | `str` | | | `status` | `str` | | -| `current_step` | `str | None` | | +| `current_step` | `str \| None` | | | `progress_count` | `int` | | | `total_count` | `int` | | -| `progress` | `JobProgress | None` | | -| `results` | `dict[str, Any] | None` | | -| `error_message` | `str | None` | | -| `started_at` | `datetime | None` | | -| `completed_at` | `datetime | None` | | -| `created_at` | `datetime | None` | | -| `updated_at` | `datetime | None` | | +| `progress` | `JobProgress \| None` | | +| `results` | `dict[str, Any] \| None` | | +| `error_message` | `str \| None` | | +| `started_at` | `datetime \| None` | | +| `completed_at` | `datetime \| None` | | +| `created_at` | `datetime \| None` | | +| `updated_at` | `datetime \| None` | | #### メソッド #### *classmethod* `from_dict(cls, data: dict[str, Any]) -> Job` -Create Job from API response dict. +APIレスポンスの辞書からJobを作成します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `data` | | API response dictionary | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `cls` | | **Yes** | | +| `data` | `dict[str, Any]` | **Yes** | API response dictionary | **戻り値:** Job instance @@ -990,31 +966,29 @@ Create Job from API response dict. #### *property* `is_completed` -Check if job is completed. +ジョブが完了したかどうかを確認します。 --- #### *property* `is_failed` -Check if job failed. +ジョブが失敗したかどうかを確認します。 --- #### *property* `is_pending` -Check if job is pending (queued or pending). +ジョブが待機中(キュー待ちまたはペンディング)かどうかを確認します。 --- #### *property* `is_running` -Check if job is running. +ジョブが実行中かどうかを確認します。 ---- - -### `JobProgress` +### 3.10 `JobProgress` -Job progress information. +ジョブの進捗情報。 #### 属性 @@ -1023,9 +997,9 @@ Job progress information. | `percentage` | `float` | | | `message` | `str` | | -### `MetricResult` +### 3.11 `MetricResult` -Single metric evaluation result. +単一メトリックの評価結果。 #### 属性 @@ -1033,15 +1007,15 @@ Single metric evaluation result. |---|---|---| | `metric` | `str` | | | `score` | `float` | | -| `reason` | `str | None` | | +| `reason` | `str \| None` | | | `engine` | `str` | | -| `execution_time_seconds` | `float | None` | (default: None) | +| `execution_time_seconds` | `float \| None` | (default: None) | -### `Report` +### 3.12 `Report` *継承:* `BaseModel` -Report model. +レポートモデル。 #### 属性 @@ -1049,14 +1023,14 @@ Report model. |---|---|---| | `report_id` | `UUID` | | | `job_id` | `UUID` | | -| `config_id` | `UUID | None` | | +| `config_id` | `UUID \| None` | | | `type` | `str` | | | `status` | `Literal[completed, partial]` | | | `created_at` | `datetime` | | | `summary` | `ReportSummary` | | -| `details` | `ReportDetails | None` | | +| `details` | `ReportDetails \| None` | | -### `ReportSummary` +### 3.13 `ReportSummary` *継承:* `BaseModel` @@ -1066,11 +1040,11 @@ Report model. | 属性 | 型 | 説明 | |---|---|---| -| `evaluation` | `EvaluationSummary | None` | | -| `redteam` | `RedTeamSummary | None` | | -| `policy` | `PolicySummary | None` | | +| `evaluation` | `EvaluationSummary \| None` | | +| `redteam` | `RedTeamSummary \| None` | | +| `policy` | `PolicySummary \| None` | | -### `ReportDetails` +### 3.14 `ReportDetails` *継承:* `BaseModel` @@ -1084,7 +1058,7 @@ Report model. | `top_violations` | `list[Violation]` | 重大違反(上位) | | `recommendations` | `list[str]` | 改善推奨事項 | -### `EvaluationSummary` +### 3.15 `EvaluationSummary` *継承:* `BaseModel` @@ -1100,7 +1074,7 @@ Report model. | `failed` | `int` | | | `category_breakdown` | `list[CategoryBreakdown]` | | -### `RedTeamSummary` +### 3.16 `RedTeamSummary` *継承:* `BaseModel` @@ -1116,7 +1090,7 @@ RedTeamサマリ | `successful_attacks` | `int` | | | `category_breakdown` | `list[CategoryBreakdown]` | | -### `PolicySummary` +### 3.17 `PolicySummary` *継承:* `BaseModel` @@ -1131,7 +1105,7 @@ RedTeamサマリ | `violations_count` | `int` | | | `framework_breakdown` | `list[CategoryBreakdown]` | | -### `CategoryBreakdown` +### 3.18 `CategoryBreakdown` *継承:* `BaseModel` @@ -1142,12 +1116,12 @@ RedTeamサマリ | 属性 | 型 | 説明 | |---|---|---| | `category` | `str` | | -| `success_rate` | `float | None` | | -| `compliance_rate` | `float | None` | | +| `success_rate` | `float \| None` | | +| `compliance_rate` | `float \| None` | | | `count` | `int` | | -| `violations` | `int | None` | | +| `violations` | `int \| None` | | -### `FailedCase` +### 3.19 `FailedCase` *継承:* `BaseModel` @@ -1159,13 +1133,13 @@ RedTeamサマリ |---|---|---| | `case_id` | `str` | | | `input` | `str` | 入力(PIIマスキング済み) | -| `expected` | `str | None` | 期待値 | +| `expected` | `str \| None` | 期待値 | | `actual` | `str` | 実際の出力(PIIマスキング済み) | | `reason` | `str` | | | `category` | `str` | | | `severity` | `Literal[low, medium, high, critical]` | | -### `Violation` +### 3.20 `Violation` *継承:* `BaseModel` @@ -1183,75 +1157,69 @@ RedTeamサマリ --- -## 例外 - -### `GenFluxError` - -*継承:* `Exception` - -Base exception for GenFlux SDK. - -### `APIError` - -*継承:* `GenFluxError` - -API request failed. - -### `AuthenticationError` - -*継承:* `APIError` - -Authentication failed (401). - -### `NotFoundError` - -*継承:* `APIError` - -Resource not found (404). +## 4. 例外 -### `ValidationError` +すべての例外は `GenFluxError` を基底クラスとしています。 -*継承:* `APIError` +### 4.1 例外一覧 -Validation error (422). +| 例外 | 継承元 | HTTP ステータス | 説明 | +|---|---|---|---| +| `GenFluxError` | `Exception` | — | 基底例外クラス | +| `APIError` | `GenFluxError` | — | API リクエスト失敗(基底) | +| `AuthenticationError` | `APIError` | 401 | API Key が無効または未設定 | +| `NotFoundError` | `APIError` | 404 | リソースが見つからない | +| `ValidationError` | `APIError` | 400, 422 | リクエストパラメータが不正 | +| `RateLimitError` | `APIError` | 429 | レート制限超過 | +| `TimeoutError` | `GenFluxError` | — | ジョブのタイムアウト | +| `JobFailedError` | `GenFluxError` | — | ジョブ実行の失敗 | +| `ConfigNotFoundError` | `GenFluxError` | — | 指定した Config が存在しない | +| `ResourceNotFoundError` | `GenFluxError` | — | リソースが見つからない | -### `TimeoutError` +> **Note:** `APIError` 系は HTTP レスポンスに起因する例外です。`status_code` 属性でステータスコードを取得できます。 +> `TimeoutError` / `JobFailedError` はジョブ実行に起因する例外で、HTTP ステータスコードはありません。 -*継承:* `GenFluxError` +### 4.2 例外ハンドリング -Operation timed out. - -### `JobFailedError` - -*継承:* `GenFluxError` - -Job execution failed. - -### `RateLimitError` - -*継承:* `APIError` - -Rate limit exceeded (429). - -### `ConfigNotFoundError` - -*継承:* `GenFluxError` - -Config not found. - -### `ResourceNotFoundError` +```python +from genflux import GenFlux +from genflux.exceptions import ( + AuthenticationError, + RateLimitError, + TimeoutError, + JobFailedError, +) -*継承:* `GenFluxError` +client = GenFlux() +evaluator = client.evaluation() -Generic resource not found error. +try: + result = evaluator.faithfulness( + question="What is Python?", + answer="Python is a programming language.", + contexts=["Python is a high-level programming language."], + ) +except AuthenticationError: + # API Key が無効または未設定 + pass +except RateLimitError as e: + # レート制限。e.retry_after 秒後にリトライ + pass +except TimeoutError: + # ジョブがタイムアウト + pass +except JobFailedError as e: + # ジョブ実行失敗。e.error_message で詳細を確認 + pass +``` --- -## ユーティリティ +## 5. ユーティリティ -### `ProgressBar` +### 5.1 `ProgressBar` -Simple progress bar for terminal output. +ターミナル出力用のシンプルなプログレスバー。 #### 属性 @@ -1270,39 +1238,37 @@ Simple progress bar for terminal output. #### `update(current: int, message: str | None = None, indeterminate: bool = False) -> None` -Update progress bar. +プログレスバーを更新します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `current` | | Current progress value (0 to total) | -| `message` | | Optional status message | -| `indeterminate` | | When True, show "Processing..." instead of percentage (for single-metric or initial state) | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `current` | `int` | **Yes** | Current progress value (0 to total) | +| `message` | `str \| None` | No | Optional status message | +| `indeterminate` | `bool` | No | When True, show "Processing..." instead of percentage (for single-metric or initial state) | --- #### `update_from_job(job: Job) -> None` -Update progress bar from Job object. +Jobオブジェクトからプログレスバーを更新します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `job` | | Job object with progress information | - ---- +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `job` | `Job` | **Yes** | Job object with progress information | -### `create_progress_callback(enable: bool = True) -> Callable[Job, None]` +### 5.2 `create_progress_callback(enable: bool = True) -> Callable[Job, None]` -Create a progress callback for job.wait(). +job.wait()用のプログレスコールバックを作成します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `enable` | | Whether to enable progress display (default: True) | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `enable` | | **Yes** | Whether to enable progress display (default: True) | **戻り値:** Callback function for job.wait() @@ -1330,4 +1296,6 @@ result = client.jobs.wait(job.id, callback=callback) --- -*Auto-generated at 2026-03-12 00:24 UTC by `scripts/generate_api_reference.py`* +*Auto-generated at 2026-03-23 07:15 UTC by `scripts/generate_api_reference.py`* + + diff --git a/docs/DEVELOPER_API_REFERENCE.md b/docs/DEVELOPER_API_REFERENCE.md index 5508304..c768a42 100644 --- a/docs/DEVELOPER_API_REFERENCE.md +++ b/docs/DEVELOPER_API_REFERENCE.md @@ -1,8 +1,8 @@ - + -# GenFlux Python SDK - Developer API Reference +# Genflux Python SDK - Developer API Reference 開発者向けの詳細な API リファレンスです。 内部クラス・プライベートメソッドも含みます。 @@ -13,7 +13,7 @@ ## 📋 目次 -- [GenFlux クライアント](#genflux-1) +- [Genflux クライアント](#genflux-1) - [BaseClient(内部)](#baseclient) - [ConfigClient](#configclient) - [JobsClient](#jobsclient) @@ -28,25 +28,25 @@ ### `GenFlux` -GenFlux API Client. +GenFlux APIクライアント。 #### 属性 | 属性 | 型 | 説明 | |---|---|---| -| `api_key` | `str | None` | (default: None) | -| `base_url` | `str | None` | (default: None) | -| `environment` | `str | None` | (default: None) | +| `api_key` | `str \| None` | (default: None) | +| `base_url` | `str \| None` | (default: None) | +| `environment` | `str \| None` | (default: None) | | `timeout` | `float` | (default: 60.0) | #### コンストラクタパラメータ -| パラメータ | 型 | 説明 | -|---|---|---| -| `api_key` | | API key for authentication. If not provided, uses GENFLUX_API_KEY env var. | -| `base_url` | | Base URL for the GenFlux API. If not provided, uses GENFLUX_API_BASE_URL env var or constructs from environment setting. | -| `environment` | | Environment name ("local", "dev", or "prod"). Uses GENFLUX_ENVIRONMENT env var if not provided. Defaults to "prod". | -| `timeout` | | Request timeout in seconds (default: 60) | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `api_key` | `str \| None` | No | API key for authentication. If not provided, uses GENFLUX_API_KEY env var. | +| `base_url` | `str \| None` | No | Base URL for the GenFlux API. If not provided, uses GENFLUX_API_BASE_URL env var or constructs from environment setting. | +| `environment` | `str \| None` | No | Environment name ("local", "dev", or "prod"). Uses GENFLUX_ENVIRONMENT env var if not provided. Defaults to "prod". | +| `timeout` | `float` | No | Request timeout in seconds (default: 60.0) | #### 使用例 @@ -67,13 +67,13 @@ client = GenFlux(api_key="dev_test_key", environment="local") #### `_delete(path: str) -> None` -Send DELETE request to API. +APIにDELETEリクエストを送信します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API endpoint path | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API endpoint path | **例外:** @@ -83,13 +83,13 @@ Send DELETE request to API. #### `_get(path: str) -> dict[str, Any]` -Send GET request to API. +APIにGETリクエストを送信します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API endpoint path | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API endpoint path | **戻り値:** Response data @@ -101,7 +101,7 @@ Send GET request to API. #### `_get_headers() -> dict[str, str]` -Get HTTP headers for API requests. +APIリクエスト用のHTTPヘッダーを取得します。 **戻り値:** Dictionary of headers @@ -109,13 +109,13 @@ Get HTTP headers for API requests. #### `_handle_http_error(error: HTTPStatusError) -> None` -Handle HTTP errors and raise appropriate exceptions. +HTTPエラーを処理し、適切な例外を発生させます。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `error` | | HTTP status error | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `error` | `HTTPStatusError` | **Yes** | HTTP status error | **例外:** @@ -129,14 +129,14 @@ Handle HTTP errors and raise appropriate exceptions. #### `_post(path: str, data: dict[str, Any]) -> dict[str, Any]` -Send POST request to API. +APIにPOSTリクエストを送信します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API endpoint path | -| `data` | | Request body data | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API endpoint path | +| `data` | `dict[str, Any]` | **Yes** | Request body data | **戻り値:** Response data @@ -148,14 +148,14 @@ Send POST request to API. #### `_put(path: str, data: dict[str, Any]) -> dict[str, Any]` -Send PUT request to API. +APIにPUTリクエストを送信します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API endpoint path | -| `data` | | Request body data | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API endpoint path | +| `data` | `dict[str, Any]` | **Yes** | Request body data | **戻り値:** Response data @@ -167,13 +167,13 @@ Send PUT request to API. #### `evaluation(config_id: str | None = None) -> EvaluationClient` -Create an evaluation client for the given config. +指定された設定で評価クライアントを作成します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `config_id` | | Config ID to use for evaluations (optional, uses default if not provided) | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `config_id` | `str \| None` | No | Config ID to use for evaluations (optional, uses default if not provided) | **戻り値:** EvaluationClient instance @@ -198,23 +198,21 @@ result = evaluator.faithfulness( ) ``` ---- - ### `BaseClient` -Base HTTP client for GenFlux API. +GenFlux API用の基底HTTPクライアント。 #### メソッド #### `_build_url(path: str) -> str` -Build full URL from path. +パスから完全なURLを構築します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API path (e.g., "/configs") | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API path (e.g., "/configs") | **戻り値:** Full URL @@ -222,7 +220,7 @@ Build full URL from path. #### `_get_headers() -> dict[str, str]` -Get request headers with authentication. +認証付きのリクエストヘッダーを取得します。 **戻り値:** Request headers @@ -230,13 +228,13 @@ Get request headers with authentication. #### `_handle_error(response: Response) -> None` -Handle API error responses. +APIエラーレスポンスを処理します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `response` | | HTTP response | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `response` | `Response` | **Yes** | HTTP response | **例外:** @@ -250,19 +248,20 @@ Handle API error responses. #### `close()` -Close HTTP client. +HTTPクライアントを閉じます。 --- #### `delete(path: str, kwargs: Any) -> dict[str, Any] | None` -Send DELETE request. +DELETEリクエストを送信します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API path **kwargs: Additional request parameters | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API path **kwargs: Additional request parameters | +| `kwargs` | `Any` | **Yes** | | **戻り値:** Response data (if any) @@ -274,13 +273,14 @@ Send DELETE request. #### `get(path: str, kwargs: Any) -> dict[str, Any]` -Send GET request. +GETリクエストを送信します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API path **kwargs: Additional request parameters | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API path **kwargs: Additional request parameters | +| `kwargs` | `Any` | **Yes** | | **戻り値:** Response data @@ -292,14 +292,15 @@ Send GET request. #### `post(path: str, json: dict[str, Any] | None = None, kwargs: Any) -> dict[str, Any]` -Send POST request. +POSTリクエストを送信します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API path | -| `json` | | Request body (JSON) **kwargs: Additional request parameters | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API path | +| `json` | `dict[str, Any] \| None` | No | Request body (JSON) **kwargs: Additional request parameters | +| `kwargs` | `Any` | **Yes** | | **戻り値:** Response data @@ -311,14 +312,15 @@ Send POST request. #### `put(path: str, json: dict[str, Any] | None = None, kwargs: Any) -> dict[str, Any]` -Send PUT request. +PUTリクエストを送信します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API path | -| `json` | | Request body (JSON) **kwargs: Additional request parameters | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API path | +| `json` | `dict[str, Any] \| None` | No | Request body (JSON) **kwargs: Additional request parameters | +| `kwargs` | `Any` | **Yes** | | **戻り値:** Response data @@ -326,25 +328,23 @@ Send PUT request. - `APIError`: If request failed ---- - ### `ConfigClient` *継承:* `BaseClient` -Client for managing evaluation configs. +評価設定管理用クライアント。 #### メソッド #### `_build_url(path: str) -> str` -Build full URL from path. +パスから完全なURLを構築します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API path (e.g., "/configs") | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API path (e.g., "/configs") | **戻り値:** Full URL @@ -352,7 +352,7 @@ Build full URL from path. #### `_get_headers() -> dict[str, str]` -Get request headers with authentication. +認証付きのリクエストヘッダーを取得します。 **戻り値:** Request headers @@ -360,13 +360,13 @@ Get request headers with authentication. #### `_handle_error(response: Response) -> None` -Handle API error responses. +APIエラーレスポンスを処理します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `response` | | HTTP response | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `response` | `Response` | **Yes** | HTTP response | **例外:** @@ -380,19 +380,19 @@ Handle API error responses. #### `close()` -Close HTTP client. +HTTPクライアントを閉じます。 --- #### `create(config: ConfigCreate) -> Config` -Create a new config. +新しい設定を作成します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `config` | | Config creation parameters | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `config` | `ConfigCreate` | **Yes** | Config creation parameters | **戻り値:** Created config @@ -428,13 +428,13 @@ print(f"Created config: {config.id}") #### `delete(config_id: str | UUID) -> bool` -Delete config. +設定を削除します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `config_id` | | Config ID | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `config_id` | `str \| UUID` | **Yes** | Config ID | **戻り値:** True if deleted successfully @@ -454,13 +454,13 @@ print(f"Deleted: {success}") #### `get(config_id: str | UUID) -> Config` -Get config by ID. +IDで設定を取得します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `config_id` | | Config ID | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `config_id` | `str \| UUID` | **Yes** | Config ID | **戻り値:** Config object @@ -480,14 +480,14 @@ print(f"Config name: {config.name}") #### `list(limit: int = 100, offset: int = 0) -> ConfigListResponse` -List all configs. +すべての設定を一覧取得します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `limit` | | Maximum number of configs to return | -| `offset` | | Number of configs to skip | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `limit` | `int` | No | Maximum number of configs to return | +| `offset` | `int` | No | Number of configs to skip | **戻り値:** List of configs @@ -507,14 +507,15 @@ for config in configs.configs: #### `post(path: str, json: dict[str, Any] | None = None, kwargs: Any) -> dict[str, Any]` -Send POST request. +POSTリクエストを送信します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API path | -| `json` | | Request body (JSON) **kwargs: Additional request parameters | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API path | +| `json` | `dict[str, Any] \| None` | No | Request body (JSON) **kwargs: Additional request parameters | +| `kwargs` | `Any` | **Yes** | | **戻り値:** Response data @@ -526,14 +527,15 @@ Send POST request. #### `put(path: str, json: dict[str, Any] | None = None, kwargs: Any) -> dict[str, Any]` -Send PUT request. +PUTリクエストを送信します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API path | -| `json` | | Request body (JSON) **kwargs: Additional request parameters | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API path | +| `json` | `dict[str, Any] \| None` | No | Request body (JSON) **kwargs: Additional request parameters | +| `kwargs` | `Any` | **Yes** | | **戻り値:** Response data @@ -545,14 +547,14 @@ Send PUT request. #### `update(config_id: str | UUID, config_update: ConfigUpdate) -> Config` -Update config. +設定を更新します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `config_id` | | Config ID | -| `config_update` | | Config update parameters | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `config_id` | `str \| UUID` | **Yes** | Config ID | +| `config_update` | `ConfigUpdate` | **Yes** | Config update parameters | **戻り値:** Updated config @@ -577,23 +579,21 @@ updated_config = client.update( print(f"Updated: {updated_config.name}") ``` ---- - ### `JobsClient` -Client for Job (Execution) management. +ジョブ(実行)管理用クライアント。 #### メソッド #### `cancel(job_id: str) -> Job` -Cancel a running job. +実行中のジョブをキャンセルします。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `job_id` | | Job ID to cancel | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `job_id` | `str` | **Yes** | Job ID to cancel | **戻り値:** Cancelled Job object @@ -615,15 +615,15 @@ print(job.status) #### `create(execution_type: str, config_id: str | None = None, data: dict[str, Any] | None = None) -> Job` -Create a new job. +新しいジョブを作成します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `execution_type` | | Execution type (e.g., 'quick_evaluate', 'evaluation') | -| `config_id` | | Config ID (optional, uses default if not provided) | -| `data` | | Additional data for the job (for quick_evaluate) | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `execution_type` | `str` | **Yes** | Execution type (e.g., 'quick_evaluate', 'evaluation') | +| `config_id` | `str \| None` | No | Config ID (optional, uses default if not provided) | +| `data` | `dict[str, Any] \| None` | No | Additional data for the job (for quick_evaluate) | **戻り値:** Created Job object @@ -653,13 +653,13 @@ job = client.jobs.create( #### `get(job_id: str) -> Job` -Get job by ID. +IDでジョブを取得します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `job_id` | | Job ID | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `job_id` | `str` | **Yes** | Job ID | **戻り値:** Job object @@ -680,15 +680,15 @@ print(job.status) #### `list(status: str | None = None, execution_type: str | None = None, limit: int = 100) -> list[Job]` -List jobs. +ジョブ一覧を取得します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `status` | | Filter by status (e.g., 'completed', 'running', 'failed') | -| `execution_type` | | Filter by execution type (e.g., 'quick_evaluate', 'redteam_static', 'oss') | -| `limit` | | Maximum number of jobs to return (not yet implemented in backend) | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `status` | `str \| None` | No | Filter by status (e.g., 'completed', 'running', 'failed') | +| `execution_type` | `str \| None` | No | Filter by execution type (e.g., 'quick_evaluate', 'redteam_static', 'oss') | +| `limit` | `int` | No | Maximum number of jobs to return (not yet implemented in backend) | **戻り値:** List of Job objects @@ -713,16 +713,16 @@ redteam_jobs = client.jobs.list(execution_type="redteam_static") #### `wait(job_id: str, timeout: int = 600, poll_interval: float = 5.0, callback: Union[Callable[Job, None], None] = None) -> Job` -Wait for job completion. +ジョブの完了を待機します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `job_id` | | Job ID to wait for | -| `timeout` | | Maximum wait time in seconds (default: 600) | -| `poll_interval` | | Polling interval in seconds (default: 5.0) | -| `callback` | | Optional callback function called on each poll with Job object | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `job_id` | `str` | **Yes** | Job ID to wait for | +| `timeout` | `int` | No | Maximum wait time in seconds (default: 600) | +| `poll_interval` | `float` | No | Polling interval in seconds (default: 5.0) | +| `callback` | `Union[Callable[Job, None], None]` | No | Optional callback function called on each poll with Job object | **戻り値:** Completed Job object @@ -745,25 +745,23 @@ job = client.jobs.wait( ) ``` ---- - ### `ReportsClient` *継承:* `BaseClient` -Client for Reports API. +レポートAPI用クライアント。 #### メソッド #### `_build_url(path: str) -> str` -Build full URL from path. +パスから完全なURLを構築します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API path (e.g., "/configs") | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API path (e.g., "/configs") | **戻り値:** Full URL @@ -771,7 +769,7 @@ Build full URL from path. #### `_get_headers() -> dict[str, str]` -Get request headers with authentication. +認証付きのリクエストヘッダーを取得します。 **戻り値:** Request headers @@ -779,13 +777,13 @@ Get request headers with authentication. #### `_handle_error(response: Response) -> None` -Handle API error responses. +APIエラーレスポンスを処理します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `response` | | HTTP response | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `response` | `Response` | **Yes** | HTTP response | **例外:** @@ -799,19 +797,20 @@ Handle API error responses. #### `close()` -Close HTTP client. +HTTPクライアントを閉じます。 --- #### `delete(path: str, kwargs: Any) -> dict[str, Any] | None` -Send DELETE request. +DELETEリクエストを送信します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API path **kwargs: Additional request parameters | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API path **kwargs: Additional request parameters | +| `kwargs` | `Any` | **Yes** | | **戻り値:** Response data (if any) @@ -823,14 +822,14 @@ Send DELETE request. #### `get(report_id: str | UUID, view: Literal[summary, details] = "summary") -> Report` -Get a report by ID. +IDでレポートを取得します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `report_id` | | Report ID (= Job ID) | -| `view` | | View level - "summary": CI判定用の指標のみ - "details": 失敗ケース上位N件 + カテゴリ別集計 | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `report_id` | `str \| UUID` | **Yes** | Report ID (= Job ID) | +| `view` | `Literal[summary, details]` | No | View level - "summary": CI判定用の指標のみ - "details": 失敗ケース上位N件 + カテゴリ別集計 | **戻り値:** Report object @@ -865,14 +864,15 @@ for failed_case in report.details.failed_cases: #### `post(path: str, json: dict[str, Any] | None = None, kwargs: Any) -> dict[str, Any]` -Send POST request. +POSTリクエストを送信します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API path | -| `json` | | Request body (JSON) **kwargs: Additional request parameters | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API path | +| `json` | `dict[str, Any] \| None` | No | Request body (JSON) **kwargs: Additional request parameters | +| `kwargs` | `Any` | **Yes** | | **戻り値:** Response data @@ -884,14 +884,15 @@ Send POST request. #### `put(path: str, json: dict[str, Any] | None = None, kwargs: Any) -> dict[str, Any]` -Send PUT request. +PUTリクエストを送信します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `path` | | API path | -| `json` | | Request body (JSON) **kwargs: Additional request parameters | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `path` | `str` | **Yes** | API path | +| `json` | `dict[str, Any] \| None` | No | Request body (JSON) **kwargs: Additional request parameters | +| `kwargs` | `Any` | **Yes** | | **戻り値:** Response data @@ -899,29 +900,27 @@ Send PUT request. - `APIError`: If request failed ---- - ### `EvaluationClient` -Client for evaluation operations. +評価操作用クライアント。 -Provides a synchronous-style interface for evaluations, -internally using Job-based async execution. +同期スタイルのインターフェースを提供し、 +内部的にJobベースの非同期実行を使用します。 #### メソッド #### `answer_relevancy(question: str, answer: str, contexts: list[str] | None = None, timeout: int = 300) -> MetricResult` -Evaluate answer relevancy (answer addresses the question). +回答の関連性を評価します(回答が質問に対応しているか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts (optional) | -| `timeout` | | Maximum wait time in seconds | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str] \| None` | No | Context/retrieval texts (optional) | +| `timeout` | `int` | No | Maximum wait time in seconds | **戻り値:** MetricResult with answer relevancy score @@ -938,16 +937,16 @@ result = evaluator.answer_relevancy( #### `bias(question: str, answer: str, contexts: list[str] | None = None, timeout: int = 300) -> MetricResult` -Evaluate bias (answer contains biased content). +バイアスを評価します(回答に偏りのあるコンテンツが含まれているか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts (optional) | -| `timeout` | | Maximum wait time in seconds | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str] \| None` | No | Context/retrieval texts (optional) | +| `timeout` | `int` | No | Maximum wait time in seconds | **戻り値:** MetricResult with bias score (lower is better) @@ -955,16 +954,16 @@ Evaluate bias (answer contains biased content). #### `contextual_precision(question: str, answer: str, contexts: list[str], timeout: int = 300) -> MetricResult` -Evaluate contextual precision (relevant contexts ranked higher). +コンテキストの精度を評価します(関連するコンテキストが上位にランクされているか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts (order matters) | -| `timeout` | | Maximum wait time in seconds | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str]` | **Yes** | Context/retrieval texts (order matters) | +| `timeout` | `int` | No | Maximum wait time in seconds | **戻り値:** MetricResult with contextual precision score @@ -972,17 +971,17 @@ Evaluate contextual precision (relevant contexts ranked higher). #### `contextual_recall(question: str, answer: str, contexts: list[str], ground_truth: str, timeout: int = 300) -> MetricResult` -Evaluate contextual recall (answer can be attributed to contexts). +コンテキストの再現率を評価します(回答がコンテキストに帰属できるか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts | -| `ground_truth` | | Ground truth answer (required for contextual_recall) | -| `timeout` | | Maximum wait time in seconds | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str]` | **Yes** | Context/retrieval texts | +| `ground_truth` | `str` | **Yes** | Ground truth answer (required for contextual_recall) | +| `timeout` | `int` | No | Maximum wait time in seconds | **戻り値:** MetricResult with contextual recall score @@ -990,16 +989,16 @@ Evaluate contextual recall (answer can be attributed to contexts). #### `contextual_relevancy(question: str, answer: str, contexts: list[str], timeout: int = 300) -> MetricResult` -Evaluate contextual relevancy (contexts are relevant to question). +コンテキストの関連性を評価します(コンテキストが質問に関連しているか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts | -| `timeout` | | Maximum wait time in seconds | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str]` | **Yes** | Context/retrieval texts | +| `timeout` | `int` | No | Maximum wait time in seconds | **戻り値:** MetricResult with contextual relevancy score @@ -1017,23 +1016,23 @@ result = evaluator.contextual_relevancy( #### `evaluate(metric: str, question: str, answer: str, contexts: list[str] | None = None, ground_truth: str | None = None, timeout: int = 300, callback: Union[Callable[Job, None], None] = None, show_progress: bool = True) -> MetricResult` -Evaluate a single question-answer pair. +単一の質問-回答ペアを評価します。 -This method provides a synchronous-style API that internally -creates a job, waits for completion, and returns the result. +このメソッドは内部的にジョブを作成し、完了を待機して結果を返す +同期スタイルのAPIを提供します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `metric` | | Metric name (e.g., 'faithfulness', 'answer_relevancy') | -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts (optional) | -| `ground_truth` | | Ground truth answer (required for contextual_recall) | -| `timeout` | | Maximum wait time in seconds (default: 300) | -| `callback` | | Optional progress callback (overrides show_progress) | -| `show_progress` | | Show progress bar (default: True, ignored if callback is provided) | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `metric` | `str` | **Yes** | Metric name to evaluate. Valid values - 'faithfulness', 'answer_relevancy', 'context_relevancy', 'llm_context_precision', 'context_recall', 'hallucination', 'toxicity', 'bias'. (メソッド名と内部メトリック名の対応: contextual_relevancy() → 'context_relevancy', contextual_precision() → 'llm_context_precision', contextual_recall() → 'context_recall') | +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str] \| None` | No | Context/retrieval texts (optional) | +| `ground_truth` | `str \| None` | No | Ground truth answer (required for contextual_recall) | +| `timeout` | `int` | No | Maximum wait time in seconds (default: 300) | +| `callback` | `Union[Callable[Job, None], None]` | No | Optional progress callback (overrides show_progress) | +| `show_progress` | `bool` | No | Show progress bar (default: True, ignored if callback is provided) | **戻り値:** MetricResult with score and reason @@ -1062,17 +1061,17 @@ print(f"Score: {result.score}, Reason: {result.reason}") #### `faithfulness(question: str, answer: str, contexts: list[str], timeout: int = 300, on_progress: Union[Callable[Job, None], None] = None) -> MetricResult` -Evaluate faithfulness (answers based on contexts). +忠実性を評価します(回答がコンテキストに基づいているか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts | -| `timeout` | | Maximum wait time in seconds | -| `on_progress` | | Optional progress callback | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str]` | **Yes** | Context/retrieval texts | +| `timeout` | `int` | No | Maximum wait time in seconds | +| `on_progress` | `Union[Callable[Job, None], None]` | No | Optional progress callback | **戻り値:** MetricResult with faithfulness score @@ -1090,16 +1089,16 @@ result = evaluator.faithfulness( #### `hallucination(question: str, answer: str, contexts: list[str], timeout: int = 300) -> MetricResult` -Evaluate hallucination (answer contains information not in contexts). +ハルシネーションを評価します(回答にコンテキストにない情報が含まれているか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts | -| `timeout` | | Maximum wait time in seconds | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str]` | **Yes** | Context/retrieval texts | +| `timeout` | `int` | No | Maximum wait time in seconds | **戻り値:** MetricResult with hallucination score (lower is better) @@ -1107,30 +1106,28 @@ Evaluate hallucination (answer contains information not in contexts). #### `toxicity(question: str, answer: str, contexts: list[str] | None = None, timeout: int = 300) -> MetricResult` -Evaluate toxicity (answer contains toxic content). +有害性を評価します(回答に有害なコンテンツが含まれているか)。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `question` | | Question text | -| `answer` | | Answer text | -| `contexts` | | Context/retrieval texts (optional) | -| `timeout` | | Maximum wait time in seconds | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `question` | `str` | **Yes** | Question text | +| `answer` | `str` | **Yes** | Answer text | +| `contexts` | `list[str] \| None` | No | Context/retrieval texts (optional) | +| `timeout` | `int` | No | Maximum wait time in seconds | **戻り値:** MetricResult with toxicity score (lower is better) --- ---- - ## モデル ### `Config` *継承:* `BaseModel` -Complete config object. +完全な設定オブジェクト。 #### 属性 @@ -1140,12 +1137,12 @@ Complete config object. | `tenant_id` | `UUID` | | | `user_id` | `UUID` | | | `name` | `str` | | -| `description` | `str | None` | | +| `description` | `str \| None` | | | `locale` | `str` | | -| `api_settings` | `ApiSettings | None` | | -| `rag_quality_config` | `RagQualityConfig | None` | | -| `redteam_config` | `RedteamConfig | None` | | -| `policy_check_config` | `PolicyCheckConfig | None` | | +| `api_settings` | `ApiSettings \| None` | | +| `rag_quality_config` | `RagQualityConfig \| None` | | +| `redteam_config` | `RedteamConfig \| None` | | +| `policy_check_config` | `PolicyCheckConfig \| None` | | | `created_at` | `datetime` | | | `updated_at` | `datetime` | | @@ -1153,67 +1150,67 @@ Complete config object. *継承:* `BaseModel` -Request model for creating a config. +設定作成用のリクエストモデル。 #### 属性 | 属性 | 型 | 説明 | |---|---|---| | `name` | `str` | Config name | -| `description` | `str | None` | Config description | +| `description` | `str \| None` | Config description | | `locale` | `str` | Locale (ja/en) | | `api_endpoint` | `str` | API endpoint URL | | `auth_type` | `str` | Authentication type | -| `auth_header` | `str | None` | Auth header name | -| `auth_token` | `str | None` | Auth token | -| `request_format` | `dict[str, Any] | None` | Request format | -| `response_format` | `dict[str, Any] | None` | Response format | -| `evaluation_metrics` | `dict[str, Any] | None` | Evaluation metrics | -| `total_prompt_count` | `int | None` | Total prompt count | -| `prompt_category_ratios` | `dict[str, Any] | None` | Category ratios | -| `manual_prompts` | `list[str] | None` | Manual prompts | -| `evaluation_success_rate_threshold` | `float | None` | Success rate threshold (%) | -| `redteam_objectives` | `list[str] | None` | RedTeam objectives | -| `redteam_max_turns` | `int | None` | Max turns | -| `redteam_defense_rate_threshold` | `float | None` | Defense rate threshold (%) | -| `compliance_frameworks` | `list[str] | None` | Compliance frameworks | -| `policy_compliance_rate_threshold` | `float | None` | Compliance rate threshold (%) | +| `auth_header` | `str \| None` | Auth header name | +| `auth_token` | `str \| None` | Auth token | +| `request_format` | `dict[str, Any] \| None` | Request format | +| `response_format` | `dict[str, Any] \| None` | Response format | +| `evaluation_metrics` | `dict[str, Any] \| None` | Evaluation metrics | +| `total_prompt_count` | `int \| None` | Total prompt count | +| `prompt_category_ratios` | `dict[str, Any] \| None` | Category ratios | +| `manual_prompts` | `list[str] \| None` | Manual prompts | +| `evaluation_success_rate_threshold` | `float \| None` | Success rate threshold (%) | +| `redteam_objectives` | `list[str] \| None` | RedTeam objectives | +| `redteam_max_turns` | `int \| None` | Max turns | +| `redteam_defense_rate_threshold` | `float \| None` | Defense rate threshold (%) | +| `compliance_frameworks` | `list[str] \| None` | Compliance frameworks | +| `policy_compliance_rate_threshold` | `float \| None` | Compliance rate threshold (%) | ### `ConfigUpdate` *継承:* `BaseModel` -Request model for updating a config. +設定更新用のリクエストモデル。 #### 属性 | 属性 | 型 | 説明 | |---|---|---| -| `name` | `str | None` | | -| `description` | `str | None` | | -| `locale` | `str | None` | | -| `api_endpoint` | `str | None` | | -| `auth_type` | `str | None` | | -| `auth_header` | `str | None` | | -| `auth_token` | `str | None` | | -| `request_format` | `dict[str, Any] | None` | | -| `response_format` | `dict[str, Any] | None` | | -| `evaluation_metrics` | `dict[str, Any] | None` | | -| `total_prompt_count` | `int | None` | | -| `prompt_category_ratios` | `dict[str, Any] | None` | | -| `manual_prompts` | `list[str] | None` | | -| `evaluation_success_rate_threshold` | `float | None` | | -| `redteam_objectives` | `list[str] | None` | | -| `redteam_max_turns` | `int | None` | | -| `redteam_defense_rate_threshold` | `float | None` | | -| `compliance_frameworks` | `list[str] | None` | | -| `policy_compliance_rate_threshold` | `float | None` | | +| `name` | `str \| None` | | +| `description` | `str \| None` | | +| `locale` | `str \| None` | | +| `api_endpoint` | `str \| None` | | +| `auth_type` | `str \| None` | | +| `auth_header` | `str \| None` | | +| `auth_token` | `str \| None` | | +| `request_format` | `dict[str, Any] \| None` | | +| `response_format` | `dict[str, Any] \| None` | | +| `evaluation_metrics` | `dict[str, Any] \| None` | | +| `total_prompt_count` | `int \| None` | | +| `prompt_category_ratios` | `dict[str, Any] \| None` | | +| `manual_prompts` | `list[str] \| None` | | +| `evaluation_success_rate_threshold` | `float \| None` | | +| `redteam_objectives` | `list[str] \| None` | | +| `redteam_max_turns` | `int \| None` | | +| `redteam_defense_rate_threshold` | `float \| None` | | +| `compliance_frameworks` | `list[str] \| None` | | +| `policy_compliance_rate_threshold` | `float \| None` | | ### `ConfigListResponse` *継承:* `BaseModel` -Response model for listing configs. +設定一覧取得用のレスポンスモデル。 #### 属性 @@ -1226,7 +1223,7 @@ Response model for listing configs. *継承:* `BaseModel` -API settings configuration. +API設定。 #### 属性 @@ -1234,57 +1231,57 @@ API settings configuration. |---|---|---| | `api_endpoint` | `str` | | | `auth_type` | `str` | | -| `auth_header` | `str | None` | | -| `auth_token` | `str | None` | | -| `request_format` | `dict[str, Any] | None` | | -| `response_format` | `dict[str, Any] | None` | | +| `auth_header` | `str \| None` | | +| `auth_token` | `str \| None` | | +| `request_format` | `dict[str, Any] \| None` | | +| `response_format` | `dict[str, Any] \| None` | | ### `RagQualityConfig` *継承:* `BaseModel` -RAG Quality evaluation configuration. +RAG品質評価の設定。 #### 属性 | 属性 | 型 | 説明 | |---|---|---| | `evaluation_metrics` | `dict[str, Any]` | | -| `total_prompt_count` | `int | None` | | -| `prompt_category_ratios` | `dict[str, Any] | None` | | -| `manual_prompts` | `list[str] | None` | | -| `evaluation_success_rate_threshold` | `float | None` | | +| `total_prompt_count` | `int \| None` | | +| `prompt_category_ratios` | `dict[str, Any] \| None` | | +| `manual_prompts` | `list[str] \| None` | | +| `evaluation_success_rate_threshold` | `float \| None` | | ### `RedteamConfig` *継承:* `BaseModel` -RedTeam evaluation configuration. +RedTeam評価の設定。 #### 属性 | 属性 | 型 | 説明 | |---|---|---| -| `redteam_objectives` | `list[str] | None` | | -| `redteam_max_turns` | `int | None` | | -| `redteam_defense_rate_threshold` | `float | None` | | +| `redteam_objectives` | `list[str] \| None` | | +| `redteam_max_turns` | `int \| None` | | +| `redteam_defense_rate_threshold` | `float \| None` | | ### `PolicyCheckConfig` *継承:* `BaseModel` -Policy check configuration. +ポリシーチェックの設定。 #### 属性 | 属性 | 型 | 説明 | |---|---|---| -| `compliance_frameworks` | `list[str] | None` | | -| `policy_compliance_rate_threshold` | `float | None` | | +| `compliance_frameworks` | `list[str] \| None` | | +| `policy_compliance_rate_threshold` | `float \| None` | | ### `Job` -Job (Execution) model. +ジョブ(実行)モデル。 #### 属性 @@ -1296,28 +1293,29 @@ Job (Execution) model. | `config_id` | `str` | | | `execution_type` | `str` | | | `status` | `str` | | -| `current_step` | `str | None` | | +| `current_step` | `str \| None` | | | `progress_count` | `int` | | | `total_count` | `int` | | -| `progress` | `JobProgress | None` | | -| `results` | `dict[str, Any] | None` | | -| `error_message` | `str | None` | | -| `started_at` | `datetime | None` | | -| `completed_at` | `datetime | None` | | -| `created_at` | `datetime | None` | | -| `updated_at` | `datetime | None` | | +| `progress` | `JobProgress \| None` | | +| `results` | `dict[str, Any] \| None` | | +| `error_message` | `str \| None` | | +| `started_at` | `datetime \| None` | | +| `completed_at` | `datetime \| None` | | +| `created_at` | `datetime \| None` | | +| `updated_at` | `datetime \| None` | | #### メソッド #### *classmethod* `from_dict(cls, data: dict[str, Any]) -> Job` -Create Job from API response dict. +APIレスポンスの辞書からJobを作成します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `data` | | API response dictionary | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `cls` | | **Yes** | | +| `data` | `dict[str, Any]` | **Yes** | API response dictionary | **戻り値:** Job instance @@ -1325,31 +1323,29 @@ Create Job from API response dict. #### *property* `is_completed` -Check if job is completed. +ジョブが完了したかどうかを確認します。 --- #### *property* `is_failed` -Check if job failed. +ジョブが失敗したかどうかを確認します。 --- #### *property* `is_pending` -Check if job is pending (queued or pending). +ジョブが待機中(キュー待ちまたはペンディング)かどうかを確認します。 --- #### *property* `is_running` -Check if job is running. - ---- +ジョブが実行中かどうかを確認します。 ### `JobProgress` -Job progress information. +ジョブの進捗情報。 #### 属性 @@ -1360,7 +1356,7 @@ Job progress information. ### `MetricResult` -Single metric evaluation result. +単一メトリックの評価結果。 #### 属性 @@ -1368,15 +1364,15 @@ Single metric evaluation result. |---|---|---| | `metric` | `str` | | | `score` | `float` | | -| `reason` | `str | None` | | +| `reason` | `str \| None` | | | `engine` | `str` | | -| `execution_time_seconds` | `float | None` | (default: None) | +| `execution_time_seconds` | `float \| None` | (default: None) | ### `Report` *継承:* `BaseModel` -Report model. +レポートモデル。 #### 属性 @@ -1384,12 +1380,12 @@ Report model. |---|---|---| | `report_id` | `UUID` | | | `job_id` | `UUID` | | -| `config_id` | `UUID | None` | | +| `config_id` | `UUID \| None` | | | `type` | `str` | | | `status` | `Literal[completed, partial]` | | | `created_at` | `datetime` | | | `summary` | `ReportSummary` | | -| `details` | `ReportDetails | None` | | +| `details` | `ReportDetails \| None` | | ### `ReportSummary` @@ -1401,9 +1397,9 @@ Report model. | 属性 | 型 | 説明 | |---|---|---| -| `evaluation` | `EvaluationSummary | None` | | -| `redteam` | `RedTeamSummary | None` | | -| `policy` | `PolicySummary | None` | | +| `evaluation` | `EvaluationSummary \| None` | | +| `redteam` | `RedTeamSummary \| None` | | +| `policy` | `PolicySummary \| None` | | ### `ReportDetails` @@ -1477,10 +1473,10 @@ RedTeamサマリ | 属性 | 型 | 説明 | |---|---|---| | `category` | `str` | | -| `success_rate` | `float | None` | | -| `compliance_rate` | `float | None` | | +| `success_rate` | `float \| None` | | +| `compliance_rate` | `float \| None` | | | `count` | `int` | | -| `violations` | `int | None` | | +| `violations` | `int \| None` | | ### `FailedCase` @@ -1494,7 +1490,7 @@ RedTeamサマリ |---|---|---| | `case_id` | `str` | | | `input` | `str` | 入力(PIIマスキング済み) | -| `expected` | `str | None` | 期待値 | +| `expected` | `str \| None` | 期待値 | | `actual` | `str` | 実際の出力(PIIマスキング済み) | | `reason` | `str` | | | `category` | `str` | | @@ -1524,61 +1520,61 @@ RedTeamサマリ *継承:* `Exception` -Base exception for GenFlux SDK. +GenFlux SDKの基底例外クラス。 ### `APIError` *継承:* `GenFluxError` -API request failed. +APIリクエストが失敗しました。 ### `AuthenticationError` *継承:* `APIError` -Authentication failed (401). +認証に失敗しました(401)。 ### `NotFoundError` *継承:* `APIError` -Resource not found (404). +リソースが見つかりません(404)。 ### `ValidationError` *継承:* `APIError` -Validation error (422). +バリデーションエラー(400, 422)。 ### `TimeoutError` *継承:* `GenFluxError` -Operation timed out. +操作がタイムアウトしました。 ### `JobFailedError` *継承:* `GenFluxError` -Job execution failed. +ジョブの実行に失敗しました。 ### `RateLimitError` *継承:* `APIError` -Rate limit exceeded (429). +レート制限を超過しました(429)。 ### `ConfigNotFoundError` *継承:* `GenFluxError` -Config not found. +設定が見つかりません。 ### `ResourceNotFoundError` *継承:* `GenFluxError` -Generic resource not found error. +汎用リソースが見つからないエラー。 --- @@ -1586,7 +1582,7 @@ Generic resource not found error. ### `ProgressBar` -Simple progress bar for terminal output. +ターミナル出力用のシンプルなプログレスバー。 #### 属性 @@ -1605,42 +1601,42 @@ Simple progress bar for terminal output. #### `update(current: int, message: str | None = None, indeterminate: bool = False) -> None` -Update progress bar. +プログレスバーを更新します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `current` | | Current progress value (0 to total) | -| `message` | | Optional status message | -| `indeterminate` | | When True, show "Processing..." instead of percentage (for single-metric or initial state) | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `current` | `int` | **Yes** | Current progress value (0 to total) | +| `message` | `str \| None` | No | Optional status message | +| `indeterminate` | `bool` | No | When True, show "Processing..." instead of percentage (for single-metric or initial state) | --- #### `update_from_job(job: Job) -> None` -Update progress bar from Job object. +Jobオブジェクトからプログレスバーを更新します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `job` | | Job object with progress information | - ---- +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `job` | `Job` | **Yes** | Job object with progress information | ### `create_progress_callback(enable: bool = True) -> Callable[Job, None]` -Create a progress callback for job.wait(). +job.wait()用のプログレスコールバックを作成します。 **パラメータ:** -| パラメータ | 型 | 説明 | -|---|---|---| -| `enable` | | Whether to enable progress display (default: True) | +| パラメータ | 型 | 必須 | 説明 | +|---|---|---|---| +| `enable` | | **Yes** | Whether to enable progress display (default: True) | **戻り値:** Callback function for job.wait() --- -*Auto-generated at 2026-03-12 00:24 UTC by `scripts/generate_api_reference.py`* +*Auto-generated at 2026-03-23 07:15 UTC by `scripts/generate_api_reference.py`* + + diff --git a/docs/EXAMPLES.md b/docs/EXAMPLES.md index f422767..9133b8b 100644 --- a/docs/EXAMPLES.md +++ b/docs/EXAMPLES.md @@ -1,4 +1,4 @@ -# GenFlux Python SDK - サンプルコード集 +# Genflux Python SDK - サンプルコード集 実際のユースケースごとのサンプルコードを紹介します。 @@ -40,7 +40,6 @@ result = evaluator.faithfulness( print(f"スコア: {result.score}") print(f"理由: {result.reason}") -print(f"エンジン: {result.engine}") # 結果判定 if result.score >= 0.8: @@ -174,22 +173,26 @@ client = GenFlux() # 1. Config作成 print("1. Config作成中...") +from genflux.models.config import ConfigCreate + config = client.configs.create( - name="Test RAG API", - api_endpoint="https://api.dify.ai/v1/chat-messages", - auth_type="bearer_token", - auth_credentials="app-xxxxxxxxxxxx", - request_format={ - "method": "POST", - "body_template": { - "query": "{{prompt}}", - "response_mode": "blocking", - "user": "test-user" + ConfigCreate( + name="Test RAG API", + api_endpoint="https://api.example.com/chat", + auth_type="bearer_token", + auth_token="your_token_here", + request_format={ + "method": "POST", + "body_template": { + "query": "{{prompt}}", + "response_mode": "blocking", + "user": "test-user" + } + }, + response_format={ + "response_path": "answer" } - }, - response_format={ - "response_path": "answer" - } + ) ) print(f" ✅ Config作成完了: {config.id}") @@ -255,7 +258,7 @@ while time.time() - start_time < max_wait: job_status = client.jobs.get(job.id) elapsed = int(time.time() - start_time) - print(f"[{elapsed}s] Status: {job_status.status}, Progress: {job_status.progress}/{job_status.total_count}") + print(f"[{elapsed}s] Status: {job_status.status}, Progress: {job_status.progress_count}/{job_status.total_count}") if job_status.status in ["completed", "failed", "cancelled"]: print(f"\nJob終了: {job_status.status}") @@ -508,15 +511,15 @@ def custom_callback(job): } emoji = status_emoji.get(job.status, "❓") - progress_pct = (job.progress / job.total_count * 100) if job.total_count > 0 else 0 - - print(f"{emoji} Status: {job.status} | Progress: {job.progress}/{job.total_count} ({progress_pct:.1f}%)") + progress_pct = (job.progress_count / job.total_count * 100) if job.total_count > 0 else 0 + + print(f"{emoji} Status: {job.status} | Progress: {job.progress_count}/{job.total_count} ({progress_pct:.1f}%)") result = evaluator.faithfulness( question="What is Python?", answer="Python is a programming language.", contexts=["Python is a high-level programming language."], - callback=custom_callback + on_progress=custom_callback ) # 3. ログファイルへの進捗記録 @@ -525,7 +528,7 @@ import datetime def logging_callback(job): """ログファイルに進捗を記録""" timestamp = datetime.datetime.now().isoformat() - log_entry = f"[{timestamp}] Job {job.id}: {job.status} - {job.progress}/{job.total_count}\n" + log_entry = f"[{timestamp}] Job {job.id}: {job.status} - {job.progress_count}/{job.total_count}\n" with open("evaluation_progress.log", "a") as f: f.write(log_entry) @@ -537,7 +540,7 @@ result = evaluator.faithfulness( question="What is Python?", answer="Python is a programming language.", contexts=["Python is a high-level programming language."], - callback=logging_callback + on_progress=logging_callback ) ``` @@ -545,7 +548,7 @@ result = evaluator.faithfulness( ## まとめ -これらのサンプルコードを参考に、GenFlux Python SDKを活用してください。 +これらのサンプルコードを参考に、Genflux Python SDKを活用してください。 さらに詳しい情報は以下を参照: - [README.md](../README.md) - 基本的な使い方 @@ -553,5 +556,5 @@ result = evaluator.faithfulness( --- -**GenFlux Python SDK - サンプルコード集** +**Genflux Python SDK - サンプルコード集** diff --git a/docs/LOCAL_SETUP.md b/docs/LOCAL_SETUP.md index 98a24ec..c8c99cb 100644 --- a/docs/LOCAL_SETUP.md +++ b/docs/LOCAL_SETUP.md @@ -1,6 +1,6 @@ -# GenFlux Python SDK(ローカル環境) +# Genflux Python SDK(ローカル環境) -GenFlux Platform の公式Python SDKです。RAG(Retrieval-Augmented Generation)システムの評価、セキュリティテスト、ポリシーチェックを簡単に実行することができます。 +Genflux Platform の公式Python SDKです。RAG(Retrieval-Augmented Generation)システムの評価、セキュリティテスト、ポリシーチェックを簡単に実行することができます。 [![Python Version](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/) [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) @@ -46,7 +46,7 @@ git clone ### 2. バックエンドサーバーの起動 -GenFlux Platform Backend を起動します。 +Genflux Platform Backend を起動します。 ```bash # バックエンドディレクトリに移動 @@ -123,7 +123,7 @@ uv pip install -e . #### 本番環境(Production) ```bash -# API Key(GenFlux Platform の管理画面から取得) +# API Key(Genflux Platform の管理画面から取得) export GENFLUX_API_KEY="genflux_your_api_key_here" # 環境指定(省略可: デフォルトは "prod") @@ -161,7 +161,7 @@ export GENFLUX_ENVIRONMENT="local" - `prod`: 本番環境(デフォルト) **注意**: -- `GENFLUX_API_KEY`: GenFlux Platform の管理画面から取得してください +- `GENFLUX_API_KEY`: Genflux Platform の管理画面から取得してください - `GENFLUX_ENVIRONMENT`: 省略した場合、**本番環境(prod)がデフォルト**です - `GENFLUX_API_BASE_URL`: カスタムURLが必要な特殊な環境でのみ使用 @@ -343,4 +343,4 @@ MIT License - 詳細は [LICENSE](LICENSE) ファイルを参照してくださ --- -**GenFlux - RAG Evaluation Made Simple** +**Genflux - RAG Evaluation Made Simple** diff --git a/docs/QUICKSTART.md b/docs/QUICKSTART.md index d9bd312..249a726 100644 --- a/docs/QUICKSTART.md +++ b/docs/QUICKSTART.md @@ -1,6 +1,6 @@ -# GenFlux Python SDK - クイックスタート +# Genflux Python SDK - クイックスタート -最も簡単な方法で GenFlux SDK を使い始めましょう。このガイドでは、Config 作成から評価実行まで、最小限のコードで試せます。 +最も簡単な方法で Genflux SDK を使い始めましょう。このガイドでは、Config 作成から評価実行まで、最小限のコードで試せます。 --- @@ -17,7 +17,7 @@ ## 前提条件 - Python 3.11 以上 -- GenFlux Platform で発行した API Key(環境変数 `GENFLUX_API_KEY` に設定) +- Genflux Platform で発行した API Key(環境変数 `GENFLUX_API_KEY` に設定) --- @@ -263,7 +263,5 @@ Contextual Relevancy: 0.88 --- ---- - **次へ**: [WORKFLOW.md](./WORKFLOW.md) で本格的な使い方を学ぶ diff --git a/docs/WORKFLOW.md b/docs/WORKFLOW.md index 8242cc0..612e2ac 100644 --- a/docs/WORKFLOW.md +++ b/docs/WORKFLOW.md @@ -1,4 +1,4 @@ -# GenFlux Python SDK - 本格的なワークフロー +# Genflux Python SDK - 本格的なワークフロー 実践的なユースケースに基づいた、本格的なワークフロー例を紹介します。 @@ -195,15 +195,14 @@ for metric_key, metric_name in metrics: ) else: result = method( - question=question, - answer=answer, - contexts=contexts, - ) + question=question, + answer=answer, + contexts=contexts, + ) results[metric_name] = { "score": result.score, "reason": result.reason, - "engine": result.engine } print(f" ✅ Score: {result.score:.2f}") @@ -286,16 +285,6 @@ if not config_id: } }, response_format={"response_path": "answer"}, - evaluation_metrics=None, - total_prompt_count=None, - prompt_category_ratios=None, - manual_prompts=None, - evaluation_success_rate_threshold=None, - redteam_objectives=None, - redteam_max_turns=None, - redteam_defense_rate_threshold=None, - compliance_frameworks=None, - policy_compliance_rate_threshold=None, ) config = client.configs.create(config_data) config_id = str(config.id) @@ -399,16 +388,6 @@ if not config_id: } }, response_format={"response_path": "answer"}, - evaluation_metrics=None, - total_prompt_count=None, - prompt_category_ratios=None, - manual_prompts=None, - evaluation_success_rate_threshold=None, - redteam_objectives=None, - redteam_max_turns=None, - redteam_defense_rate_threshold=None, - compliance_frameworks=None, - policy_compliance_rate_threshold=None, ) config = client.configs.create(config_data) config_id = str(config.id) diff --git a/llms-full.txt b/llms-full.txt index 1bb98ec..7d32a4f 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -1,6 +1,6 @@ -# GenFlux Python SDK — Full Context for LLMs +# Genflux Python SDK — Full Context for LLMs -> GenFlux Python SDK は RAG(Retrieval-Augmented Generation)システムの**評価・セキュリティテスト・ポリシーチェック**を Python から実行するための公式クライアントライブラリです。このファイルには LLM がコードを生成・修正するために必要な全 API 情報が含まれています。 +> Genflux Python SDK は RAG(Retrieval-Augmented Generation)システムの**評価・セキュリティテスト・ポリシーチェック**を Python から実行するための公式クライアントライブラリです。このファイルには LLM がコードを生成・修正するために必要な全 API 情報が含まれています。 ## Quick Start @@ -85,14 +85,14 @@ Everything exported from `genflux/__init__.py`: # Utils: ProgressBar, create_progress_callback ``` -## GenFlux Client +## Genflux Client ```python @dataclass class GenFlux(api_key: str | None = None, base_url: str | None = None, environment: str | None = None, timeout: float = 60.0) -> None ``` -GenFlux API Client. +GenFlux APIクライアント。 **Constructor Parameters:** @@ -111,7 +111,7 @@ GenFlux API Client. **Methods:** -- `evaluation(config_id: str | None = None) -> EvaluationClient` — Create an evaluation client for the given config. +- `evaluation(config_id: str | None = None) -> EvaluationClient` — 指定された設定で評価クライアントを作成します。 ## EvaluationClient @@ -119,15 +119,15 @@ Created via `client.evaluation(config_id=None)`. Provides synchronous evaluation **Methods:** -- `answer_relevancy(question: str, answer: str, contexts: list[str] | None = None, timeout: int = 300) -> MetricResult` — Evaluate answer relevancy (answer addresses the question). -- `bias(question: str, answer: str, contexts: list[str] | None = None, timeout: int = 300) -> MetricResult` — Evaluate bias (answer contains biased content). -- `contextual_precision(question: str, answer: str, contexts: list[str], timeout: int = 300) -> MetricResult` — Evaluate contextual precision (relevant contexts ranked higher). -- `contextual_recall(question: str, answer: str, contexts: list[str], ground_truth: str, timeout: int = 300) -> MetricResult` — Evaluate contextual recall (answer can be attributed to contexts). -- `contextual_relevancy(question: str, answer: str, contexts: list[str], timeout: int = 300) -> MetricResult` — Evaluate contextual relevancy (contexts are relevant to question). -- `evaluate(metric: str, question: str, answer: str, contexts: list[str] | None = None, ground_truth: str | None = None, timeout: int = 300, callback: Union[Callable[Job, None], None] = None, show_progress: bool = True) -> MetricResult` — Evaluate a single question-answer pair. -- `faithfulness(question: str, answer: str, contexts: list[str], timeout: int = 300, on_progress: Union[Callable[Job, None], None] = None) -> MetricResult` — Evaluate faithfulness (answers based on contexts). -- `hallucination(question: str, answer: str, contexts: list[str], timeout: int = 300) -> MetricResult` — Evaluate hallucination (answer contains information not in contexts). -- `toxicity(question: str, answer: str, contexts: list[str] | None = None, timeout: int = 300) -> MetricResult` — Evaluate toxicity (answer contains toxic content). +- `answer_relevancy(question: str, answer: str, contexts: list[str] | None = None, timeout: int = 300) -> MetricResult` — 回答の関連性を評価します(回答が質問に対応しているか)。 +- `bias(question: str, answer: str, contexts: list[str] | None = None, timeout: int = 300) -> MetricResult` — バイアスを評価します(回答に偏りのあるコンテンツが含まれているか)。 +- `contextual_precision(question: str, answer: str, contexts: list[str], timeout: int = 300) -> MetricResult` — コンテキストの精度を評価します(関連するコンテキストが上位にランクされているか)。 +- `contextual_recall(question: str, answer: str, contexts: list[str], ground_truth: str, timeout: int = 300) -> MetricResult` — コンテキストの再現率を評価します(回答がコンテキストに帰属できるか)。 +- `contextual_relevancy(question: str, answer: str, contexts: list[str], timeout: int = 300) -> MetricResult` — コンテキストの関連性を評価します(コンテキストが質問に関連しているか)。 +- `evaluate(metric: str, question: str, answer: str, contexts: list[str] | None = None, ground_truth: str | None = None, timeout: int = 300, callback: Union[Callable[Job, None], None] = None, show_progress: bool = True) -> MetricResult` — 単一の質問-回答ペアを評価します。 +- `faithfulness(question: str, answer: str, contexts: list[str], timeout: int = 300, on_progress: Union[Callable[Job, None], None] = None) -> MetricResult` — 忠実性を評価します(回答がコンテキストに基づいているか)。 +- `hallucination(question: str, answer: str, contexts: list[str], timeout: int = 300) -> MetricResult` — ハルシネーションを評価します(回答にコンテキストにない情報が含まれているか)。 +- `toxicity(question: str, answer: str, contexts: list[str] | None = None, timeout: int = 300) -> MetricResult` — 有害性を評価します(回答に有害なコンテンツが含まれているか)。 All metric methods share a common pattern: @@ -149,11 +149,11 @@ Accessed via `client.configs`. CRUD operations for evaluation configurations. **Methods:** -- `create(config: ConfigCreate) -> Config` — Create a new config. -- `delete(config_id: str | UUID) -> bool` — Delete config. -- `get(config_id: str | UUID) -> Config` — Get config by ID. -- `list(limit: int = 100, offset: int = 0) -> ConfigListResponse` — List all configs. -- `update(config_id: str | UUID, config_update: ConfigUpdate) -> Config` — Update config. +- `create(config: ConfigCreate) -> Config` — 新しい設定を作成します。 +- `delete(config_id: str | UUID) -> bool` — 設定を削除します。 +- `get(config_id: str | UUID) -> Config` — IDで設定を取得します。 +- `list(limit: int = 100, offset: int = 0) -> ConfigListResponse` — すべての設定を一覧取得します。 +- `update(config_id: str | UUID, config_update: ConfigUpdate) -> Config` — 設定を更新します。 ## JobsClient @@ -161,11 +161,11 @@ Accessed via `client.jobs`. Manages asynchronous evaluation jobs. **Methods:** -- `cancel(job_id: str) -> Job` — Cancel a running job. -- `create(execution_type: str, config_id: str | None = None, data: dict[str, Any] | None = None) -> Job` — Create a new job. -- `get(job_id: str) -> Job` — Get job by ID. -- `list(status: str | None = None, execution_type: str | None = None, limit: int = 100) -> list[Job]` — List jobs. -- `wait(job_id: str, timeout: int = 600, poll_interval: float = 5.0, callback: Union[Callable[Job, None], None] = None) -> Job` — Wait for job completion. +- `cancel(job_id: str) -> Job` — 実行中のジョブをキャンセルします。 +- `create(execution_type: str, config_id: str | None = None, data: dict[str, Any] | None = None) -> Job` — 新しいジョブを作成します。 +- `get(job_id: str) -> Job` — IDでジョブを取得します。 +- `list(status: str | None = None, execution_type: str | None = None, limit: int = 100) -> list[Job]` — ジョブ一覧を取得します。 +- `wait(job_id: str, timeout: int = 600, poll_interval: float = 5.0, callback: Union[Callable[Job, None], None] = None) -> Job` — ジョブの完了を待機します。 ## ReportsClient @@ -173,13 +173,13 @@ Accessed via `client.reports`. Fetch evaluation reports. **Methods:** -- `get(report_id: str | UUID, view: Literal[summary, details] = "summary") -> Report` — Get a report by ID. +- `get(report_id: str | UUID, view: Literal[summary, details] = "summary") -> Report` — IDでレポートを取得します。 ## Data Models ### `Config` -Complete config object. +完全な設定オブジェクト。 | Field | Type | Description | |---|---|---| @@ -198,7 +198,7 @@ Complete config object. ### `ConfigCreate` -Request model for creating a config. +設定作成用のリクエストモデル。 | Field | Type | Description | |---|---|---| @@ -224,7 +224,7 @@ Request model for creating a config. ### `ConfigUpdate` -Request model for updating a config. +設定更新用のリクエストモデル。 | Field | Type | Description | |---|---|---| @@ -250,7 +250,7 @@ Request model for updating a config. ### `ConfigListResponse` -Response model for listing configs. +設定一覧取得用のレスポンスモデル。 | Field | Type | Description | |---|---|---| @@ -259,7 +259,7 @@ Response model for listing configs. ### `Job` -Job (Execution) model. +ジョブ(実行)モデル。 | Field | Type | Description | |---|---|---| @@ -282,7 +282,7 @@ Job (Execution) model. ### `JobProgress` -Job progress information. +ジョブの進捗情報。 | Field | Type | Description | |---|---|---| @@ -291,7 +291,7 @@ Job progress information. ### `MetricResult` -Single metric evaluation result. +単一メトリックの評価結果。 | Field | Type | Description | |---|---|---| @@ -303,7 +303,7 @@ Single metric evaluation result. ### `Report` -Report model. +レポートモデル。 | Field | Type | Description | |---|---|---| @@ -418,7 +418,7 @@ Exception ├── APIError (status_code, message, details) │ ├── AuthenticationError (401) │ ├── NotFoundError (404) - │ ├── ValidationError (422) + │ ├── ValidationError (400, 422) │ └── RateLimitError (429, retry_after) ├── TimeoutError (operation, timeout, job_id) ├── JobFailedError (job_id, error_message) @@ -428,16 +428,16 @@ Exception All exceptions: -- `GenFluxError`: Base exception for GenFlux SDK. -- `APIError`: API request failed. -- `AuthenticationError`: Authentication failed (401). -- `NotFoundError`: Resource not found (404). -- `ValidationError`: Validation error (422). -- `TimeoutError`: Operation timed out. -- `JobFailedError`: Job execution failed. -- `RateLimitError`: Rate limit exceeded (429). -- `ConfigNotFoundError`: Config not found. -- `ResourceNotFoundError`: Generic resource not found error. +- `GenFluxError`: GenFlux SDKの基底例外クラス。 +- `APIError`: APIリクエストが失敗しました。 +- `AuthenticationError`: 認証に失敗しました(401)。 +- `NotFoundError`: リソースが見つかりません(404)。 +- `ValidationError`: バリデーションエラー(400, 422)。 +- `TimeoutError`: 操作がタイムアウトしました。 +- `JobFailedError`: ジョブの実行に失敗しました。 +- `RateLimitError`: レート制限を超過しました(429)。 +- `ConfigNotFoundError`: 設定が見つかりません。 +- `ResourceNotFoundError`: 汎用リソースが見つからないエラー。 ## Evaluation Metrics Reference @@ -458,7 +458,7 @@ All exceptions: genflux-python-sdk/ ├── src/genflux/ # SDK source │ ├── __init__.py # Public API (__all__) -│ ├── client.py # GenFlux main client +│ ├── client.py # Genflux main client │ ├── evaluation.py # EvaluationClient │ ├── jobs.py # JobsClient │ ├── progress.py # Progress display utilities diff --git a/llms.txt b/llms.txt index 0430b3b..49062df 100644 --- a/llms.txt +++ b/llms.txt @@ -1,6 +1,6 @@ -# GenFlux Python SDK +# Genflux Python SDK -> GenFlux Python SDK は RAG(Retrieval-Augmented Generation)システムの**評価・セキュリティテスト・ポリシーチェック**を Python から実行するための公式クライアントライブラリです。同期的な API の裏で非同期 Job をポーリングし、結果を返すアーキテクチャを採用しています。 +> Genflux Python SDK は RAG(Retrieval-Augmented Generation)システムの**評価・セキュリティテスト・ポリシーチェック**を Python から実行するための公式クライアントライブラリです。同期的な API の裏で非同期 Job をポーリングし、結果を返すアーキテクチャを採用しています。 ## Quick Start @@ -73,7 +73,7 @@ Priority: `GENFLUX_API_BASE_URL` > `GENFLUX_ENVIRONMENT` > default (`"prod"`). ``` src/genflux/ ├── __init__.py # Public API (__all__) — single source of truth -├── client.py # GenFlux main client (entry point) +├── client.py # Genflux main client (entry point) ├── evaluation.py # EvaluationClient (12 metric methods) ├── jobs.py # JobsClient (create / wait / cancel jobs) ├── progress.py # ProgressBar / create_progress_callback @@ -133,6 +133,6 @@ make llms-check # Verify llms.txt is up-to-date ## Optional -- [Backend API Reference](docs/BACKEND_API_REFERENCE.md): REST API endpoints of the GenFlux Platform backend +- [Backend API Reference](docs/BACKEND_API_REFERENCE.md): REST API endpoints of the Genflux Platform backend - [Test Evaluation Sheet](docs/TEST_EVALUATION_SHEET.md): Test cases and evaluation criteria - [Local Setup](docs/LOCAL_SETUP.md): Local development environment setup with Docker diff --git a/pyproject.toml b/pyproject.toml index 1438b86..861efa9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "hatchling.build" [project] name = "genflux" version = "0.1.2" -description = "Python SDK for GenFlux API - RAG Evaluation Platform" +description = "Python SDK for Genflux API - RAG Evaluation Platform" readme = "README.md" license = "MIT" license-files = ["LICENSE"] @@ -15,7 +15,7 @@ dependencies = [ "pydantic>=2.0.0", "tqdm>=4.66.0", ] -authors = [{ name = "GenFlux Team", email = "genflux-support@elith.jp" }] +authors = [{ name = "Genflux Team", email = "genflux-support@elith.jp" }] keywords = ["rag", "evaluation", "llm", "ai-safety", "redteam", "policy-check", "genflux"] classifiers = [ "Programming Language :: Python :: 3", @@ -40,9 +40,11 @@ include = ["src/genflux"] [dependency-groups] dev = [ "build>=1.2.0", + "openai>=1.0.0", "pip-audit>=2.7.0", "pip-licenses>=4.4.0", "pre-commit>=4.2.0", + "python-dotenv>=1.0.0", "pyright>=1.1.402", "pytest>=8.4.1", "ruff>=0.11.4", diff --git a/scripts/generate_api_reference.py b/scripts/generate_api_reference.py index 0cc6320..08ae035 100644 --- a/scripts/generate_api_reference.py +++ b/scripts/generate_api_reference.py @@ -2,18 +2,22 @@ """API Reference ドキュメント自動生成スクリプト. SDK のソースコードから docstring・型ヒントを解析し、 -Markdown 形式の API Reference を生成する。 +3-pass LLM パイプライン(改善→ハルシネーションチェック→UXレビュー)で +高品質な Markdown 形式の API Reference を生成する。 Usage: - # External(SDKユーザー向け)API Reference を生成 + # 両方を生成(LLM 3-pass 改善付き) + python scripts/generate_api_reference.py --mode all + + # キャッシュなしで再生成 + python scripts/generate_api_reference.py --mode all --no-cache + + # External(SDKユーザー向け)のみ python scripts/generate_api_reference.py --mode external - # Developer(開発者向け)API Reference を生成 + # Developer(開発者向け)のみ python scripts/generate_api_reference.py --mode developer - # 両方を生成 - python scripts/generate_api_reference.py --mode all - # 差分チェック(CIで使用) python scripts/generate_api_reference.py --mode all --check """ @@ -21,7 +25,9 @@ from __future__ import annotations import argparse +import hashlib import inspect +import os import re import sys import textwrap @@ -46,6 +52,7 @@ class DocParam: name: str type_hint: str description: str + required: bool = True @dataclass @@ -170,6 +177,49 @@ def _parse_example_section(content: str) -> list[str]: return examples +def _enrich_params_from_signature( + doc_params: list[DocParam], + func: Any, +) -> list[DocParam]: + """Docstring パラメータに関数シグネチャの型・デフォルト情報を補完する.""" + try: + sig = inspect.signature(func) + except (ValueError, TypeError): + return doc_params + + sig_map: dict[str, inspect.Parameter] = { + name: param + for name, param in sig.parameters.items() + if name != "self" + } + + doc_map = {p.name: p for p in doc_params} + result: list[DocParam] = [] + + # シグネチャ順で出力(docstring にないパラメータも拾う) + for param_name, param in sig_map.items(): + type_str = _type_to_str(param.annotation) + is_required = param.default is inspect.Parameter.empty + + if param_name in doc_map: + dp = doc_map[param_name] + result.append(DocParam( + name=dp.name, + type_hint=dp.type_hint or type_str, + description=dp.description, + required=is_required, + )) + else: + result.append(DocParam( + name=param_name, + type_hint=type_str, + description="", + required=is_required, + )) + + return result + + # --------------------------------------------------------------------------- # 型ヒント → 文字列 # --------------------------------------------------------------------------- @@ -305,6 +355,10 @@ def _extract_class_info( methods: list[MethodInfo] = [] fields: list[DocParam] = [] + # コンストラクタパラメータを __init__ シグネチャから enrichment + if doc.params and hasattr(cls, "__init__"): + doc.params = _enrich_params_from_signature(doc.params, cls.__init__) + # このクラス自身で定義されたメソッド名の集合 own_members = set(cls.__dict__.keys()) if not include_inherited else None @@ -360,6 +414,8 @@ def _extract_class_info( if isinstance(cm, classmethod): actual_func = cm.__func__ mdoc = _parse_google_docstring(inspect.getdoc(obj)) + # シグネチャから型・Required 情報を補完 + mdoc.params = _enrich_params_from_signature(mdoc.params, actual_func) sig_str = _get_signature_str(actual_func, name) methods.append(MethodInfo( name=name, @@ -383,14 +439,27 @@ def _extract_class_info( # Markdown 生成 # --------------------------------------------------------------------------- -def _md_params_table(params: list[DocParam]) -> str: +def _escape_pipe_in_table(text: str) -> str: + """Markdown テーブルセル内の | をエスケープする.""" + return text.replace("|", r"\|") + + +def _md_params_table(params: list[DocParam], *, show_required: bool = True) -> str: """パラメータをMarkdownテーブルとして出力する.""" if not params: return "" - lines = ["| パラメータ | 型 | 説明 |", "|---|---|---|"] - for p in params: - type_str = f"`{p.type_hint}`" if p.type_hint else "" - lines.append(f"| `{p.name}` | {type_str} | {p.description} |") + + if show_required: + lines = ["| パラメータ | 型 | 必須 | 説明 |", "|---|---|---|---|"] + for p in params: + type_str = f"`{_escape_pipe_in_table(p.type_hint)}`" if p.type_hint else "" + req_str = "**Yes**" if p.required else "No" + lines.append(f"| `{p.name}` | {type_str} | {req_str} | {p.description} |") + else: + lines = ["| パラメータ | 型 | 説明 |", "|---|---|---|"] + for p in params: + type_str = f"`{_escape_pipe_in_table(p.type_hint)}`" if p.type_hint else "" + lines.append(f"| `{p.name}` | {type_str} | {p.description} |") return "\n".join(lines) @@ -400,7 +469,7 @@ def _md_fields_table(fields: list[DocParam]) -> str: return "" lines = ["| 属性 | 型 | 説明 |", "|---|---|---|"] for f in fields: - type_str = f"`{f.type_hint}`" if f.type_hint else "" + type_str = f"`{_escape_pipe_in_table(f.type_hint)}`" if f.type_hint else "" lines.append(f"| `{f.name}` | {type_str} | {f.description} |") return "\n".join(lines) @@ -431,7 +500,7 @@ def _md_example(examples: list[str]) -> str: return "\n\n".join(blocks) -def _md_method(method: MethodInfo) -> str: +def _md_method(method: MethodInfo, *, num_prefix: str = "") -> str: """メソッドのMarkdownセクションを生成する.""" lines: list[str] = [] @@ -444,7 +513,8 @@ def _md_method(method: MethodInfo) -> str: elif method.is_staticmethod: prefix = "*staticmethod* " - lines.append(f"#### {prefix}`{method.signature}`") + num_label = f"{num_prefix} " if num_prefix else "" + lines.append(f"#### {num_label}{prefix}`{method.signature}`") lines.append("") if method.doc.summary: @@ -485,13 +555,14 @@ def _md_method(method: MethodInfo) -> str: return "\n".join(lines) -def _md_class(info: ClassInfo, *, heading_level: int = 2) -> str: +def _md_class(info: ClassInfo, *, heading_level: int = 2, num_prefix: str = "") -> str: """クラスのMarkdownセクションを生成する.""" h = "#" * heading_level lines: list[str] = [] # クラスヘッダー - lines.append(f"{h} `{info.name}`") + num_label = f"{num_prefix} " if num_prefix else "" + lines.append(f"{h} {num_label}`{info.name}`") lines.append("") if info.bases: @@ -532,10 +603,11 @@ def _md_class(info: ClassInfo, *, heading_level: int = 2) -> str: if public_methods: lines.append(f"{h}# メソッド") lines.append("") - for method in public_methods: + for i, method in enumerate(public_methods): lines.append(_md_method(method)) - lines.append("---") - lines.append("") + if i < len(public_methods) - 1: + lines.append("---") + lines.append("") return "\n".join(lines) @@ -598,9 +670,9 @@ def _generate_external_reference() -> str: -# GenFlux Python SDK - API Reference +# Genflux Python SDK - API Reference -GenFlux Python SDK の完全な API リファレンスです。 +Genflux Python SDK の完全な API リファレンスです。 このドキュメントはソースコードの docstring・型ヒントから**自動生成**されています。 > ⚠️ **このファイルは自動生成物です。直接編集しないでください。** @@ -609,51 +681,47 @@ def _generate_external_reference() -> str: --- -## 📋 目次 +## 目次 -- [機能全体像](#機能全体像) -- [GenFlux クライアント](#genflux-1) -- [ConfigClient](#configclient) -- [JobsClient](#jobsclient) -- [ReportsClient](#reportsclient) -- [EvaluationClient](#evaluationclient) -- [モデル](#モデル) -- [例外](#例外) -- [ユーティリティ](#ユーティリティ) +- [1. 概要](#1-概要) +- [2. クライアント](#2-クライアント) + - [2.1 GenFlux](#21-genflux) + - [2.2 ConfigClient](#22-configclient) + - [2.3 JobsClient](#23-jobsclient) + - [2.4 ReportsClient](#24-reportsclient) + - [2.5 EvaluationClient](#25-evaluationclient) +- [3. モデル](#3-モデル) +- [4. 例外](#4-例外) +- [5. ユーティリティ](#5-ユーティリティ) ---""") - # 機能全体像(静的セクション) + # 1. 概要 sections.append(_OVERVIEW_SECTION) - # --- GenFlux クライアント --- - sections.append("## クライアント") + # 2. クライアント + sections.append("## 2. クライアント") sections.append("") - # External: クラス自身で定義されたメソッドのみ表示(継承元の内部メソッドを除外) genflux_info = _extract_class_info(GenFlux, include_inherited=False) - sections.append(_md_class(genflux_info, heading_level=3)) + sections.append(_md_class(genflux_info, heading_level=3, num_prefix="2.1")) - # --- ConfigClient --- config_client_info = _extract_class_info(ConfigClient, include_inherited=False) - sections.append(_md_class(config_client_info, heading_level=3)) + sections.append(_md_class(config_client_info, heading_level=3, num_prefix="2.2")) - # --- JobsClient --- jobs_client_info = _extract_class_info(JobsClient, include_inherited=False) - sections.append(_md_class(jobs_client_info, heading_level=3)) + sections.append(_md_class(jobs_client_info, heading_level=3, num_prefix="2.3")) - # --- ReportsClient --- reports_client_info = _extract_class_info(ReportsClient, include_inherited=False) - sections.append(_md_class(reports_client_info, heading_level=3)) + sections.append(_md_class(reports_client_info, heading_level=3, num_prefix="2.4")) - # --- EvaluationClient --- eval_client_info = _extract_class_info(EvaluationClient, include_inherited=False) - sections.append(_md_class(eval_client_info, heading_level=3)) + sections.append(_md_class(eval_client_info, heading_level=3, num_prefix="2.5")) - # --- モデル --- + # 3. モデル sections.append("---") sections.append("") - sections.append("## モデル") + sections.append("## 3. モデル") sections.append("") model_classes = [ @@ -664,38 +732,28 @@ def _generate_external_reference() -> str: EvaluationSummary, RedTeamSummary, PolicySummary, CategoryBreakdown, FailedCase, Violation, ] - for model_cls in model_classes: + for i, model_cls in enumerate(model_classes): info = _extract_class_info(model_cls, include_inherited=False) - sections.append(_md_class(info, heading_level=3)) + sections.append(_md_class(info, heading_level=3, num_prefix=f"3.{i + 1}")) - # --- 例外 --- + # 4. 例外 sections.append("---") sections.append("") - sections.append("## 例外") - sections.append("") + sections.append(_EXCEPTIONS_SECTION) - exception_classes = [ - GenFluxError, APIError, AuthenticationError, NotFoundError, - ValidationError, TimeoutError, JobFailedError, RateLimitError, - ConfigNotFoundError, ResourceNotFoundError, - ] - for exc_cls in exception_classes: - info = _extract_class_info(exc_cls, include_inherited=False) - sections.append(_md_class(info, heading_level=3)) - - # --- ユーティリティ --- + # 5. ユーティリティ sections.append("---") sections.append("") - sections.append("## ユーティリティ") + sections.append("## 5. ユーティリティ") sections.append("") pb_info = _extract_class_info(ProgressBar, include_inherited=False) - sections.append(_md_class(pb_info, heading_level=3)) + sections.append(_md_class(pb_info, heading_level=3, num_prefix="5.1")) # create_progress_callback (関数) cb_doc = _parse_google_docstring(inspect.getdoc(create_progress_callback)) cb_sig = _get_signature_str(create_progress_callback, "create_progress_callback") - sections.append(f"### `{cb_sig}`") + sections.append(f"### 5.2 `{cb_sig}`") sections.append("") if cb_doc.summary: sections.append(cb_doc.summary) @@ -785,7 +843,7 @@ def _generate_developer_reference() -> str: -# GenFlux Python SDK - Developer API Reference +# Genflux Python SDK - Developer API Reference 開発者向けの詳細な API リファレンスです。 内部クラス・プライベートメソッドも含みます。 @@ -796,7 +854,7 @@ def _generate_developer_reference() -> str: ## 📋 目次 -- [GenFlux クライアント](#genflux-1) +- [Genflux クライアント](#genflux-1) - [BaseClient(内部)](#baseclient) - [ConfigClient](#configclient) - [JobsClient](#jobsclient) @@ -808,7 +866,7 @@ def _generate_developer_reference() -> str: ---""") - # GenFlux (include private) + # Genflux (include private) sections.append("## クライアント") sections.append("") @@ -908,89 +966,523 @@ def _generate_developer_reference() -> str: # --------------------------------------------------------------------------- _OVERVIEW_SECTION = """\ -## 機能全体像 +## 1. 概要 -GenFlux SDK は、RAG システムの評価を簡単に実行するための包括的な機能を提供します。 +```python +from genflux import GenFlux -### アーキテクチャ概要 +client = GenFlux() # GENFLUX_API_KEY 環境変数を使用 +evaluator = client.evaluation() +result = evaluator.faithfulness( + question="What is Python?", + answer="Python is a programming language.", + contexts=["Python is a high-level programming language..."], +) +print(f"Score: {result.score}") # 0.0 ~ 1.0 ``` -┌─────────────────────────────────────────────────────────────┐ -│ GenFlux Client │ -│ (メインエントリーポイント) │ -└────────────────┬────────────────────────────────────────────┘ - │ - ┌──────────┼──────────┬──────────┬──────────┐ - │ │ │ │ │ - ▼ ▼ ▼ ▼ ▼ -┌──────────┐┌──────────┐┌──────────┐┌──────────┐┌──────────┐ -│ Config ││ Jobs ││ Reports ││Evaluation││ Progress │ -│ Client ││ Client ││ Client ││ Client ││ Display │ -└──────────┘└──────────┘└──────────┘└──────────┘└──────────┘ - │ │ │ │ │ - └───────────┴───────────┴───────────┴───────────┘ - │ - ▼ - ┌──────────────────┐ - │ Backend API │ - │ (Job Queue) │ - └──────────────────┘ -``` -### 主要コンポーネント +### アーキテクチャ + +```mermaid +graph TB + User["Your Code"] --> GF["Genflux Client"] + + GF --> CC["client.configs
ConfigClient"] + GF --> JC["client.jobs
JobsClient"] + GF --> RC["client.reports
ReportsClient"] + GF --> EC["client.evaluation()
EvaluationClient"] -| コンポーネント | 説明 | -|---|---| -| **GenFlux Client** | メインエントリーポイント。認証管理・サブクライアント初期化 | -| **ConfigClient** | RAG API 設定の CRUD 管理 | -| **JobsClient** | 非同期ジョブの作成・監視・キャンセル | -| **EvaluationClient** | 12 種類のメトリックによる評価実行 | -| **ReportsClient** | 評価レポートの取得(サマリー/詳細) | + CC --> API["Genflux Backend API"] + JC --> API + RC --> API + EC --> API -### サポートされる評価メトリック + API --> Queue["Job Queue"] + Queue --> Result["MetricResult
score / reason"] -| メトリック | 説明 | スコア範囲 | + style GF fill:#4A90D9,color:#fff + style EC fill:#7B68EE,color:#fff + style API fill:#2E8B57,color:#fff +``` + +### クライアント構成 + +| クライアント | アクセス方法 | 説明 | |---|---|---| -| **Faithfulness** | 回答が提供された文脈に基づいているか | 0.0 ~ 1.0 (高↑) | -| **Answer Relevancy** | 回答が質問に対して適切に答えているか | 0.0 ~ 1.0 (高↑) | -| **Contextual Relevancy** | 取得された文脈が質問に関連しているか | 0.0 ~ 1.0 (高↑) | -| **Contextual Precision** | 関連性の高い文脈が上位にランクされているか | 0.0 ~ 1.0 (高↑) | -| **Contextual Recall** | 回答の情報が文脈に帰属できるか | 0.0 ~ 1.0 (高↑) | -| **Hallucination** | 回答が文脈にない情報を含んでいるか | 0.0 ~ 1.0 (低↓) | -| **Toxicity** | 回答に有害なコンテンツが含まれるか | 0.0 ~ 1.0 (低↓) | -| **Bias** | 回答に偏見が含まれるか | 0.0 ~ 1.0 (低↓) | +| [`GenFlux`](#genflux-1) | `GenFlux()` | メインクライアント(認証・サブクライアント管理) | +| [`EvaluationClient`](#evaluationclient) | `client.evaluation()` | 8 種類のメトリックによる評価実行 | +| [`ConfigClient`](#configclient) | `client.configs` | RAG API 設定の CRUD | +| [`JobsClient`](#jobsclient) | `client.jobs` | 非同期ジョブの作成・監視・キャンセル | +| [`ReportsClient`](#reportsclient) | `client.reports` | 評価レポートの取得(サマリー/詳細) | + +### 評価メトリック + +| メトリック | メソッド | `contexts` | `ground_truth` | スコア | +|---|---|---|---|---| +| Faithfulness | `evaluator.faithfulness()` | 必須 | — | 0〜1(高いほど良い) | +| Answer Relevancy | `evaluator.answer_relevancy()` | 任意 | — | 0〜1(高いほど良い) | +| Contextual Relevancy | `evaluator.contextual_relevancy()` | 必須 | — | 0〜1(高いほど良い) | +| Contextual Precision | `evaluator.contextual_precision()` | 必須 | — | 0〜1(高いほど良い) | +| Contextual Recall | `evaluator.contextual_recall()` | 必須 | 必須 | 0〜1(高いほど良い) | +| Hallucination | `evaluator.hallucination()` | 必須 | — | 0〜1(低いほど良い) | +| Toxicity | `evaluator.toxicity()` | 任意 | — | 0〜1(低いほど良い) | +| Bias | `evaluator.bias()` | 任意 | — | 0〜1(低いほど良い) | -### 典型的な使用パターン +--- +""" -```python -from genflux import GenFlux +_EXCEPTIONS_SECTION = """\ +## 4. 例外 -# 1. クライアント初期化 -client = GenFlux(api_key="pk_xxx") +すべての例外は `GenFluxError` を基底クラスとしています。 -# 2. 評価実行(シンプル) -evaluator = client.evaluation(config_id="config_123") -result = evaluator.faithfulness( - question="What is Python?", - answer="Python is a programming language.", - contexts=["Python is a high-level programming language..."], +### 4.1 例外一覧 + +| 例外 | 継承元 | HTTP ステータス | 説明 | +|---|---|---|---| +| `GenFluxError` | `Exception` | — | 基底例外クラス | +| `APIError` | `GenFluxError` | — | API リクエスト失敗(基底) | +| `AuthenticationError` | `APIError` | 401 | API Key が無効または未設定 | +| `NotFoundError` | `APIError` | 404 | リソースが見つからない | +| `ValidationError` | `APIError` | 400, 422 | リクエストパラメータが不正 | +| `RateLimitError` | `APIError` | 429 | レート制限超過 | +| `TimeoutError` | `GenFluxError` | — | ジョブのタイムアウト | +| `JobFailedError` | `GenFluxError` | — | ジョブ実行の失敗 | +| `ConfigNotFoundError` | `GenFluxError` | — | 指定した Config が存在しない | +| `ResourceNotFoundError` | `GenFluxError` | — | リソースが見つからない | + +> **Note:** `APIError` 系は HTTP レスポンスに起因する例外です。`status_code` 属性でステータスコードを取得できます。 +> `TimeoutError` / `JobFailedError` はジョブ実行に起因する例外で、HTTP ステータスコードはありません。 + +### 4.2 例外ハンドリング + +```python +from genflux import GenFlux +from genflux.exceptions import ( + AuthenticationError, + RateLimitError, + TimeoutError, + JobFailedError, ) -print(f"Score: {result.score}") # 0.0 ~ 1.0 -# 3. 複数メトリック -faith = evaluator.faithfulness(question, answer, contexts) -relevancy = evaluator.answer_relevancy(question, answer) -toxicity = evaluator.toxicity(question, answer) +client = GenFlux() +evaluator = client.evaluation() -# 4. CI/CD 統合 -if result.score < 0.8: - sys.exit(1) # テスト失敗 +try: + result = evaluator.faithfulness( + question="What is Python?", + answer="Python is a programming language.", + contexts=["Python is a high-level programming language."], + ) +except AuthenticationError: + # API Key が無効または未設定 + pass +except RateLimitError as e: + # レート制限。e.retry_after 秒後にリトライ + pass +except TimeoutError: + # ジョブがタイムアウト + pass +except JobFailedError as e: + # ジョブ実行失敗。e.error_message で詳細を確認 + pass ``` - ---- """ +# --------------------------------------------------------------------------- +# LLM Enrichment Pipeline (3-pass) +# --------------------------------------------------------------------------- + +_CACHE_DIR = _SDK_ROOT / ".cache" / "docs" + + +def _load_openai_client() -> Any: + """OpenAI クライアントを初期化する (.env 対応).""" + try: + from dotenv import load_dotenv + + load_dotenv(_SDK_ROOT / ".env") + except ImportError: + pass + + api_key = os.environ.get("OPENAI_API_KEY") + if not api_key: + print(" ⚠ OPENAI_API_KEY が設定されていません。LLM 改善をスキップします。") + return None + + try: + from openai import OpenAI + + return OpenAI(api_key=api_key, timeout=300.0, max_retries=2) + except ImportError: + print(" ⚠ openai パッケージが見つかりません。`uv sync --group dev` を実行してください。") + return None + + +def _extract_source_summary() -> str: + """ソースコードから関数シグネチャ・docstring を抽出し、ground truth を作成する.""" + from genflux.client import GenFlux + from genflux.clients.config import ConfigClient + from genflux.clients.reports import ReportsClient + from genflux.evaluation import EvaluationClient + from genflux.jobs import JobsClient + from genflux.models.config import Config, ConfigCreate, ConfigUpdate + from genflux.models.job import Job, JobProgress, MetricResult + + summary_parts: list[str] = [] + + classes = [ + GenFlux, ConfigClient, JobsClient, ReportsClient, EvaluationClient, + Config, ConfigCreate, ConfigUpdate, Job, JobProgress, MetricResult, + ] + + for cls in classes: + summary_parts.append(f"### {cls.__name__}") + doc = inspect.getdoc(cls) or "" + if doc: + summary_parts.append(f"Docstring: {doc[:500]}") + + # Public methods + for name, obj in inspect.getmembers(cls): + if name.startswith("_") or not callable(obj): + continue + try: + sig = inspect.signature(obj) + mdoc = inspect.getdoc(obj) or "" + summary_parts.append(f" {name}{sig}") + if mdoc: + summary_parts.append(f" -> {mdoc[:200]}") + except (ValueError, TypeError): + pass + + # Pydantic fields + if hasattr(cls, "model_fields"): + for fname, finfo in cls.model_fields.items(): + type_str = _type_to_str(finfo.annotation) if finfo.annotation else "?" + summary_parts.append(f" field {fname}: {type_str}") + + summary_parts.append("") + + return "\n".join(summary_parts) + + +def _call_openai( + client: Any, + system_prompt: str, + user_prompt: str, + *, + model: str = "gpt-4o", + temperature: float = 0.3, + max_retries: int = 3, +) -> str: + """OpenAI API を呼び出す(リトライ付き).""" + import time + + for attempt in range(max_retries): + try: + response = client.chat.completions.create( + model=model, + temperature=temperature, + timeout=300, + messages=[ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": user_prompt}, + ], + ) + return response.choices[0].message.content or "" + except Exception as e: + if attempt < max_retries - 1: + wait = (attempt + 1) * 10 + print(f" ⚠ API エラー: {e.__class__.__name__}. {wait}秒後にリトライ... ({attempt + 2}/{max_retries})") + time.sleep(wait) + else: + print(f" ❌ API エラー(リトライ上限): {e}") + raise + + +def _clean_llm_output(text: str) -> str: + """LLM 出力から余分なタグ・コードフェンスを除去する.""" + result = text.strip() + # コードフェンス除去 + if result.startswith("```markdown"): + result = result[len("```markdown"):].strip() + elif result.startswith("```md"): + result = result[len("```md"):].strip() + elif result.startswith("```") and not result.startswith("```python") and not result.startswith("```mermaid"): + result = result[3:].strip() + if result.endswith("```"): + result = result[:-3].rstrip() + # タグ除去 + result = re.sub(r"", "", result) + return result.strip() + + +def _split_md_sections(md: str) -> list[tuple[str, str]]: + """Markdown をh2セクション単位で分割する. + + Returns: + [(section_name, section_content), ...] + """ + sections: list[tuple[str, str]] = [] + current_name = "_header" + current_lines: list[str] = [] + + for line in md.split("\n"): + if line.startswith("## ") and not line.startswith("### "): + if current_lines: + sections.append((current_name, "\n".join(current_lines))) + current_name = line.strip("# ").strip() + current_lines = [line] + else: + current_lines.append(line) + + if current_lines: + sections.append((current_name, "\n".join(current_lines))) + + return sections + + +def _rejoin_sections(sections: list[tuple[str, str]]) -> str: + """分割されたセクションを結合する.""" + return "\n".join(content for _, content in sections) + + +def _pass1_enrich(client: Any, raw_md: str, source_summary: str) -> str: + """Pass 1: ドキュメントの説明文をセクション単位で改善する.""" + print(" [Pass 1/3] ドキュメント説明文の改善...") + + system_prompt = """\ +あなたはテクニカルライターです。Python SDK の API リファレンスの一部セクション (Markdown) を改善してください。 + +ルール: +- パラメータ説明が空欄("") や不十分な場合、ソースコード情報をもとに簡潔で分かりやすい日本語の説明を追加する +- 既に十分な説明がある箇所はそのまま残す +- クラスやメソッドの summary が不十分な場合、1-2文で改善する +- Markdown のテーブル構造、見出し、コードブロックは絶対に壊さない +- mermaid ブロックは一切変更しない +- メソッドシグネチャ(`method_name(param: type)` 形式)は一切変更しない +- 型名、パラメータ名、クラス名は絶対に変更しない +- 存在しない機能やパラメータを追加しない(ソースにないものは書かない) +- 新しい見出し(## や ### )を追加しない。既存の見出し構造をそのまま維持する +- 見出しの通し番号は大分類(## 2. クライアント)とクラス(### 2.1 GenFlux)の2階層まで。メソッドの見出し(####)には番号を付けない +- 出力は改善後の Markdown セクションをそのまま返すこと(説明や前置きは不要)""" + + sections = _split_md_sections(raw_md) + enriched_sections: list[tuple[str, str]] = [] + + for name, content in sections: + # ヘッダー・目次・関連ドキュメント・短いセクションはそのまま + if name in ("_header", "目次", "関連ドキュメント") or len(content) < 100: + enriched_sections.append((name, content)) + continue + + print(f" セクション: {name}") + user_prompt = f"""\ +ソースコード情報 (ground truth): + + +{source_summary} + + +以下のセクションを改善してください: + + +{content} +""" + + result = _call_openai(client, system_prompt, user_prompt) + result = _clean_llm_output(result) + enriched_sections.append((name, result)) + + return _rejoin_sections(enriched_sections) + + +def _pass2_hallucination_check(client: Any, enriched_md: str, source_summary: str) -> str: + """Pass 2: ハルシネーションをセクション単位でチェックし修正する.""" + print(" [Pass 2/3] ハルシネーションチェック...") + + system_prompt = """\ +あなたは品質保証エンジニアです。API リファレンスの一部セクション (Markdown) にハルシネーション(事実と異なる記述)がないかチェックしてください。 + +チェック項目: +1. ソースに存在しないメソッド名・パラメータ名・型名が記載されていないか +2. パラメータの型がソースと一致するか +3. 必須/任意の記載がソースのデフォルト値と一致するか +4. メソッドの戻り値の型がソースと一致するか +5. 説明文がソースの実際の動作と矛盾していないか +6. 存在しない例外クラスや属性が記載されていないか + +修正ルール: +- ハルシネーションを発見したら、ソースの情報に基づいて修正する +- 修正できない場合は該当の説明文を削除する(嘘を残すよりは空欄が良い) +- Markdown 構造は絶対に壊さない +- mermaid ブロック、コードブロック、テーブル構造はそのまま維持 +- 問題なければそのまま返す +- 新しい見出し(## や ### )を追加しない。既存の見出し構造をそのまま維持する +- 出力は修正後の Markdown セクションをそのまま返すこと(説明や前置きは不要)""" + + sections = _split_md_sections(enriched_md) + checked_sections: list[tuple[str, str]] = [] + + for name, content in sections: + if name in ("_header", "目次", "関連ドキュメント") or len(content) < 100: + checked_sections.append((name, content)) + continue + + print(f" セクション: {name}") + user_prompt = f"""\ +ソースコード情報 (ground truth): + + +{source_summary} + + +以下のセクションをチェックして、ハルシネーションがあれば修正してください: + + +{content} +""" + + result = _call_openai(client, system_prompt, user_prompt) + result = _clean_llm_output(result) + checked_sections.append((name, result)) + + return _rejoin_sections(checked_sections) + + +def _pass3_ux_review(client: Any, md: str) -> str: + """Pass 3: UX レビュー(読みやすさ・一貫性)をセクション単位で実行.""" + print(" [Pass 3/3] UX レビュー...") + + system_prompt = """\ +あなたは SDK ドキュメントの UX スペシャリストです。API リファレンスの一部セクション (Markdown) の読みやすさとユーザー体験をレビューしてください。 + +チェック項目: +1. 見出しの階層が正しいか(h2 > h3 > h4 の順序) +2. テーブルの列が揃っているか、壊れていないか +3. コードブロックが正しく閉じているか +4. 内部リンク(アンカー)が正しい形式か +5. 日本語の文体が統一されているか(です/ます調で統一) +6. 説明文が冗長すぎないか(1パラメータ1-2文以内) +7. mermaid ブロックの構文が正しいか +8. 空行が適切に入っているか(セクション間に空行) +9. 見出し番号が2階層(2.1, 3.1 等)までに収まっているか(メソッドの #### 見出しに 2.2.1 のような3階層番号があれば削除する) + +修正ルール: +- UX を損なう問題を発見したら修正する +- メソッドシグネチャ、型名、パラメータ名は絶対に変更しない +- 内容の意味を変えない +- Markdown の基本構造(見出しレベル、テーブル、コードブロック)を壊さない +- 新しい見出し(## や ### )を追加しない。既存の見出し構造をそのまま維持する +- 出力は修正後の Markdown セクションをそのまま返すこと(説明や前置きは不要)""" + + sections = _split_md_sections(md) + reviewed_sections: list[tuple[str, str]] = [] + + for name, content in sections: + if name in ("_header", "目次", "関連ドキュメント") or len(content) < 100: + reviewed_sections.append((name, content)) + continue + + print(f" セクション: {name}") + user_prompt = f"""\ +以下のセクションを UX 観点でレビューし、問題があれば修正してください: + + +{content} +""" + + result = _call_openai(client, system_prompt, user_prompt) + result = _clean_llm_output(result) + reviewed_sections.append((name, result)) + + return _rejoin_sections(reviewed_sections) + + +def _compute_source_hash() -> str: + """SDK ソースファイル群 + 生成スクリプトのハッシュを計算する. + + ソースコードが変われば必ずハッシュが変わるため、 + ドキュメントに埋め込んで CI で「make docs し忘れ」を検出できる。 + """ + hasher = hashlib.sha256() + src_dir = _SDK_ROOT / "src" / "genflux" + targets = sorted(src_dir.rglob("*.py")) + [Path(__file__).resolve()] + for path in targets: + hasher.update(path.read_bytes()) + return hasher.hexdigest()[:16] + + +_SOURCE_HASH_PATTERN = re.compile(r"") + + +def _embed_source_hash(md: str, source_hash: str) -> str: + """ドキュメント末尾にソースハッシュを埋め込む(既存があれば置換).""" + tag = f"" + if _SOURCE_HASH_PATTERN.search(md): + return _SOURCE_HASH_PATTERN.sub(tag, md) + return md.rstrip() + "\n\n" + tag + "\n" + + +def _extract_source_hash(md: str) -> str | None: + """ドキュメントからソースハッシュを抽出する.""" + m = _SOURCE_HASH_PATTERN.search(md) + if m: + return m.group().split(": ")[1].rstrip(" ->") + return None + + +def _get_cache_path(raw_md: str, mode: str) -> Path: + """キャッシュファイルのパスを取得する.""" + content_hash = hashlib.sha256(raw_md.encode()).hexdigest()[:16] + return _CACHE_DIR / f"{mode}_{content_hash}.md" + + +def _enrich_with_llm(raw_md: str, *, mode: str = "external", use_cache: bool = True) -> str: + """3-pass LLM パイプラインでドキュメントを改善する. + + Args: + raw_md: ソースから自動生成した Markdown + mode: external or developer + use_cache: キャッシュを使用するか + + Returns: + 改善後の Markdown + """ + # キャッシュチェック + cache_path = _get_cache_path(raw_md, mode) + if use_cache and cache_path.exists(): + print(f" キャッシュを使用: {cache_path.name}") + return cache_path.read_text(encoding="utf-8") + + # OpenAI クライアント初期化 + openai_client = _load_openai_client() + if openai_client is None: + return raw_md + + # Ground truth 抽出 + print(" ソースコードから ground truth を抽出中...") + source_summary = _extract_source_summary() + + # 3-pass pipeline + result = raw_md + result = _pass1_enrich(openai_client, result, source_summary) + result = _pass2_hallucination_check(openai_client, result, source_summary) + result = _pass3_ux_review(openai_client, result) + + # LLM が付与する余分なタグ・フェンスを除去 + result = _clean_llm_output(result) + + # キャッシュ保存 + _CACHE_DIR.mkdir(parents=True, exist_ok=True) + cache_path.write_text(result, encoding="utf-8") + print(f" キャッシュ保存: {cache_path.name}") + + return result + + # --------------------------------------------------------------------------- # メイン # --------------------------------------------------------------------------- @@ -998,7 +1490,7 @@ def _generate_developer_reference() -> str: def main() -> int: """メインエントリーポイント.""" parser = argparse.ArgumentParser( - description="GenFlux SDK API Reference 自動生成", + description="Genflux SDK API Reference 自動生成", ) parser.add_argument( "--mode", @@ -1017,33 +1509,49 @@ def main() -> int: action="store_true", help="生成結果と既存ファイルの差分をチェック(CI用)。差分があれば exit code 1", ) + parser.add_argument( + "--no-cache", + action="store_true", + help="LLM キャッシュを使用せず、常に再生成する", + ) args = parser.parse_args() output_dir: Path = args.output_dir output_dir.mkdir(parents=True, exist_ok=True) - has_diff = False - if args.mode in ("external", "all"): - external_md = _generate_external_reference() - external_path = output_dir / "API_REFERENCE.md" - if args.check: - if _check_diff(external_path, external_md): + # --check モード: ソースハッシュの一致を確認する。 + # LLM 出力は非決定的なので内容比較は不可能。代わりに + # make docs 時に埋め込んだソースハッシュと現在のソースハッシュを比較し、 + # 「ソースを変えたのに make docs していない」を検出する。 + if args.check: + current_hash = _compute_source_hash() + print(f"ソースハッシュ (現在): {current_hash}") + has_diff = False + + doc_files = [] + if args.mode in ("external", "all"): + doc_files.append(("API_REFERENCE.md", "External")) + if args.mode in ("developer", "all"): + doc_files.append(("DEVELOPER_API_REFERENCE.md", "Developer")) + + for filename, label in doc_files: + path = output_dir / filename + if not path.exists(): + print(f" ⚠ {path} が存在しません") has_diff = True - else: - external_path.write_text(external_md, encoding="utf-8") - print(f"✅ External API Reference: {external_path}") + continue - if args.mode in ("developer", "all"): - developer_md = _generate_developer_reference() - developer_path = output_dir / "DEVELOPER_API_REFERENCE.md" - if args.check: - if _check_diff(developer_path, developer_md): + existing = path.read_text(encoding="utf-8") + embedded_hash = _extract_source_hash(existing) + if embedded_hash is None: + print(f" ⚠ {label}: source-hash が埋め込まれていません(make docs を実行してください)") has_diff = True - else: - developer_path.write_text(developer_md, encoding="utf-8") - print(f"✅ Developer API Reference: {developer_path}") + elif embedded_hash != current_hash: + print(f" ⚠ {label}: source-hash 不一致 (埋め込み: {embedded_hash}, 現在: {current_hash})") + has_diff = True + else: + print(f" ✅ {label}: source-hash 一致 ({current_hash})") - if args.check: if has_diff: print("❌ API Reference が最新ではありません。以下を実行してください:") print(" make docs") @@ -1051,37 +1559,32 @@ def main() -> int: print("✅ API Reference は最新です。") return 0 - return 0 - - -def _check_diff(path: Path, new_content: str) -> bool: - """既存ファイルと生成内容の差分をチェックする. - - タイムスタンプ行は無視して比較する。 + # 通常モード: ドキュメント生成 + LLM enrichment + ソースハッシュ埋め込み + source_hash = _compute_source_hash() - Args: - path: 既存ファイルのパス - new_content: 新しく生成された内容 - - Returns: - 差分がある場合 True - """ - if not path.exists(): - print(f" ⚠ {path} が存在しません") - return True - - existing = path.read_text(encoding="utf-8") - - # タイムスタンプ行を除去して比較 - ts_pattern = re.compile(r"|^\*Auto-generated at.*$", re.MULTILINE) - existing_clean = ts_pattern.sub("", existing).strip() - new_clean = ts_pattern.sub("", new_content).strip() + if args.mode in ("external", "all"): + external_md = _generate_external_reference() + print("\n🤖 External API Reference を LLM で改善中...") + external_md = _enrich_with_llm( + external_md, mode="external", use_cache=not args.no_cache, + ) + external_md = _embed_source_hash(external_md, source_hash) + external_path = output_dir / "API_REFERENCE.md" + external_path.write_text(external_md, encoding="utf-8") + print(f"✅ External API Reference: {external_path}") - if existing_clean != new_clean: - print(f" ⚠ {path} に差分があります") - return True + if args.mode in ("developer", "all"): + developer_md = _generate_developer_reference() + print("\n🤖 Developer API Reference を LLM で改善中...") + developer_md = _enrich_with_llm( + developer_md, mode="developer", use_cache=not args.no_cache, + ) + developer_md = _embed_source_hash(developer_md, source_hash) + developer_path = output_dir / "DEVELOPER_API_REFERENCE.md" + developer_path.write_text(developer_md, encoding="utf-8") + print(f"✅ Developer API Reference: {developer_path}") - return False + return 0 if __name__ == "__main__": diff --git a/scripts/generate_llms_txt.py b/scripts/generate_llms_txt.py index 91d715a..4a9d922 100644 --- a/scripts/generate_llms_txt.py +++ b/scripts/generate_llms_txt.py @@ -209,7 +209,7 @@ def _collect_sdk_info() -> SDKInfo: # --- Public API --- public_api = list(gf.__all__) - # --- GenFlux Client --- + # --- Genflux Client --- def _client_methods(cls: type) -> list[tuple[str, str, str]]: methods = [] for name, obj in _get_public_methods(cls): @@ -334,12 +334,12 @@ def _generate_llms_txt(info: SDKInfo) -> str: lines: list[str] = [] # ── H1 (required) ── - lines.append("# GenFlux Python SDK") + lines.append("# Genflux Python SDK") lines.append("") # ── Blockquote (summary) ── lines.append( - "> GenFlux Python SDK は RAG(Retrieval-Augmented Generation)システムの" + "> Genflux Python SDK は RAG(Retrieval-Augmented Generation)システムの" "**評価・セキュリティテスト・ポリシーチェック**を Python から実行するための" "公式クライアントライブラリです。" "同期的な API の裏で非同期 Job をポーリングし、結果を返すアーキテクチャを採用しています。" @@ -440,7 +440,7 @@ def _generate_llms_txt(info: SDKInfo) -> str: lines.append("```") lines.append("src/genflux/") lines.append("├── __init__.py # Public API (__all__) — single source of truth") - lines.append("├── client.py # GenFlux main client (entry point)") + lines.append("├── client.py # Genflux main client (entry point)") lines.append("├── evaluation.py # EvaluationClient (12 metric methods)") lines.append("├── jobs.py # JobsClient (create / wait / cancel jobs)") lines.append("├── progress.py # ProgressBar / create_progress_callback") @@ -527,7 +527,7 @@ def _generate_llms_txt(info: SDKInfo) -> str: lines.append("") lines.append( "- [Backend API Reference](docs/BACKEND_API_REFERENCE.md):" - " REST API endpoints of the GenFlux Platform backend" + " REST API endpoints of the Genflux Platform backend" ) lines.append( "- [Test Evaluation Sheet](docs/TEST_EVALUATION_SHEET.md):" @@ -551,12 +551,12 @@ def _generate_llms_full_txt(info: SDKInfo) -> str: lines: list[str] = [] # ── H1 ── - lines.append("# GenFlux Python SDK — Full Context for LLMs") + lines.append("# Genflux Python SDK — Full Context for LLMs") lines.append("") # ── Blockquote ── lines.append( - "> GenFlux Python SDK は RAG(Retrieval-Augmented Generation)システムの" + "> Genflux Python SDK は RAG(Retrieval-Augmented Generation)システムの" "**評価・セキュリティテスト・ポリシーチェック**を Python から実行するための" "公式クライアントライブラリです。" "このファイルには LLM がコードを生成・修正するために必要な全 API 情報が含まれています。" @@ -671,8 +671,8 @@ def _generate_llms_full_txt(info: SDKInfo) -> str: lines.append("```") lines.append("") - # ── GenFlux Client ── - lines.append("## GenFlux Client") + # ── Genflux Client ── + lines.append("## Genflux Client") lines.append("") lines.append("```python") lines.append("@dataclass") @@ -795,7 +795,7 @@ def _generate_llms_full_txt(info: SDKInfo) -> str: lines.append(" ├── APIError (status_code, message, details)") lines.append(" │ ├── AuthenticationError (401)") lines.append(" │ ├── NotFoundError (404)") - lines.append(" │ ├── ValidationError (422)") + lines.append(" │ ├── ValidationError (400, 422)") lines.append(" │ └── RateLimitError (429, retry_after)") lines.append(" ├── TimeoutError (operation, timeout, job_id)") lines.append(" ├── JobFailedError (job_id, error_message)") @@ -841,7 +841,7 @@ def _generate_llms_full_txt(info: SDKInfo) -> str: lines.append("genflux-python-sdk/") lines.append("├── src/genflux/ # SDK source") lines.append("│ ├── __init__.py # Public API (__all__)") - lines.append("│ ├── client.py # GenFlux main client") + lines.append("│ ├── client.py # Genflux main client") lines.append("│ ├── evaluation.py # EvaluationClient") lines.append("│ ├── jobs.py # JobsClient") lines.append("│ ├── progress.py # Progress display utilities") @@ -931,7 +931,7 @@ def _check_diff(path: Path, new_content: str) -> bool: def main() -> int: """メインエントリーポイント.""" parser = argparse.ArgumentParser( - description="Generate llms.txt and llms-full.txt for the GenFlux Python SDK", + description="Generate llms.txt and llms-full.txt for the Genflux Python SDK", ) parser.add_argument( "--check", diff --git a/src/genflux/client.py b/src/genflux/client.py index b8bf561..343f903 100644 --- a/src/genflux/client.py +++ b/src/genflux/client.py @@ -17,7 +17,7 @@ @dataclass class GenFlux: - """GenFlux API Client. + """GenFlux APIクライアント。 Args: api_key: API key for authentication. If not provided, uses GENFLUX_API_KEY env var. @@ -25,7 +25,7 @@ class GenFlux: or constructs from environment setting. environment: Environment name ("local", "dev", or "prod"). Uses GENFLUX_ENVIRONMENT env var if not provided. Defaults to "prod". - timeout: Request timeout in seconds (default: 60) + timeout (float): Request timeout in seconds (default: 60.0) Example: >>> from genflux import GenFlux @@ -84,7 +84,7 @@ def __post_init__(self) -> None: self.jobs = JobsClient(self) def evaluation(self, config_id: str | None = None) -> EvaluationClient: - """Create an evaluation client for the given config. + """指定された設定で評価クライアントを作成します。 Args: config_id: Config ID to use for evaluations (optional, uses default if not provided) @@ -113,7 +113,7 @@ def evaluation(self, config_id: str | None = None) -> EvaluationClient: return EvaluationClient(self.jobs, config_id) def _get_headers(self) -> dict[str, str]: - """Get HTTP headers for API requests. + """APIリクエスト用のHTTPヘッダーを取得します。 Returns: Dictionary of headers @@ -128,7 +128,7 @@ def _get_headers(self) -> dict[str, str]: return headers def _post(self, path: str, data: dict[str, Any]) -> dict[str, Any]: - """Send POST request to API. + """APIにPOSTリクエストを送信します。 Args: path: API endpoint path @@ -149,7 +149,7 @@ def _post(self, path: str, data: dict[str, Any]) -> dict[str, Any]: raise # Never reached, but makes type checker happy def _get(self, path: str) -> dict[str, Any]: - """Send GET request to API. + """APIにGETリクエストを送信します。 Args: path: API endpoint path @@ -169,7 +169,7 @@ def _get(self, path: str) -> dict[str, Any]: raise # Never reached, but makes type checker happy def _put(self, path: str, data: dict[str, Any]) -> dict[str, Any]: - """Send PUT request to API. + """APIにPUTリクエストを送信します。 Args: path: API endpoint path @@ -190,7 +190,7 @@ def _put(self, path: str, data: dict[str, Any]) -> dict[str, Any]: raise # Never reached, but makes type checker happy def _delete(self, path: str) -> None: - """Send DELETE request to API. + """APIにDELETEリクエストを送信します。 Args: path: API endpoint path @@ -205,7 +205,7 @@ def _delete(self, path: str) -> None: self._handle_http_error(e) def _handle_http_error(self, error: httpx.HTTPStatusError) -> None: - """Handle HTTP errors and raise appropriate exceptions. + """HTTPエラーを処理し、適切な例外を発生させます。 Args: error: HTTP status error @@ -253,6 +253,6 @@ def _handle_http_error(self, error: httpx.HTTPStatusError) -> None: raise APIError(status_code, message, details) def __del__(self) -> None: - """Clean up HTTP client.""" + """HTTPクライアントをクリーンアップします。""" if hasattr(self, "_http_client"): self._http_client.close() diff --git a/src/genflux/clients/base.py b/src/genflux/clients/base.py index 971cc18..ef50b39 100644 --- a/src/genflux/clients/base.py +++ b/src/genflux/clients/base.py @@ -18,7 +18,7 @@ class BaseClient: - """Base HTTP client for GenFlux API.""" + """GenFlux API用の基底HTTPクライアント。""" def __init__( self, @@ -26,7 +26,7 @@ def __init__( base_url: str | None = None, timeout: int = 30, ): - """Initialize base client. + """基底クライアントを初期化します。 Args: api_key: API key for authentication (optional) @@ -63,11 +63,11 @@ def __exit__(self, exc_type, exc_val, exc_tb): self.close() def close(self): - """Close HTTP client.""" + """HTTPクライアントを閉じます。""" self._client.close() def _get_headers(self) -> dict[str, str]: - """Get request headers with authentication. + """認証付きのリクエストヘッダーを取得します。 Returns: Request headers @@ -78,7 +78,7 @@ def _get_headers(self) -> dict[str, str]: return headers def _build_url(self, path: str) -> str: - """Build full URL from path. + """パスから完全なURLを構築します。 Args: path: API path (e.g., "/configs") @@ -89,7 +89,7 @@ def _build_url(self, path: str) -> str: return urljoin(self.base_url + "/", path.lstrip("/")) def _handle_error(self, response: httpx.Response) -> None: - """Handle API error responses. + """APIエラーレスポンスを処理します。 Args: response: HTTP response @@ -136,7 +136,7 @@ def _handle_error(self, response: httpx.Response) -> None: raise APIError(response.status_code, message, details) def get(self, path: str, **kwargs: Any) -> dict[str, Any]: - """Send GET request. + """GETリクエストを送信します。 Args: path: API path @@ -155,7 +155,7 @@ def get(self, path: str, **kwargs: Any) -> dict[str, Any]: return response.json() def post(self, path: str, json: dict[str, Any] | None = None, **kwargs: Any) -> dict[str, Any]: - """Send POST request. + """POSTリクエストを送信します。 Args: path: API path @@ -175,7 +175,7 @@ def post(self, path: str, json: dict[str, Any] | None = None, **kwargs: Any) -> return response.json() def put(self, path: str, json: dict[str, Any] | None = None, **kwargs: Any) -> dict[str, Any]: - """Send PUT request. + """PUTリクエストを送信します。 Args: path: API path @@ -195,7 +195,7 @@ def put(self, path: str, json: dict[str, Any] | None = None, **kwargs: Any) -> d return response.json() def delete(self, path: str, **kwargs: Any) -> dict[str, Any] | None: - """Send DELETE request. + """DELETEリクエストを送信します。 Args: path: API path diff --git a/src/genflux/clients/config.py b/src/genflux/clients/config.py index 0ba9952..64be138 100644 --- a/src/genflux/clients/config.py +++ b/src/genflux/clients/config.py @@ -7,10 +7,10 @@ class ConfigClient(BaseClient): - """Client for managing evaluation configs.""" + """評価設定管理用クライアント。""" def create(self, config: ConfigCreate) -> Config: - """Create a new config. + """新しい設定を作成します。 Args: config: Config creation parameters @@ -48,7 +48,7 @@ def create(self, config: ConfigCreate) -> Config: return Config.model_validate(response_data) def get(self, config_id: str | UUID) -> Config: # type: ignore[override] - """Get config by ID. + """IDで設定を取得します。 Args: config_id: Config ID @@ -70,7 +70,7 @@ def get(self, config_id: str | UUID) -> Config: # type: ignore[override] return Config.model_validate(response_data) def list(self, limit: int = 100, offset: int = 0) -> ConfigListResponse: - """List all configs. + """すべての設定を一覧取得します。 Args: limit: Maximum number of configs to return @@ -93,7 +93,7 @@ def list(self, limit: int = 100, offset: int = 0) -> ConfigListResponse: return ConfigListResponse.model_validate(response_data) def update(self, config_id: str | UUID, config_update: ConfigUpdate) -> Config: - """Update config. + """設定を更新します。 Args: config_id: Config ID @@ -125,7 +125,7 @@ def update(self, config_id: str | UUID, config_update: ConfigUpdate) -> Config: return Config.model_validate(response_data) def delete(self, config_id: str | UUID) -> bool: # type: ignore[override] - """Delete config. + """設定を削除します。 Args: config_id: Config ID diff --git a/src/genflux/clients/reports.py b/src/genflux/clients/reports.py index 9d22700..bedfeaf 100644 --- a/src/genflux/clients/reports.py +++ b/src/genflux/clients/reports.py @@ -9,14 +9,14 @@ class ReportsClient(BaseClient): - """Client for Reports API.""" + """レポートAPI用クライアント。""" def get( # type: ignore[override] self, report_id: str | UUID, view: Literal["summary", "details"] = "summary", ) -> Report: - """Get a report by ID. + """IDでレポートを取得します。 Args: report_id: Report ID (= Job ID) diff --git a/src/genflux/evaluation.py b/src/genflux/evaluation.py index 2757e81..f00d9de 100644 --- a/src/genflux/evaluation.py +++ b/src/genflux/evaluation.py @@ -12,10 +12,10 @@ class EvaluationClient: - """Client for evaluation operations. + """評価操作用クライアント。 - Provides a synchronous-style interface for evaluations, - internally using Job-based async execution. + 同期スタイルのインターフェースを提供し、 + 内部的にJobベースの非同期実行を使用します。 """ def __init__(self, jobs_client: JobsClient, config_id: str | None): @@ -39,13 +39,20 @@ def evaluate( callback: Callable[[Job], None] | None = None, show_progress: bool = True, ) -> MetricResult: - """Evaluate a single question-answer pair. + """単一の質問-回答ペアを評価します。 - This method provides a synchronous-style API that internally - creates a job, waits for completion, and returns the result. + このメソッドは内部的にジョブを作成し、完了を待機して結果を返す + 同期スタイルのAPIを提供します。 Args: - metric: Metric name (e.g., 'faithfulness', 'answer_relevancy') + metric: Metric name to evaluate. Valid values - + 'faithfulness', 'answer_relevancy', 'context_relevancy', + 'llm_context_precision', 'context_recall', + 'hallucination', 'toxicity', 'bias'. + (メソッド名と内部メトリック名の対応: + contextual_relevancy() → 'context_relevancy', + contextual_precision() → 'llm_context_precision', + contextual_recall() → 'context_recall') question: Question text answer: Answer text contexts: Context/retrieval texts (optional) @@ -179,7 +186,7 @@ def faithfulness( timeout: int = 300, on_progress: Callable[[Job], None] | None = None, ) -> MetricResult: - """Evaluate faithfulness (answers based on contexts). + """忠実性を評価します(回答がコンテキストに基づいているか)。 Args: question: Question text @@ -215,7 +222,7 @@ def answer_relevancy( contexts: list[str] | None = None, timeout: int = 300, ) -> MetricResult: - """Evaluate answer relevancy (answer addresses the question). + """回答の関連性を評価します(回答が質問に対応しているか)。 Args: question: Question text @@ -247,7 +254,7 @@ def contextual_relevancy( contexts: list[str], timeout: int = 300, ) -> MetricResult: - """Evaluate contextual relevancy (contexts are relevant to question). + """コンテキストの関連性を評価します(コンテキストが質問に関連しているか)。 Args: question: Question text @@ -280,7 +287,7 @@ def contextual_precision( contexts: list[str], timeout: int = 300, ) -> MetricResult: - """Evaluate contextual precision (relevant contexts ranked higher). + """コンテキストの精度を評価します(関連するコンテキストが上位にランクされているか)。 Args: question: Question text @@ -307,7 +314,7 @@ def contextual_recall( ground_truth: str, timeout: int = 300, ) -> MetricResult: - """Evaluate contextual recall (answer can be attributed to contexts). + """コンテキストの再現率を評価します(回答がコンテキストに帰属できるか)。 Args: question: Question text @@ -335,7 +342,7 @@ def hallucination( contexts: list[str], timeout: int = 300, ) -> MetricResult: - """Evaluate hallucination (answer contains information not in contexts). + """ハルシネーションを評価します(回答にコンテキストにない情報が含まれているか)。 Args: question: Question text @@ -361,7 +368,7 @@ def toxicity( contexts: list[str] | None = None, timeout: int = 300, ) -> MetricResult: - """Evaluate toxicity (answer contains toxic content). + """有害性を評価します(回答に有害なコンテンツが含まれているか)。 Args: question: Question text @@ -387,7 +394,7 @@ def bias( contexts: list[str] | None = None, timeout: int = 300, ) -> MetricResult: - """Evaluate bias (answer contains biased content). + """バイアスを評価します(回答に偏りのあるコンテンツが含まれているか)。 Args: question: Question text diff --git a/src/genflux/exceptions/api.py b/src/genflux/exceptions/api.py index b1505ec..dc9be14 100644 --- a/src/genflux/exceptions/api.py +++ b/src/genflux/exceptions/api.py @@ -73,13 +73,13 @@ def _parse_not_found_from_response( class GenFluxError(Exception): - """Base exception for GenFlux SDK.""" + """GenFlux SDKの基底例外クラス。""" pass class APIError(GenFluxError): - """API request failed.""" + """APIリクエストが失敗しました。""" def __init__(self, status_code: int, message: str, details: dict | None = None): """Initialize API error. @@ -96,7 +96,7 @@ def __init__(self, status_code: int, message: str, details: dict | None = None): class AuthenticationError(APIError): - """Authentication failed (401).""" + """認証に失敗しました(401)。""" def __init__(self, message: str = "Invalid API Key", details: dict | None = None): """Initialize authentication error. @@ -109,7 +109,7 @@ def __init__(self, message: str = "Invalid API Key", details: dict | None = None class NotFoundError(APIError): - """Resource not found (404).""" + """リソースが見つかりません(404)。""" def __init__( self, @@ -132,7 +132,7 @@ def __init__( class ValidationError(APIError): - """Validation error (422).""" + """バリデーションエラー(400, 422)。""" def __init__(self, message: str, details: dict | None = None): """Initialize validation error. @@ -145,7 +145,7 @@ def __init__(self, message: str, details: dict | None = None): class TimeoutError(GenFluxError): - """Operation timed out.""" + """操作がタイムアウトしました。""" def __init__( self, @@ -183,7 +183,7 @@ def __init__( class JobFailedError(GenFluxError): - """Job execution failed.""" + """ジョブの実行に失敗しました。""" def __init__( self, @@ -205,7 +205,7 @@ def __init__( class RateLimitError(APIError): - """Rate limit exceeded (429).""" + """レート制限を超過しました(429)。""" def __init__( self, @@ -225,7 +225,7 @@ def __init__( class ConfigNotFoundError(GenFluxError): - """Config not found.""" + """設定が見つかりません。""" def __init__(self, config_id: str | None = None): """Initialize config not found error. @@ -243,7 +243,7 @@ def __init__(self, config_id: str | None = None): class ResourceNotFoundError(GenFluxError): - """Generic resource not found error.""" + """汎用リソースが見つからないエラー。""" def __init__(self, resource_type: str, resource_id: str): """Initialize resource not found error. diff --git a/src/genflux/jobs.py b/src/genflux/jobs.py index bfb5596..afbea10 100644 --- a/src/genflux/jobs.py +++ b/src/genflux/jobs.py @@ -28,7 +28,7 @@ class JobsClient: - """Client for Job (Execution) management.""" + """ジョブ(実行)管理用クライアント。""" def __init__(self, client: "GenFlux"): """Initialize JobsClient. @@ -44,7 +44,7 @@ def create( config_id: str | None = None, data: dict[str, Any] | None = None, ) -> Job: - """Create a new job. + """新しいジョブを作成します。 Args: execution_type: Execution type (e.g., 'quick_evaluate', 'evaluation') @@ -100,7 +100,7 @@ def list( execution_type: str | None = None, limit: int = 100, ) -> list[Job]: - """List jobs. + """ジョブ一覧を取得します。 Args: status: Filter by status (e.g., 'completed', 'running', 'failed') @@ -138,7 +138,7 @@ def list( return [Job.from_dict(job_data) for job_data in jobs_data] def get(self, job_id: str) -> Job: - """Get job by ID. + """IDでジョブを取得します。 Args: job_id: Job ID @@ -170,7 +170,7 @@ def wait( poll_interval: float = 5.0, callback: Callable[[Job], None] | None = None, ) -> Job: - """Wait for job completion. + """ジョブの完了を待機します。 Args: job_id: Job ID to wait for @@ -275,7 +275,7 @@ def wait( ) def cancel(self, job_id: str) -> Job: - """Cancel a running job. + """実行中のジョブをキャンセルします。 Args: job_id: Job ID to cancel diff --git a/src/genflux/models/config.py b/src/genflux/models/config.py index 8d1d0ac..3c68698 100644 --- a/src/genflux/models/config.py +++ b/src/genflux/models/config.py @@ -8,7 +8,7 @@ class ApiSettings(BaseModel): - """API settings configuration.""" + """API設定。""" api_endpoint: str auth_type: str @@ -19,7 +19,7 @@ class ApiSettings(BaseModel): class RagQualityConfig(BaseModel): - """RAG Quality evaluation configuration.""" + """RAG品質評価の設定。""" evaluation_metrics: dict[str, Any] = Field(default_factory=dict) total_prompt_count: int | None = None @@ -29,7 +29,7 @@ class RagQualityConfig(BaseModel): class RedteamConfig(BaseModel): - """RedTeam evaluation configuration.""" + """RedTeam評価の設定。""" redteam_objectives: list[str] | None = None redteam_max_turns: int | None = None @@ -37,14 +37,14 @@ class RedteamConfig(BaseModel): class PolicyCheckConfig(BaseModel): - """Policy check configuration.""" + """ポリシーチェックの設定。""" compliance_frameworks: list[str] | None = None policy_compliance_rate_threshold: float | None = None class Config(BaseModel): - """Complete config object.""" + """完全な設定オブジェクト。""" id: UUID tenant_id: UUID @@ -61,7 +61,7 @@ class Config(BaseModel): class ConfigCreate(BaseModel): - """Request model for creating a config.""" + """設定作成用のリクエストモデル。""" name: str = Field(..., description="Config name") description: str | None = Field(None, description="Config description") @@ -93,7 +93,7 @@ class ConfigCreate(BaseModel): class ConfigUpdate(BaseModel): - """Request model for updating a config.""" + """設定更新用のリクエストモデル。""" name: str | None = None description: str | None = None @@ -125,7 +125,7 @@ class ConfigUpdate(BaseModel): class ConfigListResponse(BaseModel): - """Response model for listing configs.""" + """設定一覧取得用のレスポンスモデル。""" configs: list[Config] total: int diff --git a/src/genflux/models/job.py b/src/genflux/models/job.py index f191c4c..8a3e8c4 100644 --- a/src/genflux/models/job.py +++ b/src/genflux/models/job.py @@ -7,7 +7,7 @@ @dataclass class JobProgress: - """Job progress information.""" + """ジョブの進捗情報。""" percentage: float message: str @@ -15,7 +15,7 @@ class JobProgress: @dataclass class Job: - """Job (Execution) model.""" + """ジョブ(実行)モデル。""" id: str tenant_id: str @@ -36,7 +36,7 @@ class Job: @classmethod def from_dict(cls, data: dict[str, Any]) -> "Job": - """Create Job from API response dict. + """APIレスポンスの辞書からJobを作成します。 Args: data: API response dictionary @@ -79,28 +79,28 @@ def from_dict(cls, data: dict[str, Any]) -> "Job": @property def is_completed(self) -> bool: - """Check if job is completed.""" + """ジョブが完了したかどうかを確認します。""" return self.status == "completed" @property def is_failed(self) -> bool: - """Check if job failed.""" + """ジョブが失敗したかどうかを確認します。""" return self.status == "failed" @property def is_running(self) -> bool: - """Check if job is running.""" + """ジョブが実行中かどうかを確認します。""" return self.status == "running" @property def is_pending(self) -> bool: - """Check if job is pending (queued or pending).""" + """ジョブが待機中(キュー待ちまたはペンディング)かどうかを確認します。""" return self.status in ("pending", "queued") @dataclass class MetricResult: - """Single metric evaluation result.""" + """単一メトリックの評価結果。""" metric: str score: float diff --git a/src/genflux/models/report.py b/src/genflux/models/report.py index 83e387b..d3ec350 100644 --- a/src/genflux/models/report.py +++ b/src/genflux/models/report.py @@ -85,7 +85,7 @@ class ReportDetails(BaseModel): class Report(BaseModel): - """Report model.""" + """レポートモデル。""" model_config = {"from_attributes": True} diff --git a/src/genflux/progress.py b/src/genflux/progress.py index 4295414..39630dc 100644 --- a/src/genflux/progress.py +++ b/src/genflux/progress.py @@ -10,7 +10,7 @@ @dataclass class ProgressBar: - """Simple progress bar for terminal output.""" + """ターミナル出力用のシンプルなプログレスバー。""" total: int = 100 width: int = 50 @@ -32,7 +32,7 @@ def update( *, indeterminate: bool = False, ) -> None: - """Update progress bar. + """プログレスバーを更新します。 Args: current: Current progress value (0 to total) @@ -59,7 +59,7 @@ def update( print(file=self.file) # New line on complete def update_from_job(self, job: Job) -> None: - """Update progress bar from Job object. + """Jobオブジェクトからプログレスバーを更新します。 Args: job: Job object with progress information @@ -84,7 +84,7 @@ def update_from_job(self, job: Job) -> None: def create_progress_callback(enable: bool = True) -> Callable[[Job], None]: - """Create a progress callback for job.wait(). + """job.wait()用のプログレスコールバックを作成します。 Args: enable: Whether to enable progress display (default: True) diff --git a/uv.lock b/uv.lock index 89e6e60..42f4c4b 100644 --- a/uv.lock +++ b/uv.lock @@ -301,6 +301,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, ] +[[package]] +name = "distro" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, +] + [[package]] name = "docutils" version = "0.22.4" @@ -321,7 +330,7 @@ wheels = [ [[package]] name = "genflux" -version = "0.1.0" +version = "0.1.2" source = { editable = "." } dependencies = [ { name = "httpx" }, @@ -332,11 +341,13 @@ dependencies = [ [package.dev-dependencies] dev = [ { name = "build" }, + { name = "openai" }, { name = "pip-audit" }, { name = "pip-licenses" }, { name = "pre-commit" }, { name = "pyright" }, { name = "pytest" }, + { name = "python-dotenv" }, { name = "ruff" }, { name = "twine" }, ] @@ -351,11 +362,13 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ { name = "build", specifier = ">=1.2.0" }, + { name = "openai", specifier = ">=1.0.0" }, { name = "pip-audit", specifier = ">=2.7.0" }, { name = "pip-licenses", specifier = ">=4.4.0" }, { name = "pre-commit", specifier = ">=4.2.0" }, { name = "pyright", specifier = ">=1.1.402" }, { name = "pytest", specifier = ">=8.4.1" }, + { name = "python-dotenv", specifier = ">=1.0.0" }, { name = "ruff", specifier = ">=0.11.4" }, { name = "twine", specifier = ">=6.0.0" }, ] @@ -493,6 +506,91 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b2/a3/e137168c9c44d18eff0376253da9f1e9234d0239e0ee230d2fee6cea8e55/jeepney-0.9.0-py3-none-any.whl", hash = "sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683", size = 49010, upload-time = "2025-02-27T18:51:00.104Z" }, ] +[[package]] +name = "jiter" +version = "0.13.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0d/5e/4ec91646aee381d01cdb9974e30882c9cd3b8c5d1079d6b5ff4af522439a/jiter-0.13.0.tar.gz", hash = "sha256:f2839f9c2c7e2dffc1bc5929a510e14ce0a946be9365fd1219e7ef342dae14f4", size = 164847, upload-time = "2026-02-02T12:37:56.441Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/29/499f8c9eaa8a16751b1c0e45e6f5f1761d180da873d417996cc7bddc8eef/jiter-0.13.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ea026e70a9a28ebbdddcbcf0f1323128a8db66898a06eaad3a4e62d2f554d096", size = 311157, upload-time = "2026-02-02T12:35:37.758Z" }, + { url = "https://files.pythonhosted.org/packages/50/f6/566364c777d2ab450b92100bea11333c64c38d32caf8dc378b48e5b20c46/jiter-0.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:66aa3e663840152d18cc8ff1e4faad3dd181373491b9cfdc6004b92198d67911", size = 319729, upload-time = "2026-02-02T12:35:39.246Z" }, + { url = "https://files.pythonhosted.org/packages/73/dd/560f13ec5e4f116d8ad2658781646cca91b617ae3b8758d4a5076b278f70/jiter-0.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3524798e70655ff19aec58c7d05adb1f074fecff62da857ea9be2b908b6d701", size = 354766, upload-time = "2026-02-02T12:35:40.662Z" }, + { url = "https://files.pythonhosted.org/packages/7c/0d/061faffcfe94608cbc28a0d42a77a74222bdf5055ccdbe5fd2292b94f510/jiter-0.13.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ec7e287d7fbd02cb6e22f9a00dd9c9cd504c40a61f2c61e7e1f9690a82726b4c", size = 362587, upload-time = "2026-02-02T12:35:42.025Z" }, + { url = "https://files.pythonhosted.org/packages/92/c9/c66a7864982fd38a9773ec6e932e0398d1262677b8c60faecd02ffb67bf3/jiter-0.13.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:47455245307e4debf2ce6c6e65a717550a0244231240dcf3b8f7d64e4c2f22f4", size = 487537, upload-time = "2026-02-02T12:35:43.459Z" }, + { url = "https://files.pythonhosted.org/packages/6c/86/84eb4352cd3668f16d1a88929b5888a3fe0418ea8c1dfc2ad4e7bf6e069a/jiter-0.13.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ee9da221dca6e0429c2704c1b3655fe7b025204a71d4d9b73390c759d776d165", size = 373717, upload-time = "2026-02-02T12:35:44.928Z" }, + { url = "https://files.pythonhosted.org/packages/6e/09/9fe4c159358176f82d4390407a03f506a8659ed13ca3ac93a843402acecf/jiter-0.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24ab43126d5e05f3d53a36a8e11eb2f23304c6c1117844aaaf9a0aa5e40b5018", size = 362683, upload-time = "2026-02-02T12:35:46.636Z" }, + { url = "https://files.pythonhosted.org/packages/c9/5e/85f3ab9caca0c1d0897937d378b4a515cae9e119730563572361ea0c48ae/jiter-0.13.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9da38b4fedde4fb528c740c2564628fbab737166a0e73d6d46cb4bb5463ff411", size = 392345, upload-time = "2026-02-02T12:35:48.088Z" }, + { url = "https://files.pythonhosted.org/packages/12/4c/05b8629ad546191939e6f0c2f17e29f542a398f4a52fb987bc70b6d1eb8b/jiter-0.13.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0b34c519e17658ed88d5047999a93547f8889f3c1824120c26ad6be5f27b6cf5", size = 517775, upload-time = "2026-02-02T12:35:49.482Z" }, + { url = "https://files.pythonhosted.org/packages/4d/88/367ea2eb6bc582c7052e4baf5ddf57ebe5ab924a88e0e09830dfb585c02d/jiter-0.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d2a6394e6af690d462310a86b53c47ad75ac8c21dc79f120714ea449979cb1d3", size = 551325, upload-time = "2026-02-02T12:35:51.104Z" }, + { url = "https://files.pythonhosted.org/packages/f3/12/fa377ffb94a2f28c41afaed093e0d70cfe512035d5ecb0cad0ae4792d35e/jiter-0.13.0-cp311-cp311-win32.whl", hash = "sha256:0f0c065695f616a27c920a56ad0d4fc46415ef8b806bf8fc1cacf25002bd24e1", size = 204709, upload-time = "2026-02-02T12:35:52.467Z" }, + { url = "https://files.pythonhosted.org/packages/cb/16/8e8203ce92f844dfcd3d9d6a5a7322c77077248dbb12da52d23193a839cd/jiter-0.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:0733312953b909688ae3c2d58d043aa040f9f1a6a75693defed7bc2cc4bf2654", size = 204560, upload-time = "2026-02-02T12:35:53.925Z" }, + { url = "https://files.pythonhosted.org/packages/44/26/97cc40663deb17b9e13c3a5cf29251788c271b18ee4d262c8f94798b8336/jiter-0.13.0-cp311-cp311-win_arm64.whl", hash = "sha256:5d9b34ad56761b3bf0fbe8f7e55468704107608512350962d3317ffd7a4382d5", size = 189608, upload-time = "2026-02-02T12:35:55.304Z" }, + { url = "https://files.pythonhosted.org/packages/2e/30/7687e4f87086829955013ca12a9233523349767f69653ebc27036313def9/jiter-0.13.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0a2bd69fc1d902e89925fc34d1da51b2128019423d7b339a45d9e99c894e0663", size = 307958, upload-time = "2026-02-02T12:35:57.165Z" }, + { url = "https://files.pythonhosted.org/packages/c3/27/e57f9a783246ed95481e6749cc5002a8a767a73177a83c63ea71f0528b90/jiter-0.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f917a04240ef31898182f76a332f508f2cc4b57d2b4d7ad2dbfebbfe167eb505", size = 318597, upload-time = "2026-02-02T12:35:58.591Z" }, + { url = "https://files.pythonhosted.org/packages/cf/52/e5719a60ac5d4d7c5995461a94ad5ef962a37c8bf5b088390e6fad59b2ff/jiter-0.13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1e2b199f446d3e82246b4fd9236d7cb502dc2222b18698ba0d986d2fecc6152", size = 348821, upload-time = "2026-02-02T12:36:00.093Z" }, + { url = "https://files.pythonhosted.org/packages/61/db/c1efc32b8ba4c740ab3fc2d037d8753f67685f475e26b9d6536a4322bcdd/jiter-0.13.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04670992b576fa65bd056dbac0c39fe8bd67681c380cb2b48efa885711d9d726", size = 364163, upload-time = "2026-02-02T12:36:01.937Z" }, + { url = "https://files.pythonhosted.org/packages/55/8a/fb75556236047c8806995671a18e4a0ad646ed255276f51a20f32dceaeec/jiter-0.13.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a1aff1fbdb803a376d4d22a8f63f8e7ccbce0b4890c26cc7af9e501ab339ef0", size = 483709, upload-time = "2026-02-02T12:36:03.41Z" }, + { url = "https://files.pythonhosted.org/packages/7e/16/43512e6ee863875693a8e6f6d532e19d650779d6ba9a81593ae40a9088ff/jiter-0.13.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b3fb8c2053acaef8580809ac1d1f7481a0a0bdc012fd7f5d8b18fb696a5a089", size = 370480, upload-time = "2026-02-02T12:36:04.791Z" }, + { url = "https://files.pythonhosted.org/packages/f8/4c/09b93e30e984a187bc8aaa3510e1ec8dcbdcd71ca05d2f56aac0492453aa/jiter-0.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdaba7d87e66f26a2c45d8cbadcbfc4bf7884182317907baf39cfe9775bb4d93", size = 360735, upload-time = "2026-02-02T12:36:06.994Z" }, + { url = "https://files.pythonhosted.org/packages/1a/1b/46c5e349019874ec5dfa508c14c37e29864ea108d376ae26d90bee238cd7/jiter-0.13.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7b88d649135aca526da172e48083da915ec086b54e8e73a425ba50999468cc08", size = 391814, upload-time = "2026-02-02T12:36:08.368Z" }, + { url = "https://files.pythonhosted.org/packages/15/9e/26184760e85baee7162ad37b7912797d2077718476bf91517641c92b3639/jiter-0.13.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e404ea551d35438013c64b4f357b0474c7abf9f781c06d44fcaf7a14c69ff9e2", size = 513990, upload-time = "2026-02-02T12:36:09.993Z" }, + { url = "https://files.pythonhosted.org/packages/e9/34/2c9355247d6debad57a0a15e76ab1566ab799388042743656e566b3b7de1/jiter-0.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1f4748aad1b4a93c8bdd70f604d0f748cdc0e8744c5547798acfa52f10e79228", size = 548021, upload-time = "2026-02-02T12:36:11.376Z" }, + { url = "https://files.pythonhosted.org/packages/ac/4a/9f2c23255d04a834398b9c2e0e665382116911dc4d06b795710503cdad25/jiter-0.13.0-cp312-cp312-win32.whl", hash = "sha256:0bf670e3b1445fc4d31612199f1744f67f889ee1bbae703c4b54dc097e5dd394", size = 203024, upload-time = "2026-02-02T12:36:12.682Z" }, + { url = "https://files.pythonhosted.org/packages/09/ee/f0ae675a957ae5a8f160be3e87acea6b11dc7b89f6b7ab057e77b2d2b13a/jiter-0.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:15db60e121e11fe186c0b15236bd5d18381b9ddacdcf4e659feb96fc6c969c92", size = 205424, upload-time = "2026-02-02T12:36:13.93Z" }, + { url = "https://files.pythonhosted.org/packages/1b/02/ae611edf913d3cbf02c97cdb90374af2082c48d7190d74c1111dde08bcdd/jiter-0.13.0-cp312-cp312-win_arm64.whl", hash = "sha256:41f92313d17989102f3cb5dd533a02787cdb99454d494344b0361355da52fcb9", size = 186818, upload-time = "2026-02-02T12:36:15.308Z" }, + { url = "https://files.pythonhosted.org/packages/91/9c/7ee5a6ff4b9991e1a45263bfc46731634c4a2bde27dfda6c8251df2d958c/jiter-0.13.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1f8a55b848cbabf97d861495cd65f1e5c590246fabca8b48e1747c4dfc8f85bf", size = 306897, upload-time = "2026-02-02T12:36:16.748Z" }, + { url = "https://files.pythonhosted.org/packages/7c/02/be5b870d1d2be5dd6a91bdfb90f248fbb7dcbd21338f092c6b89817c3dbf/jiter-0.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f556aa591c00f2c45eb1b89f68f52441a016034d18b65da60e2d2875bbbf344a", size = 317507, upload-time = "2026-02-02T12:36:18.351Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/b25d2ec333615f5f284f3a4024f7ce68cfa0604c322c6808b2344c7f5d2b/jiter-0.13.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7e1d61da332ec412350463891923f960c3073cf1aae93b538f0bb4c8cd46efb", size = 350560, upload-time = "2026-02-02T12:36:19.746Z" }, + { url = "https://files.pythonhosted.org/packages/be/ec/74dcb99fef0aca9fbe56b303bf79f6bd839010cb18ad41000bf6cc71eec0/jiter-0.13.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3097d665a27bc96fd9bbf7f86178037db139f319f785e4757ce7ccbf390db6c2", size = 363232, upload-time = "2026-02-02T12:36:21.243Z" }, + { url = "https://files.pythonhosted.org/packages/1b/37/f17375e0bb2f6a812d4dd92d7616e41917f740f3e71343627da9db2824ce/jiter-0.13.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d01ecc3a8cbdb6f25a37bd500510550b64ddf9f7d64a107d92f3ccb25035d0f", size = 483727, upload-time = "2026-02-02T12:36:22.688Z" }, + { url = "https://files.pythonhosted.org/packages/77/d2/a71160a5ae1a1e66c1395b37ef77da67513b0adba73b993a27fbe47eb048/jiter-0.13.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ed9bbc30f5d60a3bdf63ae76beb3f9db280d7f195dfcfa61af792d6ce912d159", size = 370799, upload-time = "2026-02-02T12:36:24.106Z" }, + { url = "https://files.pythonhosted.org/packages/01/99/ed5e478ff0eb4e8aa5fd998f9d69603c9fd3f32de3bd16c2b1194f68361c/jiter-0.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98fbafb6e88256f4454de33c1f40203d09fc33ed19162a68b3b257b29ca7f663", size = 359120, upload-time = "2026-02-02T12:36:25.519Z" }, + { url = "https://files.pythonhosted.org/packages/16/be/7ffd08203277a813f732ba897352797fa9493faf8dc7995b31f3d9cb9488/jiter-0.13.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5467696f6b827f1116556cb0db620440380434591e93ecee7fd14d1a491b6daa", size = 390664, upload-time = "2026-02-02T12:36:26.866Z" }, + { url = "https://files.pythonhosted.org/packages/d1/84/e0787856196d6d346264d6dcccb01f741e5f0bd014c1d9a2ebe149caf4f3/jiter-0.13.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:2d08c9475d48b92892583df9da592a0e2ac49bcd41fae1fec4f39ba6cf107820", size = 513543, upload-time = "2026-02-02T12:36:28.217Z" }, + { url = "https://files.pythonhosted.org/packages/65/50/ecbd258181c4313cf79bca6c88fb63207d04d5bf5e4f65174114d072aa55/jiter-0.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:aed40e099404721d7fcaf5b89bd3b4568a4666358bcac7b6b15c09fb6252ab68", size = 547262, upload-time = "2026-02-02T12:36:29.678Z" }, + { url = "https://files.pythonhosted.org/packages/27/da/68f38d12e7111d2016cd198161b36e1f042bd115c169255bcb7ec823a3bf/jiter-0.13.0-cp313-cp313-win32.whl", hash = "sha256:36ebfbcffafb146d0e6ffb3e74d51e03d9c35ce7c625c8066cdbfc7b953bdc72", size = 200630, upload-time = "2026-02-02T12:36:31.808Z" }, + { url = "https://files.pythonhosted.org/packages/25/65/3bd1a972c9a08ecd22eb3b08a95d1941ebe6938aea620c246cf426ae09c2/jiter-0.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:8d76029f077379374cf0dbc78dbe45b38dec4a2eb78b08b5194ce836b2517afc", size = 202602, upload-time = "2026-02-02T12:36:33.679Z" }, + { url = "https://files.pythonhosted.org/packages/15/fe/13bd3678a311aa67686bb303654792c48206a112068f8b0b21426eb6851e/jiter-0.13.0-cp313-cp313-win_arm64.whl", hash = "sha256:bb7613e1a427cfcb6ea4544f9ac566b93d5bf67e0d48c787eca673ff9c9dff2b", size = 185939, upload-time = "2026-02-02T12:36:35.065Z" }, + { url = "https://files.pythonhosted.org/packages/49/19/a929ec002ad3228bc97ca01dbb14f7632fffdc84a95ec92ceaf4145688ae/jiter-0.13.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fa476ab5dd49f3bf3a168e05f89358c75a17608dbabb080ef65f96b27c19ab10", size = 316616, upload-time = "2026-02-02T12:36:36.579Z" }, + { url = "https://files.pythonhosted.org/packages/52/56/d19a9a194afa37c1728831e5fb81b7722c3de18a3109e8f282bfc23e587a/jiter-0.13.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ade8cb6ff5632a62b7dbd4757d8c5573f7a2e9ae285d6b5b841707d8363205ef", size = 346850, upload-time = "2026-02-02T12:36:38.058Z" }, + { url = "https://files.pythonhosted.org/packages/36/4a/94e831c6bf287754a8a019cb966ed39ff8be6ab78cadecf08df3bb02d505/jiter-0.13.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9950290340acc1adaded363edd94baebcee7dabdfa8bee4790794cd5cfad2af6", size = 358551, upload-time = "2026-02-02T12:36:39.417Z" }, + { url = "https://files.pythonhosted.org/packages/a2/ec/a4c72c822695fa80e55d2b4142b73f0012035d9fcf90eccc56bc060db37c/jiter-0.13.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2b4972c6df33731aac0742b64fd0d18e0a69bc7d6e03108ce7d40c85fd9e3e6d", size = 201950, upload-time = "2026-02-02T12:36:40.791Z" }, + { url = "https://files.pythonhosted.org/packages/b6/00/393553ec27b824fbc29047e9c7cd4a3951d7fbe4a76743f17e44034fa4e4/jiter-0.13.0-cp313-cp313t-win_arm64.whl", hash = "sha256:701a1e77d1e593c1b435315ff625fd071f0998c5f02792038a5ca98899261b7d", size = 185852, upload-time = "2026-02-02T12:36:42.077Z" }, + { url = "https://files.pythonhosted.org/packages/6e/f5/f1997e987211f6f9bd71b8083047b316208b4aca0b529bb5f8c96c89ef3e/jiter-0.13.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:cc5223ab19fe25e2f0bf2643204ad7318896fe3729bf12fde41b77bfc4fafff0", size = 308804, upload-time = "2026-02-02T12:36:43.496Z" }, + { url = "https://files.pythonhosted.org/packages/cd/8f/5482a7677731fd44881f0204981ce2d7175db271f82cba2085dd2212e095/jiter-0.13.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9776ebe51713acf438fd9b4405fcd86893ae5d03487546dae7f34993217f8a91", size = 318787, upload-time = "2026-02-02T12:36:45.071Z" }, + { url = "https://files.pythonhosted.org/packages/f3/b9/7257ac59778f1cd025b26a23c5520a36a424f7f1b068f2442a5b499b7464/jiter-0.13.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:879e768938e7b49b5e90b7e3fecc0dbec01b8cb89595861fb39a8967c5220d09", size = 353880, upload-time = "2026-02-02T12:36:47.365Z" }, + { url = "https://files.pythonhosted.org/packages/c3/87/719eec4a3f0841dad99e3d3604ee4cba36af4419a76f3cb0b8e2e691ad67/jiter-0.13.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:682161a67adea11e3aae9038c06c8b4a9a71023228767477d683f69903ebc607", size = 366702, upload-time = "2026-02-02T12:36:48.871Z" }, + { url = "https://files.pythonhosted.org/packages/d2/65/415f0a75cf6921e43365a1bc227c565cb949caca8b7532776e430cbaa530/jiter-0.13.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a13b68cd1cd8cc9de8f244ebae18ccb3e4067ad205220ef324c39181e23bbf66", size = 486319, upload-time = "2026-02-02T12:36:53.006Z" }, + { url = "https://files.pythonhosted.org/packages/54/a2/9e12b48e82c6bbc6081fd81abf915e1443add1b13d8fc586e1d90bb02bb8/jiter-0.13.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87ce0f14c6c08892b610686ae8be350bf368467b6acd5085a5b65441e2bf36d2", size = 372289, upload-time = "2026-02-02T12:36:54.593Z" }, + { url = "https://files.pythonhosted.org/packages/4e/c1/e4693f107a1789a239c759a432e9afc592366f04e901470c2af89cfd28e1/jiter-0.13.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c365005b05505a90d1c47856420980d0237adf82f70c4aff7aebd3c1cc143ad", size = 360165, upload-time = "2026-02-02T12:36:56.112Z" }, + { url = "https://files.pythonhosted.org/packages/17/08/91b9ea976c1c758240614bd88442681a87672eebc3d9a6dde476874e706b/jiter-0.13.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1317fdffd16f5873e46ce27d0e0f7f4f90f0cdf1d86bf6abeaea9f63ca2c401d", size = 389634, upload-time = "2026-02-02T12:36:57.495Z" }, + { url = "https://files.pythonhosted.org/packages/18/23/58325ef99390d6d40427ed6005bf1ad54f2577866594bcf13ce55675f87d/jiter-0.13.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:c05b450d37ba0c9e21c77fef1f205f56bcee2330bddca68d344baebfc55ae0df", size = 514933, upload-time = "2026-02-02T12:36:58.909Z" }, + { url = "https://files.pythonhosted.org/packages/5b/25/69f1120c7c395fd276c3996bb8adefa9c6b84c12bb7111e5c6ccdcd8526d/jiter-0.13.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:775e10de3849d0631a97c603f996f518159272db00fdda0a780f81752255ee9d", size = 548842, upload-time = "2026-02-02T12:37:00.433Z" }, + { url = "https://files.pythonhosted.org/packages/18/05/981c9669d86850c5fbb0d9e62bba144787f9fba84546ba43d624ee27ef29/jiter-0.13.0-cp314-cp314-win32.whl", hash = "sha256:632bf7c1d28421c00dd8bbb8a3bac5663e1f57d5cd5ed962bce3c73bf62608e6", size = 202108, upload-time = "2026-02-02T12:37:01.718Z" }, + { url = "https://files.pythonhosted.org/packages/8d/96/cdcf54dd0b0341db7d25413229888a346c7130bd20820530905fdb65727b/jiter-0.13.0-cp314-cp314-win_amd64.whl", hash = "sha256:f22ef501c3f87ede88f23f9b11e608581c14f04db59b6a801f354397ae13739f", size = 204027, upload-time = "2026-02-02T12:37:03.075Z" }, + { url = "https://files.pythonhosted.org/packages/fb/f9/724bcaaab7a3cd727031fe4f6995cb86c4bd344909177c186699c8dec51a/jiter-0.13.0-cp314-cp314-win_arm64.whl", hash = "sha256:07b75fe09a4ee8e0c606200622e571e44943f47254f95e2436c8bdcaceb36d7d", size = 187199, upload-time = "2026-02-02T12:37:04.414Z" }, + { url = "https://files.pythonhosted.org/packages/62/92/1661d8b9fd6a3d7a2d89831db26fe3c1509a287d83ad7838831c7b7a5c7e/jiter-0.13.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:964538479359059a35fb400e769295d4b315ae61e4105396d355a12f7fef09f0", size = 318423, upload-time = "2026-02-02T12:37:05.806Z" }, + { url = "https://files.pythonhosted.org/packages/4f/3b/f77d342a54d4ebcd128e520fc58ec2f5b30a423b0fd26acdfc0c6fef8e26/jiter-0.13.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e104da1db1c0991b3eaed391ccd650ae8d947eab1480c733e5a3fb28d4313e40", size = 351438, upload-time = "2026-02-02T12:37:07.189Z" }, + { url = "https://files.pythonhosted.org/packages/76/b3/ba9a69f0e4209bd3331470c723c2f5509e6f0482e416b612431a5061ed71/jiter-0.13.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e3a5f0cde8ff433b8e88e41aa40131455420fb3649a3c7abdda6145f8cb7202", size = 364774, upload-time = "2026-02-02T12:37:08.579Z" }, + { url = "https://files.pythonhosted.org/packages/b3/16/6cdb31fa342932602458dbb631bfbd47f601e03d2e4950740e0b2100b570/jiter-0.13.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:57aab48f40be1db920a582b30b116fe2435d184f77f0e4226f546794cedd9cf0", size = 487238, upload-time = "2026-02-02T12:37:10.066Z" }, + { url = "https://files.pythonhosted.org/packages/ed/b1/956cc7abaca8d95c13aa8d6c9b3f3797241c246cd6e792934cc4c8b250d2/jiter-0.13.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7772115877c53f62beeb8fd853cab692dbc04374ef623b30f997959a4c0e7e95", size = 372892, upload-time = "2026-02-02T12:37:11.656Z" }, + { url = "https://files.pythonhosted.org/packages/26/c4/97ecde8b1e74f67b8598c57c6fccf6df86ea7861ed29da84629cdbba76c4/jiter-0.13.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1211427574b17b633cfceba5040de8081e5abf114f7a7602f73d2e16f9fdaa59", size = 360309, upload-time = "2026-02-02T12:37:13.244Z" }, + { url = "https://files.pythonhosted.org/packages/4b/d7/eabe3cf46715854ccc80be2cd78dd4c36aedeb30751dbf85a1d08c14373c/jiter-0.13.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7beae3a3d3b5212d3a55d2961db3c292e02e302feb43fce6a3f7a31b90ea6dfe", size = 389607, upload-time = "2026-02-02T12:37:14.881Z" }, + { url = "https://files.pythonhosted.org/packages/df/2d/03963fc0804e6109b82decfb9974eb92df3797fe7222428cae12f8ccaa0c/jiter-0.13.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:e5562a0f0e90a6223b704163ea28e831bd3a9faa3512a711f031611e6b06c939", size = 514986, upload-time = "2026-02-02T12:37:16.326Z" }, + { url = "https://files.pythonhosted.org/packages/f6/6c/8c83b45eb3eb1c1e18d841fe30b4b5bc5619d781267ca9bc03e005d8fd0a/jiter-0.13.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:6c26a424569a59140fb51160a56df13f438a2b0967365e987889186d5fc2f6f9", size = 548756, upload-time = "2026-02-02T12:37:17.736Z" }, + { url = "https://files.pythonhosted.org/packages/47/66/eea81dfff765ed66c68fd2ed8c96245109e13c896c2a5015c7839c92367e/jiter-0.13.0-cp314-cp314t-win32.whl", hash = "sha256:24dc96eca9f84da4131cdf87a95e6ce36765c3b156fc9ae33280873b1c32d5f6", size = 201196, upload-time = "2026-02-02T12:37:19.101Z" }, + { url = "https://files.pythonhosted.org/packages/ff/32/4ac9c7a76402f8f00d00842a7f6b83b284d0cf7c1e9d4227bc95aa6d17fa/jiter-0.13.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0a8d76c7524087272c8ae913f5d9d608bd839154b62c4322ef65723d2e5bb0b8", size = 204215, upload-time = "2026-02-02T12:37:20.495Z" }, + { url = "https://files.pythonhosted.org/packages/f9/8e/7def204fea9f9be8b3c21a6f2dd6c020cf56c7d5ff753e0e23ed7f9ea57e/jiter-0.13.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2c26cf47e2cad140fa23b6d58d435a7c0161f5c514284802f25e87fddfe11024", size = 187152, upload-time = "2026-02-02T12:37:22.124Z" }, + { url = "https://files.pythonhosted.org/packages/79/b3/3c29819a27178d0e461a8571fb63c6ae38be6dc36b78b3ec2876bbd6a910/jiter-0.13.0-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b1cbfa133241d0e6bdab48dcdc2604e8ba81512f6bbd68ec3e8e1357dd3c316c", size = 307016, upload-time = "2026-02-02T12:37:42.755Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ae/60993e4b07b1ac5ebe46da7aa99fdbb802eb986c38d26e3883ac0125c4e0/jiter-0.13.0-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:db367d8be9fad6e8ebbac4a7578b7af562e506211036cba2c06c3b998603c3d2", size = 305024, upload-time = "2026-02-02T12:37:44.774Z" }, + { url = "https://files.pythonhosted.org/packages/77/fa/2227e590e9cf98803db2811f172b2d6460a21539ab73006f251c66f44b14/jiter-0.13.0-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45f6f8efb2f3b0603092401dc2df79fa89ccbc027aaba4174d2d4133ed661434", size = 339337, upload-time = "2026-02-02T12:37:46.668Z" }, + { url = "https://files.pythonhosted.org/packages/2d/92/015173281f7eb96c0ef580c997da8ef50870d4f7f4c9e03c845a1d62ae04/jiter-0.13.0-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:597245258e6ad085d064780abfb23a284d418d3e61c57362d9449c6c7317ee2d", size = 346395, upload-time = "2026-02-02T12:37:48.09Z" }, + { url = "https://files.pythonhosted.org/packages/80/60/e50fa45dd7e2eae049f0ce964663849e897300433921198aef94b6ffa23a/jiter-0.13.0-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:3d744a6061afba08dd7ae375dcde870cffb14429b7477e10f67e9e6d68772a0a", size = 305169, upload-time = "2026-02-02T12:37:50.376Z" }, + { url = "https://files.pythonhosted.org/packages/d2/73/a009f41c5eed71c49bec53036c4b33555afcdee70682a18c6f66e396c039/jiter-0.13.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:ff732bd0a0e778f43d5009840f20b935e79087b4dc65bd36f1cd0f9b04b8ff7f", size = 303808, upload-time = "2026-02-02T12:37:52.092Z" }, + { url = "https://files.pythonhosted.org/packages/c4/10/528b439290763bff3d939268085d03382471b442f212dca4ff5f12802d43/jiter-0.13.0-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab44b178f7981fcaea7e0a5df20e773c663d06ffda0198f1a524e91b2fde7e59", size = 337384, upload-time = "2026-02-02T12:37:53.582Z" }, + { url = "https://files.pythonhosted.org/packages/67/8a/a342b2f0251f3dac4ca17618265d93bf244a2a4d089126e81e4c1056ac50/jiter-0.13.0-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bb00b6d26db67a05fe3e12c76edc75f32077fb51deed13822dc648fa373bc19", size = 343768, upload-time = "2026-02-02T12:37:55.055Z" }, +] + [[package]] name = "keyring" version = "25.7.0" @@ -649,6 +747,25 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, ] +[[package]] +name = "openai" +version = "2.26.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "distro" }, + { name = "httpx" }, + { name = "jiter" }, + { name = "pydantic" }, + { name = "sniffio" }, + { name = "tqdm" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d7/91/2a06c4e9597c338cac1e5e5a8dd6f29e1836fc229c4c523529dca387fda8/openai-2.26.0.tar.gz", hash = "sha256:b41f37c140ae0034a6e92b0c509376d907f3a66109935fba2c1b471a7c05a8fb", size = 666702, upload-time = "2026-03-05T23:17:35.874Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/2e/3f73e8ca53718952222cacd0cf7eecc9db439d020f0c1fe7ae717e4e199a/openai-2.26.0-py3-none-any.whl", hash = "sha256:6151bf8f83802f036117f06cc8a57b3a4da60da9926826cc96747888b57f394f", size = 1136409, upload-time = "2026-03-05T23:17:34.072Z" }, +] + [[package]] name = "packageurl-python" version = "0.17.6" @@ -982,6 +1099,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c0/5c/e2b18e66d73b69de87c198cba8744934b91247d8ab657a7253b591f4cf23/python_discovery-1.0.0-py3-none-any.whl", hash = "sha256:7cd9eaf3b1845875e22084f92d0ec2e309be2a3f839a9eb52980d647b72bd891", size = 28658, upload-time = "2026-02-25T17:10:47.722Z" }, ] +[[package]] +name = "python-dotenv" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3", size = 50135, upload-time = "2026-03-01T16:00:26.196Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" }, +] + [[package]] name = "pywin32-ctypes" version = "0.2.3" @@ -1147,6 +1273,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b7/46/f5af3402b579fd5e11573ce652019a67074317e18c1935cc0b4ba9b35552/secretstorage-3.5.0-py3-none-any.whl", hash = "sha256:0ce65888c0725fcb2c5bc0fdb8e5438eece02c523557ea40ce0703c266248137", size = 15554, upload-time = "2025-11-23T19:02:51.545Z" }, ] +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, +] + [[package]] name = "sortedcontainers" version = "2.4.0"