0.5.0 BlueprintAPIの適用

This commit is contained in:
2025-10-25 13:08:01 +09:00
parent cab8cd7f32
commit cc6bbe2a43
20 changed files with 519 additions and 1334 deletions
+1 -1
View File
@@ -225,7 +225,7 @@ let worker = Worker::builder()
### Code Organization
1. **Eliminated duplicate types** between `worker-types` and `worker` crates
2. **Clearer separation of concerns** - Role definition vs. PromptComposer execution
2. **Clearer separation of concerns** - Role定義とシステムプロンプト生成関数の責務を分離
3. **Consistent error construction** - All error sites updated to use new helper methods
## Files Changed
+2 -2
View File
@@ -1,6 +1,6 @@
# Release Notes - v0.3.0
**Release Date**: 2025-??-??
**Release Date**: 2025-10-23
v0.3.0 はプロンプトリソースの解決責務を利用側へ完全に移し、ツール/フック登録の推奨フローを明確化するアップデートです。これにより、ワーカーの動作を環境ごとに柔軟に制御できるようになりました。
@@ -11,7 +11,7 @@ v0.3.0 はプロンプトリソースの解決責務を利用側へ完全に移
## 新機能 / 仕様変更
- `PromptComposer``ResourceLoader` を必須依存として受け取り、partials や `{{include_file}}` の読み込みをすべてローダー経由で行うようになりました。
- システムプロンプトの構築責務をアプリケーション側のクロージャへ移し、Worker から `ResourceLoader` 依存を排除しました。
- パーシャル読み込み時にフォールバックが失敗した場合、一次/二次エラー内容を含むメッセージを返すよう改善しました。
- README とドキュメントを刷新し、推奨ワークフロー(ResourceLoader 実装 → Worker 構築 → イベント処理)を明示。`#[worker::tool]` / `#[worker::hook]` マクロを用いた登録例を追加しました。
- ユニットテスト `test_prompt_composer_uses_resource_loader` を追加し、注入されたローダーがパーシャル/include の解決に使われることを保証。
+3 -6
View File
@@ -1,6 +1,6 @@
# Release Notes - v0.4.0
**Release Date**: 2025-??-??
**Release Date**: 2025-10-24
v0.4.0 は Worker が `Role` や YAML 設定を扱わず、システムプロンプト生成を完全に利用者へ委譲する大規模リファクタです。これにより、任意のテンプレートエンジンやデータソースを組み合わせてプロンプトを構築できます。
@@ -11,19 +11,16 @@ v0.4.0 は Worker が `Role` や YAML 設定を扱わず、システムプロン
## 新機能 / 仕様変更
- `PromptComposer``Arc<SystemPromptFn>` を受け取り、`PromptContext` と履歴メッセージからシステムプロンプト文字列を生成するシンプルなラッパーになりました。
- `WorkerBuilder``.system_prompt(...)` で登録した関数を保持し、メッセージ送信時に毎回システムプロンプトを再生成します。
- システムプロンプト生成はブループリントが提供するクロージャで一度だけ評価し、ワーカーは生成済みの結果を保持する方針に統一しました。
- README/サンプルコードを刷新し、システムプロンプト関数・マクロベースのツール/フック登録手順のみを掲載。
- 新しい `docs/prompt-composer.md` を追加し、`PromptComposer` の利用例をサマリー形式で紹介。
## 不具合修正
- `PromptComposer` が内部でファイルアクセスを行う経路を排除し、生成関数の失敗時は直近のキャッシュを利用するようにしました。
- Worker から NIA 固有の設定コードを除去し、環境依存の副作用を縮小。
## 移行ガイド
1.`Role` / `ConfigParser` を利用していた場合、`PromptContext` と会話履歴を引数にシステムプロンプト文字列を返す関数を実装し、`.system_prompt(...)` に渡してください。
1.`Role` / `ConfigParser` を利用していた場合、`SystemPromptContext` と会話履歴を引数にシステムプロンプト文字列を返す関数を実装し、`.system_prompt(...)` に渡してください。
2. `Worker::load_config` やリソースパス解決に依存していたコードは削除してください。必要であればアプリケーション側でファイル読み込みを行い、生成関数内で利用してください。
3. ツール・フックは引き続き `#[worker::tool]` / `#[worker::hook]` マクロを推奨しています(API に変更はありません)。
+36
View File
@@ -0,0 +1,36 @@
# Release Notes - v0.5.0
**Release Date**: 2025-10-25
v0.5.0 introduces the Worker Blueprint API and removes the old type-state builder. Configuration now lives on the blueprint, while instantiated workers keep only the materialised system prompt and runtime state.
## Breaking Changes
- Removed `WorkerBuilder` type-state API. `Worker::blueprint()` now returns a configurable `WorkerBlueprint` which must be instantiated explicitly.
- `Worker::builder()` has been removed; always use `Worker::blueprint()` to configure new workers.
- Worker no longer exposes Role/YAML utilities; prompt generation is always supplied via `system_prompt_fn` and evaluated during instantiation.
## New Features / Behaviour
- `WorkerBlueprint` stores provider/model/api keys, tools, hooks, and optional precomputed system prompt strings. `instantiate()` evaluates the prompt (if not already cached) and hands the final string to the `Worker`.
- Instantiated workers retain only the composed system prompt string; the generator function lives solely on the blueprint and is dropped after instantiation.
- System prompts are no longer recomputed per turn. Tool metadata is appended dynamically as plain text when native tool support is unavailable.
## Migration Guide
1. Replace any legacy `Worker::builder()` usage with:
```rust
let mut blueprint = Worker::blueprint();
blueprint
.provider(LlmProvider::Claude)
.model("claude-3-sonnet")
.system_prompt_fn(your_fn);
let worker = blueprint.instantiate()?;
```
2. If you need to rebuild a worker, keep the original blueprint around. Instantiated workers no longer round-trip back into a blueprint once the prompt function has been consumed.
3. Hooks and tools can still be registered on the live worker; blueprint captures their state only before instantiation.
## Developer Notes
- Examples (`builder_basic`, `plugin_usage`) and README now illustrate the blueprint workflow and static system prompts.
- Internal helpers were adjusted so that workers maintain only runtime state while blueprint owns all configuration.
-32
View File
@@ -1,32 +0,0 @@
# PromptComposer
`PromptComposer` は、`PromptContext` と会話履歴からシステムプロンプト文字列を生成するクロージャをラップし、LLM へ送信するメッセージ列を構築します。
```rust
use std::sync::Arc;
use worker::prompt::{PromptComposer, PromptContext, PromptError, SystemPromptFn};
use worker_types::Message;
fn build_context() -> PromptContext {
// WorkspaceDetector などからアプリ固有の情報を収集して埋め込む
todo!()
}
fn generator(ctx: &PromptContext, messages: &[Message]) -> Result<String, PromptError> {
Ok(format!(
"Project {} has {} prior messages.",
ctx.workspace
.project_name
.clone()
.unwrap_or_else(|| \"unknown\".into()),
messages.len()
))
}
let context = build_context();
let composer = PromptComposer::new(context, Arc::new(generator));
let conversation = vec![Message::new(worker_types::Role::User, \"Hello\".into())];
let final_messages = composer.compose(&conversation)?;
```
`compose_with_tools` を使うと、`tools_schema` をテンプレート変数として渡した上でシステムプロンプトを再生成できます。
-185
View File
@@ -1,185 +0,0 @@
# `worker` ライブラリ
`worker`は、LLM(大規模言語モデル)との対話を抽象化し、複数のLLMプロバイダを統一的に扱うための共通ライブラリです。動的ツール登録システム、フックシステム、MCPプロトコル統合を提供します。
## アーキテクチャ
**Core Crate Pattern**を採用:`worker-types`(基本型)→ `worker-macros`(マクロ)→ `worker`(メインライブラリ)
循環依存を解消し、型安全性と保守性を向上させています。
## 概要
LLMプロバイダ(Gemini, Claude, OpenAI, Ollama, XAI)を統一インターフェースで利用できます。`Worker`構造体が中心となり、プロンプト管理、ツール登録、フックシステム、MCPサーバー統合を提供します。
## 主要なコンポーネント
### `Worker`
LLMとの対話における中心的な構造体です。
- **LLMクライアントの保持**: `LlmClient` enumを通じて複数プロバイダの統一インターフェースを提供
- **プロンプト管理**: `PromptComposer`によるテンプレートベースのプロンプト組み立て
- **ストリーミング処理**: リアルタイムイベントストリーム(`process_task_stream`)とメッセージ履歴管理(`process_task_with_history`
- **動的ツール管理**: 実行時ツール登録・実行、MCPサーバー統合
- **フックシステム**: メッセージ送信、ツール利用、ターン完了時の拡張ポイント
- **セッション管理**: メッセージ履歴の保存・復元機能
### `Tool` トレイト
動的ツール登録の基盤。`worker-types`で定義され、`#[tool]`マクロで自動実装可能です。
### `StreamEvent`
LLMストリーミング応答のイベント型。テキストチャンク、ツール呼び出し、ツール結果、完了通知、デバッグ情報、フックメッセージをサポートします。
### `LlmClient` Enum
各LLMプロバイダクライアントの統合enum。`LlmClientTrait`を実装し、統一されたストリーミング対話と接続確認機能を提供します。
### フックシステム
- `WorkerHook` トレイト: カスタムフック実装の基盤
- `HookManager`: フック登録・実行管理
- `HookEvent`: OnMessageSend、PreToolUse、PostToolUse、OnTurnCompleted
- `HookContext`: フック実行時のコンテキスト情報
### その他の主要型
- `Message`: LLM対話のメッセージ(role + content + tool_calls
- `LlmDebug`: デバッグログ制御と詳細出力
- `ModelInfo`: モデル情報とサポート機能
- `SessionData`: セッション永続化データ
## 基本的な使用方法
```rust
use worker::{Worker, LlmProvider, types::{Message, Role, StreamEvent}};
use futures_util::StreamExt;
// Worker初期化
let mut worker = Worker::new(
LlmProvider::Gemini,
"gemini-1.5-flash",
&api_keys,
None
)?;
// ツール登録(オプション)
worker.register_tool(Box::new(some_tool))?;
// メッセージ送信とストリーム処理(履歴あり)
let mut stream = worker.process_task_with_history(
"Hello, how are you?".to_string(),
None
).await;
while let Some(Ok(event)) = stream.next().await {
match event {
StreamEvent::Chunk(text) => print!("{}", text),
StreamEvent::ToolCall(call) => println!("Tool: {}", call.name),
StreamEvent::ToolResult { tool_name, result } => {
println!("Result from {}: {:?}", tool_name, result);
},
StreamEvent::Completion(_) => break,
_ => {}
}
}
```
### ツール登録と実行
```rust
// 個別ツール登録
worker.register_tool(Box::new(ReadFileTool::new()))?;
// MCPサーバーからのツール登録
let mcp_config = McpServerConfig {
name: "filesystem".to_string(),
command: "npx".to_string(),
args: vec!["-y".to_string(), "@modelcontextprotocol/server-filesystem".to_string()],
env: HashMap::new(),
};
worker.register_mcp_tools(mcp_config).await?;
// 複数MCPサーバーの並列初期化
worker.queue_mcp_server(config1);
worker.queue_mcp_server(config2);
worker.init_mcp_servers().await?;
// ツール実行
let result = worker.execute_tool("read_file", json!({"path": "./file.txt"})).await?;
```
### フックシステム
```rust
// カスタムフック実装例
struct MyHook;
#[async_trait::async_trait]
impl WorkerHook for MyHook {
fn name(&self) -> &str { "my_hook" }
fn hook_type(&self) -> &str { "OnMessageSend" }
fn matcher(&self) -> &str { "" }
async fn execute(&self, mut context: HookContext) -> (HookContext, HookResult) {
// メッセージ前処理
let new_content = format!("[処理済み] {}", context.content);
context.set_content(new_content);
(context, HookResult::Continue)
}
}
// フック登録
worker.register_hook(Box::new(MyHook));
```
### 主要API
- `register_tool()`: ツール登録
- `register_mcp_tools()`: MCPサーバーからのツール登録
- `register_hook()`: フック登録
- `get_tools()`: 登録済みツール一覧
- `execute_tool()`: ツール実行
- `process_task_stream()`: LLMストリーミング対話(履歴なし)
- `process_task_with_history()`: メッセージ履歴付きストリーミング対話
- `get_session_data()`: セッションデータ取得
- `load_session()`: セッション復元
## 型システム
**Core Crate Pattern**により型を分離:
- `worker-types`: 基本型(Tool, Message, StreamEvent等)
- `worker`: 実装とエラー型(WorkerError等)
後方互換性のため`worker::types::`経由で全型にアクセス可能。
## 主要型
- `ToolResult<T>`: ツール実行結果
- `DynamicToolDefinition`: ツール定義情報
- `WorkerError`: ライブラリ固有エラー型
## LLMプロバイダサポート
全プロバイダでストリーミング対話、ツール呼び出し、モデル一覧取得、接続確認を完全実装:
- Gemini (Google)
- Claude (Anthropic)
- OpenAI
- Ollama
- XAI (Grok)
## 主要機能
- **Core Crate Pattern**: 循環依存解消による保守性向上
- **動的ツール登録**: 実行時ツール追加・実行
- **#[tool]マクロ**: 関数からツール自動生成
- **フックシステム**: メッセージ送信・ツール利用・ターン完了時の拡張ポイント
- **ストリーミング対話**: リアルタイムLLM応答とイベント処理
- **複数プロバイダ**: 統一インターフェースでの5つのLLMプロバイダサポート
- **MCP統合**: Model Context Protocolサーバーとの動的連携
- **セッション管理**: メッセージ履歴の永続化・復元
- **ワークスペース検出**: Git情報を含む作業環境の自動認識
- **型安全性**: 強い型チェックとエラーハンドリング
- **並列処理**: MCPサーバーの並列初期化による高速化