@modular-prompt/extract 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +66 -21
  2. package/dist/cache-lifecycle.d.ts +3 -1
  3. package/dist/cache-lifecycle.d.ts.map +1 -1
  4. package/dist/cache-lifecycle.js +21 -0
  5. package/dist/cache-lifecycle.js.map +1 -1
  6. package/dist/cli/add-command.d.ts.map +1 -1
  7. package/dist/cli/add-command.js +2 -1
  8. package/dist/cli/add-command.js.map +1 -1
  9. package/dist/cli/args.d.ts +2 -0
  10. package/dist/cli/args.d.ts.map +1 -1
  11. package/dist/cli/args.js +14 -0
  12. package/dist/cli/args.js.map +1 -1
  13. package/dist/cli/create-command.d.ts +2 -0
  14. package/dist/cli/create-command.d.ts.map +1 -1
  15. package/dist/cli/create-command.js +11 -4
  16. package/dist/cli/create-command.js.map +1 -1
  17. package/dist/cli/extract-command.d.ts.map +1 -1
  18. package/dist/cli/extract-command.js +9 -3
  19. package/dist/cli/extract-command.js.map +1 -1
  20. package/dist/cli/list-command.d.ts +1 -0
  21. package/dist/cli/list-command.d.ts.map +1 -1
  22. package/dist/cli/list-command.js +3 -1
  23. package/dist/cli/list-command.js.map +1 -1
  24. package/dist/cli/manifest.d.ts +11 -0
  25. package/dist/cli/manifest.d.ts.map +1 -1
  26. package/dist/cli/manifest.js +16 -0
  27. package/dist/cli/manifest.js.map +1 -1
  28. package/dist/cli/store.js +1 -1
  29. package/dist/cli/store.js.map +1 -1
  30. package/dist/cli.js +12 -8
  31. package/dist/cli.js.map +1 -1
  32. package/dist/create-extract-runtime.d.ts +22 -0
  33. package/dist/create-extract-runtime.d.ts.map +1 -0
  34. package/dist/create-extract-runtime.js +27 -0
  35. package/dist/create-extract-runtime.js.map +1 -0
  36. package/dist/create-extract-session.d.ts.map +1 -1
  37. package/dist/create-extract-session.js +4 -1
  38. package/dist/create-extract-session.js.map +1 -1
  39. package/dist/create-mlx-extract-runtime.d.ts +18 -7
  40. package/dist/create-mlx-extract-runtime.d.ts.map +1 -1
  41. package/dist/create-mlx-extract-runtime.js +11 -1
  42. package/dist/create-mlx-extract-runtime.js.map +1 -1
  43. package/dist/create-pytorch-extract-runtime.d.ts +13 -0
  44. package/dist/create-pytorch-extract-runtime.d.ts.map +1 -0
  45. package/dist/create-pytorch-extract-runtime.js +52 -0
  46. package/dist/create-pytorch-extract-runtime.js.map +1 -0
  47. package/dist/default-models.d.ts +3 -8
  48. package/dist/default-models.d.ts.map +1 -1
  49. package/dist/default-models.js +4 -16
  50. package/dist/default-models.js.map +1 -1
  51. package/dist/extract-runtime-types.d.ts +16 -0
  52. package/dist/extract-runtime-types.d.ts.map +1 -0
  53. package/dist/extract-runtime-types.js +2 -0
  54. package/dist/extract-runtime-types.js.map +1 -0
  55. package/dist/extract-store.d.ts +21 -2
  56. package/dist/extract-store.d.ts.map +1 -1
  57. package/dist/extract-store.js +47 -8
  58. package/dist/extract-store.js.map +1 -1
  59. package/dist/index.d.ts +5 -0
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +2 -0
  62. package/dist/index.js.map +1 -1
  63. package/dist/model-resolution.d.ts +15 -5
  64. package/dist/model-resolution.d.ts.map +1 -1
  65. package/dist/model-resolution.js +87 -27
  66. package/dist/model-resolution.js.map +1 -1
  67. package/dist/types.d.ts +6 -0
  68. package/dist/types.d.ts.map +1 -1
  69. package/docs/API.md +316 -0
  70. package/docs/CACHE_DESIGN.md +475 -0
  71. package/docs/LOCAL_MODEL_SETUP.md +765 -0
  72. package/docs/PROMPT_MODULE_SPEC.md +482 -0
  73. package/package.json +7 -5
package/docs/API.md ADDED
@@ -0,0 +1,316 @@
1
+ # @modular-prompt/extract API 仕様
2
+
3
+ > **対象バージョン**: `0.1.0`
4
+ > **利用者向けガイド**: [README.md](./README.md)(サンプル・キャッシュ制約含む)
5
+
6
+ ## 概要
7
+
8
+ `@modular-prompt/extract` は、同一 corpus(文書・対話ログ)に対して **複数の切り口(cue)で繰り返し情報抽出** するためのセッション API を提供する。
9
+
10
+ - 基盤プロンプト(`baseModule`)と corpus(`materials` / `messages`)はセッション存続中固定
11
+ - 各 `extract()` 呼び出しで `cue`(出力切り口)と `inputs`(補強情報)を差し替え
12
+ - **KV キャッシュ連携は必須** — `driver` / `cacheController` / `model` は呼び出し側が用意する
13
+ - **リソースのライフサイクルは呼び出し側が管理** — `ExtractSession.close()` はセッション内 cache handle の `release()` のみ行う
14
+
15
+ ## 責務の分離
16
+
17
+ | コンポーネント | 生成 | 終了 |
18
+ |--------------|------|------|
19
+ | `driver` + `cacheController` | 呼び出し側(または provider runtime factory) | 呼び出し側(`runtime.close()` 等) |
20
+ | `ExtractSession` | `createExtractSession()` | `session.close()` — handle `release()` のみ |
21
+
22
+ `ExtractSession` は driver / cacheController を **借りる** だけで、所有しない。
23
+
24
+ ---
25
+
26
+ ## モジュール構成
27
+
28
+ ```
29
+ base (+ domain) + corpus (materials / messages) + request (inputs) ← cue
30
+ ```
31
+
32
+ | レイヤ | 指定方法 | 役割 |
33
+ |--------|---------|------|
34
+ | **base** | 省略可 → `defaultExtractBaseModule` | 抽出タスクの基本方針 |
35
+ | **domain** | `domainModule`(任意) | 用語定義・追加指示などのドメイン調整 |
36
+ | **data** | `corpus` + `request.inputs` | 抽出対象・補強情報 |
37
+ | **cue** | `request.cue` | 今回の抽出切り口 |
38
+
39
+ ### 入力型(最小入力 → Element 正規化)
40
+
41
+ API 境界では Element を直接渡さない。`buildExtractContext` が正規化する。
42
+
43
+ | スロット | 入力型 | 正規化結果 |
44
+ |---------|--------|-----------|
45
+ | `corpus.materials` | `MaterialInput \| MaterialInput[]` | `MaterialElement`(`cacheHint: immutable`) |
46
+ | `corpus.messages` | `MessageInput \| MessageInput[]` | `MessageElement`(role 別 cacheHint) |
47
+ | `request.inputs` | `string \| ChunkInput \| ...[]` | `ChunkElement`(`cacheHint: contextual`) |
48
+ | `request.cue` | `string \| SectionContent` | `TextElement`(`cacheHint: contextual`) |
49
+
50
+ #### `MaterialInput`
51
+
52
+ ```typescript
53
+ { title: string; content: string | Attachment[]; id?: string; usage?: number }
54
+ ```
55
+
56
+ `id` 省略時は `title` を使用。
57
+
58
+ library API では `content: Attachment[]` による画像 material を指定できます。MLX VLM の画像 cache 経路で利用できる画像は local file path のみで、URL / data URI は未対応です。CLI の `create` / `add` は入力ファイルを UTF-8 text として読むだけで `Attachment` を生成しないため、CLI 画像 material は Phase 3 の対象外です。
59
+
60
+ #### `MessageInput`
61
+
62
+ 標準: `{ role: 'system' | 'assistant' | 'user'; content: ... }`
63
+ ツール結果: `{ role: 'tool'; toolCallId; name; kind; value }`
64
+
65
+ #### `ChunkInput` / `ChunkInputValue`
66
+
67
+ `string` は `content` の省略記法。`partOf` 省略時は `'inputs'`。
68
+
69
+ ---
70
+
71
+ ## エントリポイント
72
+
73
+ ```typescript
74
+ import {
75
+ createExtractSession,
76
+ createMlxExtractRuntime,
77
+ createPytorchExtractRuntime,
78
+ createExtractRuntime,
79
+ resolveModelSpec,
80
+ createDriver,
81
+ buildPreviousExtractionsInputs,
82
+ inputChunk,
83
+ inputChunksFromJson,
84
+ mergeExtractBaseModule,
85
+ defaultExtractBaseModule,
86
+ resolveDefaultContainerDir,
87
+ resolveStoreDir,
88
+ validateStorename,
89
+ } from '@modular-prompt/extract';
90
+ ```
91
+
92
+ named store のパス解決と入力検証をライブラリから利用する場合:
93
+
94
+ ```typescript
95
+ import {
96
+ resolveDefaultContainerDir,
97
+ resolveStoreDir,
98
+ validateStorename,
99
+ } from '@modular-prompt/extract';
100
+
101
+ validateStorename('meeting');
102
+ const storeDir = resolveStoreDir(resolveDefaultContainerDir(), 'meeting');
103
+ ```
104
+
105
+ ### 公開シンボル
106
+
107
+ | シンボル | 種別 | 説明 |
108
+ |---------|------|------|
109
+ | `createExtractSession` | 関数 | 抽出セッションを生成 |
110
+ | `createMlxExtractRuntime` | 関数 | MLX 用 driver + cacheController バンドル |
111
+ | `createPytorchExtractRuntime` | 関数 | PyTorch 用 driver + cacheController バンドル(text-only) |
112
+ | `createExtractRuntime` | 関数 | 解決済み provider に応じた runtime factory |
113
+ | `resolveModelSpec` | 関数 | models.yaml の alias または生 model ID を extract 用 ModelSpec に解決 |
114
+ | `createDriver` | 関数 | 解決済み ModelSpec から AIService 経由で MLX / PyTorch driver を生成 |
115
+ | `resolveSessionModules` | 関数 | base (+ domain) モジュールを解決 |
116
+ | `resolveDefaultContainerDir` | 関数 | `MODULAR_PROMPT_HOME` に基づくデフォルト cache container を解決 |
117
+ | `resolveStoreDir` | 関数 | cache コンテナと storename から store ディレクトリを解決 |
118
+ | `validateStorename` | 関数 | storename の形式と予約語を検証 |
119
+ | `compileExtractPrompt` | 関数 | context 付き compile(高度な用途) |
120
+ | `buildExtractContext` | 関数 | corpus + request から `ExtractContext` を構築 |
121
+ | `defaultExtractBaseModule` | 定数 | デフォルト base `PromptModule` |
122
+ | `mergeExtractBaseModule` | 関数 | デフォルト base に overlay を merge |
123
+ | `buildPreviousExtractionsInputs` | 関数 | 過去抽出結果を `inputs` に変換 |
124
+ | `formatPreviousExtractions` | 関数 | 過去抽出結果をテキストブロック列に整形 |
125
+ | `inputChunk` / `inputChunksFromJson` | 関数 | chunk 入力ヘルパ |
126
+ | `normalizeMaterials` 等 | 関数 | 正規化ヘルパ(テスト・高度な用途) |
127
+
128
+ ### 内部 API(named store 拡張の共有実装)
129
+
130
+ `src/extract-store.ts` は package root からは export しない内部 API ですが、CLI と将来の store 管理入口が共有する disk 上の store 操作を担当します。`add-command.ts` はファイル読み込み、引数由来のエラー、`--dry-run` の出力だけを担当し、prefill と manifest の更新はこの層を呼び出します。
131
+
132
+ | API | 入力 / 出力 | 責務と保証 |
133
+ |-----|-------------|------------|
134
+ | `mergeMaterials(existing, incoming)` | `MaterialInput[]` → merged `MaterialInput[]` | `id`(省略時は `title`)で順序を保ってマージ。同一 id・同一内容はスキップし、内容差分はエラー |
135
+ | `prepareExtractCache({ cacheDir, model, provider?, backend?, maxImageSize?, materials })` | `Promise<{ model, provider, backend?, maxImageSize? }>`(解決済み model/provider) | prepare cue で corpus を KV prefill し、session/runtime を close。manifest は変更しない |
136
+ | `appendToExtractStore({ storeDir, storename, incomingMaterials, existingManifest?, now? })` | `Promise<{ manifest, model, provider, backend?, addedMaterials }>` | 既存 store を staging に複製して incremental prefill と manifest 更新を行い、成功時に rename 交換。prefill / manifest / runtime の失敗時は元の corpus・manifest・KV を保持 |
137
+
138
+ `appendToExtractStore` は `manifest.provider`(未指定の legacy manifest は MLX)、`manifest.model`、`manifest.backend`(MLX のみ。未指定時は `auto` fallback)、および保存済み `maxImageSize` を使い、provider + model の不一致を検証します。成功時だけ `updatedAt`、materials、解決済み provider/backend、画像 resize 条件を反映します。`readExtractStoreManifest` は store の存在と manifest を検証し、存在しない store には `create` を案内するエラーを返します。ライブラリ層のマージ、prefill、失敗時保全は `src/extract-store.test.ts` で CLI から独立して検証しています。
139
+
140
+ ---
141
+
142
+ create/add が内部で使う `prepareExtractCache` は `cachePreparation: 'required'` で session を実行するため、cache controller が空 handle を返した場合は driver query、manifest 書き込み、store の rename 交換に進みません。通常の `createExtractSession` は省略時の `best-effort` 契約を維持します。
143
+
144
+ ## `createMlxExtractRuntime(options)`
145
+
146
+ ```typescript
147
+ function createMlxExtractRuntime(
148
+ options: MlxExtractRuntimeOptions
149
+ ): Promise<MlxExtractRuntime>
150
+ ```
151
+
152
+ | プロパティ | 型 | 必須 | 説明 |
153
+ |-----------|-----|------|------|
154
+ | `model` | `string` | — | MLX モデルの alias または生の HF model ID。省略時は user models.yaml の `models.default` から解決。未設定時はエラー |
155
+ | `backend` | `'auto' \| 'lm' \| 'vlm' \| 'optiq'` | — | MLX backend の明示指定。省略時は models.yaml の指定、さらに未指定なら `auto` |
156
+ | `cacheDir` | `string` | — | 固定キャッシュディレクトリ。省略時は managed temp dir |
157
+ | `maxImageSize` | `number` | — | VLM 画像キャッシュの最大辺。省略時は models.yaml の指定、さらに未指定なら 768 |
158
+
159
+ `MlxExtractRuntime.close()` は `driver.close()` + `cacheController.close()` を行う。
160
+
161
+ runtime の `backend` プロパティは実際に driver へ渡した選択値であり、extract store の manifest に保存されます。backend のない既存 manifest は `auto` として再開します。
162
+
163
+ `createMlxExtractRuntime` は AIService 経由でモデルを解決・生成し、models.yaml の MLX backend 指定を保持する。backend 未指定時は `auto` としてモデル種別に応じて `mlx-lm` / `mlx-vlm` を選択する。`backend: 'vlm'` の場合、画像なしの text-only exact KV cache と、画像 material を含む vision cache を固定 cacheDir に別 namespace で永続化できる。画像付き cache は text-only VLM / LM cache と非互換で、VLM incremental prefill は対象外。モデル指定を省略した場合は user の `~/.modular-prompt/models.yaml` にある `models.default` を使用する。同梱モデルや `models` の先頭エントリへの fallback はなく、モデル未設定時は driver 作成前にエラーになる。生の model ID を指定する場合は、models.yaml の一致エントリで `provider: mlx` を設定するか、既知の MLX model 名パターンを使用してください。provider を推論できない ID はエラーになります。
164
+
165
+ ## `createPytorchExtractRuntime(options)`
166
+
167
+ ```typescript
168
+ function createPytorchExtractRuntime(
169
+ options: PyTorchExtractRuntimeOptions
170
+ ): Promise<PyTorchExtractRuntime>
171
+ ```
172
+
173
+ | プロパティ | 型 | 必須 | 説明 |
174
+ |-----------|-----|------|------|
175
+ | `model` | `string` | — | PyTorch (Transformers) モデルの alias または生の HF model ID。省略時は user models.yaml の `models.default` から解決 |
176
+ | `cacheDir` | `string` | — | 固定キャッシュディレクトリ。省略時は managed temp dir |
177
+
178
+ PyTorch runtime は `PyTorchCacheController` と `PyTorchDriver` を共有し、`getCapabilities()` で cache binding を完了してから返します。現状の PyTorch backend は text-only のため、MLX の `backend` / `maxImageSize` は渡されません。`runtime.close()` は driver と cache controller を解放します。
179
+
180
+ ## `createExtractRuntime(options)`
181
+
182
+ `createExtractRuntime({ model, provider?, cacheDir?, backend?, maxImageSize? })` は alias / raw model の解決結果に応じて MLX または PyTorch runtime を生成します。`provider` を指定した場合は models.yaml の alias/provider と一致することを検証し、raw model ID の provider を明示できます。PyTorch では `backend` / `maxImageSize` は無視されます。
183
+
184
+ `createDriver(model, { provider?, cacheController, backend?, maxImageSize? })` は runtime 内部で使用する低レベル helper で、戻り値は `{ driver, spec }`。`spec.model` は alias 解決後の生 model ID である。
185
+
186
+ ---
187
+
188
+ ## `createExtractSession(options)`
189
+
190
+ ```typescript
191
+ function createExtractSession<TContext = ExtractContext>(
192
+ options: ExtractSessionOptions<TContext>
193
+ ): ExtractSession
194
+ ```
195
+
196
+ ### `ExtractSessionOptions<TContext>`
197
+
198
+ | プロパティ | 型 | 必須 | 説明 |
199
+ |-----------|-----|------|------|
200
+ | `driver` | `AIDriver` | ✅ | 推論実行ドライバー |
201
+ | `cacheController` | `PromptCacheController` | ✅ | KV キャッシュコントローラ |
202
+ | `model` | `string` | ✅ | `prepare()` 用モデル識別子 |
203
+ | `baseModule` | `PromptModule<TContext>` | — | 省略時 `defaultExtractBaseModule` |
204
+ | `domainModule` | `PromptModule<TContext>` | — | base の上に merge |
205
+ | `corpus` | `ExtractCorpus` | ✅ | セッション固定 corpus |
206
+ | `schema` | `object` | — | JSON Schema(structured output) |
207
+ | `cachePreparation` | `'best-effort' \| 'required'` | — | 通常は `best-effort`(省略時)。`required` は空 handle をエラーにして driver query を実行しない |
208
+ | `maxImageSize` | `number` | — | VLM 画像キャッシュの正規化に使う最大辺。driver の設定と一致させる。runtime 経由では自動設定 |
209
+
210
+ #### `ExtractCorpus`
211
+
212
+ | プロパティ | 型 | 説明 |
213
+ |-----------|-----|------|
214
+ | `materials` | `MaterialsInput` | 文書 corpus |
215
+ | `messages` | `MessagesInput` | 対話ログ |
216
+
217
+ ### `ExtractSession.extract(request)`
218
+
219
+ #### `ExtractRequest`
220
+
221
+ | プロパティ | 型 | 必須 | 説明 |
222
+ |-----------|-----|------|------|
223
+ | `cue` | `string \| SectionContent` | ✅ | 抽出切り口 |
224
+ | `inputs` | `InputsInput` | — | 補強情報 |
225
+ | `options` | `QueryOptions` | — | ドライバークエリオプション |
226
+
227
+ #### `ExtractResult`
228
+
229
+ | プロパティ | 型 | 説明 |
230
+ |-----------|-----|------|
231
+ | `text` | `string` | 抽出テキスト |
232
+ | `structured` | `unknown` | schema 指定時の構造化出力 |
233
+ | `usage` | `QueryResult['usage']` | トークン使用量(`cacheReadTokens` 含む) |
234
+ | `index` | `number` | セッション内連番(0 始まり) |
235
+
236
+ ### `getHistory()` / `close()`
237
+
238
+ - `getHistory()` — セッション内全結果のコピー
239
+ - `close(options?)` — セッション終了(冪等)。`close()` 後の `extract()` は拒否
240
+ - `releaseCache`(デフォルト `true`)— `false` のとき handle を release しない。固定 cacheDir をプロセス間で再利用する場合に使う
241
+ - `releaseCache: true` のとき `cacheController.release()` が呼ばれ、続く `runtime.close()` で KV ファイルが削除される(固定 cacheDir モード)
242
+
243
+ CLI の `clean <storename>` で store 単位、`clean --all` で cache container 全体を削除できる。対象が存在しない場合は no-op になる。
244
+
245
+ ---
246
+
247
+ ## CLI(`modular-prompt-extract`)
248
+
249
+ `modular-prompt-extract` は cache container 内に named store を作成・利用する。`-d` の値は container パスで、create/add/extract/list/clean 共通で使用する。省略時は `~/.modular-prompt/extract-cache`(`MODULAR_PROMPT_HOME` を設定した場合は `${MODULAR_PROMPT_HOME}/extract-cache`)。
250
+
251
+ CLI の `create` / `add` は各入力ファイルを UTF-8 の文字列として `MaterialInput.content` に格納します。画像ファイルを `Attachment` に変換する CLI 経路はなく、CLI 画像 material は Phase 3 の対象外です。画像 material の縦切りは library API の `MaterialInput.content: Attachment[]` を使用してください。
252
+
253
+ ```bash
254
+ modular-prompt-extract create <storename> [-m <model>] [--provider <mlx|pytorch>] [--dry-run] <files...>
255
+ modular-prompt-extract add <storename> [--dry-run] <files...>
256
+ modular-prompt-extract extract <storename> [--max-tokens <n>] [--dry-run] <query...>
257
+ modular-prompt-extract list
258
+ modular-prompt-extract clean <storename>
259
+ modular-prompt-extract clean --all
260
+ ```
261
+
262
+ container を指定する場合は、各コマンドに `-d <cache-dir>` を追加する。
263
+
264
+ ```bash
265
+ modular-prompt-extract create meeting -d ~/.modular-prompt/extract-cache -m default docs/meeting.txt
266
+ modular-prompt-extract add meeting -d ~/.modular-prompt/extract-cache docs/day2.txt
267
+ modular-prompt-extract extract meeting -d ~/.modular-prompt/extract-cache '参加者を列挙'
268
+ modular-prompt-extract list -d ~/.modular-prompt/extract-cache
269
+ modular-prompt-extract clean meeting -d ~/.modular-prompt/extract-cache
270
+ modular-prompt-extract clean --all -d ~/.modular-prompt/extract-cache
271
+ ```
272
+
273
+ `<storename>` は create/add/extract/clean の positional 第1引数として必須(`clean --all` を除く)で、`[a-zA-Z0-9][a-zA-Z0-9_-]*` に一致する必要がある。`create`、`add`、`extract`、`list`、`clean` は予約語である。
274
+
275
+ `add <storename> [--dry-run] <files...>` は既存 store の manifest にファイルを追記し、manifest の model で prepare cue を実行する。既存 cache を staging store に複製してから incremental prefill と manifest 更新を行い、成功時にだけ store を入れ替える。prefill または manifest 更新が失敗した場合は元の store を保持する。同じ絶対パス `id` の同一内容はスキップし、内容が異なる場合は `clean` + `create` を案内してエラーにする。
276
+
277
+ `add --dry-run` はマージ後の compile 済みプロンプトを表示し、driver の起動・KV cache の書き込み・manifest の更新を行わない。`add` では `-m`、`--provider`、`--max-tokens` は指定できない。create の `--provider` は `mlx` または `pytorch` を受け付け、以降の add/extract は manifest に保存された provider を使用する。
278
+
279
+ これは破壊的変更であり、旧 CLI 引数形式と旧レイアウト(container 直下の `manifest.json` と cache files)はサポートしない。旧デフォルト `./.extract-cache` の自動検出・自動移行も行わない。既存データを利用する場合は、[README の旧 CLI / キャッシュレイアウトからの手動移行手順](./README.md#旧-cli--キャッシュレイアウトからの移行)に従って、新しいデフォルトまたは `-d` で指定した store container へ移動する。
280
+
281
+ ---
282
+
283
+ ## キャッシュ連携
284
+
285
+ 毎回の `extract()` で:
286
+
287
+ 1. `compileExtractPrompt` — `ExtractContext` を解決して compile
288
+ 2. `cacheController.prepare()` — cacheable 部分を prefill
289
+ 3. `supersedes` 返却時 — 旧 handle を `release()`
290
+ 4. `driver.query()` — `{ cache: false, cacheHandle }` で二重 prepare を回避
291
+
292
+ | セクション | キャッシュ |
293
+ |-----------|-----------|
294
+ | baseModule(instructions) | ✅ |
295
+ | corpus(materials, messages) | ✅ |
296
+ | inputs | ✅(incremental) |
297
+ | cue | ❌ |
298
+
299
+ ### 制約(再掲)
300
+
301
+ - **corpus / baseModule 変更** → 新セッション
302
+ - **inputs 累積** → 自動ではない。`buildPreviousExtractionsInputs` 等で明示的に渡す
303
+ - **driver / cacheController の close** → 呼び出し側(`runtime.close()`)
304
+
305
+ ---
306
+
307
+ ## 実装状況
308
+
309
+ | 項目 | 状態 |
310
+ |------|------|
311
+ | Phase 1 コア API | ✅ |
312
+ | Phase 2 キャッシュ統合 | ✅ |
313
+ | Phase 3 便利機能 | ✅ |
314
+ | Phase 4 ドキュメント・サンプル | ✅ |
315
+
316
+ **テスト**: `pnpm --filter @modular-prompt/extract test:run`