@modular-prompt/driver 0.6.3 → 0.8.1

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 (40) hide show
  1. package/README.md +37 -540
  2. package/dist/driver-registry/registry.d.ts +1 -2
  3. package/dist/driver-registry/registry.d.ts.map +1 -1
  4. package/dist/driver-registry/registry.js +1 -2
  5. package/dist/driver-registry/registry.js.map +1 -1
  6. package/dist/formatter/formatter.d.ts.map +1 -1
  7. package/dist/formatter/formatter.js +32 -14
  8. package/dist/formatter/formatter.js.map +1 -1
  9. package/dist/mlx-ml/mlx-driver.d.ts +4 -0
  10. package/dist/mlx-ml/mlx-driver.d.ts.map +1 -1
  11. package/dist/mlx-ml/mlx-driver.js +67 -8
  12. package/dist/mlx-ml/mlx-driver.js.map +1 -1
  13. package/dist/mlx-ml/process/index.d.ts +3 -3
  14. package/dist/mlx-ml/process/index.d.ts.map +1 -1
  15. package/dist/mlx-ml/process/index.js +2 -2
  16. package/dist/mlx-ml/process/index.js.map +1 -1
  17. package/dist/mlx-ml/process/parameter-mapper.d.ts.map +1 -1
  18. package/dist/mlx-ml/process/parameter-mapper.js +4 -2
  19. package/dist/mlx-ml/process/parameter-mapper.js.map +1 -1
  20. package/dist/mlx-ml/process/process-communication.d.ts.map +1 -1
  21. package/dist/mlx-ml/process/process-communication.js +2 -7
  22. package/dist/mlx-ml/process/process-communication.js.map +1 -1
  23. package/dist/mlx-ml/process/queue.d.ts +2 -2
  24. package/dist/mlx-ml/process/queue.d.ts.map +1 -1
  25. package/dist/mlx-ml/process/queue.js +2 -1
  26. package/dist/mlx-ml/process/queue.js.map +1 -1
  27. package/dist/mlx-ml/process/types.d.ts +18 -0
  28. package/dist/mlx-ml/process/types.d.ts.map +1 -1
  29. package/dist/mlx-ml/tool-call-parser.d.ts +29 -0
  30. package/dist/mlx-ml/tool-call-parser.d.ts.map +1 -0
  31. package/dist/mlx-ml/tool-call-parser.js +163 -0
  32. package/dist/mlx-ml/tool-call-parser.js.map +1 -0
  33. package/dist/mlx-ml/types.d.ts +11 -0
  34. package/dist/mlx-ml/types.d.ts.map +1 -1
  35. package/package.json +6 -4
  36. package/skills/driver-usage/SKILL.md +432 -0
  37. package/src/mlx-ml/python/__main__.py +53 -38
  38. package/src/mlx-ml/python/pyproject.toml +1 -1
  39. package/src/mlx-ml/python/token_utils.py +72 -1
  40. package/src/mlx-ml/python/uv.lock +4 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-call-parser.d.ts","sourceRoot":"","sources":["../../src/mlx-ml/tool-call-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE5E,MAAM,WAAW,mBAAmB;IAClC,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,cAAc,GAAG,IAAI,GACjC,mBAAmB,CA+BrB;AA6GD;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,cAAc,EAAE,EACvB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,gBAAgB,CAAC,EAC/D,cAAc,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1D,MAAM,CAqCR"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * モデル出力からtool callを検出・パース
3
+ *
4
+ * 検出戦略:
5
+ * 1. runtimeInfo.features.chat_template.tool_call_format が存在 → テンプレート由来のデリミタで検出
6
+ * 2. runtimeInfo.special_tokens.tool_call が存在 → 特殊トークンによるデリミタで検出
7
+ * 3. ```json:toolCall コードブロック → ラベル付きコードブロック検出
8
+ * 4. 汎用フォールバック → JSON形式のtool call検出
9
+ */
10
+ export function parseToolCalls(text, runtimeInfo) {
11
+ // 1. tool_call_format(テンプレート由来)による検出
12
+ const toolCallFormat = runtimeInfo?.features?.chat_template?.tool_call_format;
13
+ if (toolCallFormat?.call_start && toolCallFormat?.call_end) {
14
+ const result = parseWithDelimiters(text, toolCallFormat.call_start, toolCallFormat.call_end);
15
+ if (result.toolCalls.length > 0) {
16
+ return result;
17
+ }
18
+ }
19
+ // 2. 特殊トークンによる検出
20
+ const toolCallToken = runtimeInfo?.special_tokens?.tool_call;
21
+ if (toolCallToken && typeof toolCallToken === 'object' && 'start' in toolCallToken) {
22
+ const result = parseWithDelimiters(text, toolCallToken.start.text, toolCallToken.end.text);
23
+ if (result.toolCalls.length > 0) {
24
+ return result;
25
+ }
26
+ }
27
+ // 3. ```json:toolCall コードブロック検出
28
+ const codeBlockResult = parseCodeBlockToolCalls(text);
29
+ if (codeBlockResult.toolCalls.length > 0) {
30
+ return codeBlockResult;
31
+ }
32
+ // 4. 汎用フォールバック
33
+ return parseGenericToolCalls(text);
34
+ }
35
+ function parseWithDelimiters(text, startDelimiter, endDelimiter) {
36
+ const toolCalls = [];
37
+ let content = text;
38
+ let callIndex = 0;
39
+ // startDelimiter...endDelimiter のパターンを繰り返し検索
40
+ const regex = new RegExp(escapeRegExp(startDelimiter) + '([\\s\\S]*?)' + escapeRegExp(endDelimiter), 'g');
41
+ let match;
42
+ while ((match = regex.exec(text)) !== null) {
43
+ const jsonStr = match[1].trim();
44
+ try {
45
+ const parsed = JSON.parse(jsonStr);
46
+ toolCalls.push({
47
+ id: `call_${callIndex++}`,
48
+ name: parsed.name,
49
+ arguments: parsed.arguments || parsed.parameters || {}
50
+ });
51
+ }
52
+ catch {
53
+ // JSONパース失敗 → スキップ
54
+ }
55
+ }
56
+ if (toolCalls.length > 0) {
57
+ // tool call部分をテキストから除去
58
+ content = text.replace(regex, '').trim();
59
+ }
60
+ return { content, toolCalls };
61
+ }
62
+ function parseCodeBlockToolCalls(text) {
63
+ const toolCalls = [];
64
+ let content = text;
65
+ let callIndex = 0;
66
+ // ```json:toolCall ... ``` パターンを検出
67
+ const codeBlockRegex = /```json:toolCall\s*\n([\s\S]*?)```/g;
68
+ let match;
69
+ while ((match = codeBlockRegex.exec(text)) !== null) {
70
+ const jsonStr = match[1].trim();
71
+ try {
72
+ const parsed = JSON.parse(jsonStr);
73
+ toolCalls.push({
74
+ id: `call_${callIndex++}`,
75
+ name: parsed.name,
76
+ arguments: parsed.arguments || parsed.parameters || {}
77
+ });
78
+ }
79
+ catch {
80
+ // JSONパース失敗 → スキップ
81
+ }
82
+ }
83
+ if (toolCalls.length > 0) {
84
+ content = text.replace(codeBlockRegex, '').trim();
85
+ }
86
+ return { content, toolCalls };
87
+ }
88
+ function parseGenericToolCalls(text) {
89
+ const toolCalls = [];
90
+ let content = text;
91
+ let callIndex = 0;
92
+ // 汎用パターン: {"name": "...", "arguments": {...}} を検出
93
+ // 行頭からJSONオブジェクトが始まるか、テキスト末尾のJSONブロックを検出
94
+ const jsonPattern = /\{[\s\S]*?"name"\s*:\s*"[^"]+?"[\s\S]*?(?:"arguments"|"parameters")\s*:\s*\{[\s\S]*?\}\s*\}/g;
95
+ let match;
96
+ while ((match = jsonPattern.exec(text)) !== null) {
97
+ try {
98
+ const parsed = JSON.parse(match[0]);
99
+ if (parsed.name && (parsed.arguments || parsed.parameters)) {
100
+ toolCalls.push({
101
+ id: `call_${callIndex++}`,
102
+ name: parsed.name,
103
+ arguments: parsed.arguments || parsed.parameters || {}
104
+ });
105
+ }
106
+ }
107
+ catch {
108
+ // JSONパース失敗 → スキップ
109
+ }
110
+ }
111
+ if (toolCalls.length > 0) {
112
+ // tool call部分をテキストから除去(最後のJSON部分のみ)
113
+ for (const match2 of [...text.matchAll(jsonPattern)]) {
114
+ content = content.replace(match2[0], '').trim();
115
+ }
116
+ }
117
+ return { content, toolCalls };
118
+ }
119
+ function escapeRegExp(str) {
120
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
121
+ }
122
+ /**
123
+ * tool定義をテキスト形式にフォーマット
124
+ * tool_call_formatまたは特殊トークンがある場合はそのフォーマットに合わせた指示を生成
125
+ */
126
+ export function formatToolDefinitionsAsText(tools, specialTokens, toolCallFormat) {
127
+ const lines = ['## Available Tools', ''];
128
+ for (const tool of tools) {
129
+ lines.push(`### ${tool.name}`);
130
+ if (tool.description) {
131
+ lines.push(tool.description);
132
+ }
133
+ if (tool.parameters) {
134
+ lines.push(`Parameters: ${JSON.stringify(tool.parameters)}`);
135
+ }
136
+ lines.push('');
137
+ }
138
+ // tool call出力フォーマットの指示
139
+ if (toolCallFormat?.call_start && toolCallFormat?.call_end) {
140
+ lines.push('To call a tool, respond with:');
141
+ lines.push(toolCallFormat.call_start);
142
+ lines.push('{"name": "tool_name", "arguments": {"param": "value"}}');
143
+ lines.push(toolCallFormat.call_end);
144
+ }
145
+ else {
146
+ const toolCallToken = specialTokens?.tool_call;
147
+ if (toolCallToken && 'start' in toolCallToken && 'end' in toolCallToken) {
148
+ const pair = toolCallToken;
149
+ lines.push('To call a tool, respond with:');
150
+ lines.push(`${pair.start.text}`);
151
+ lines.push('{"name": "tool_name", "arguments": {"param": "value"}}');
152
+ lines.push(`${pair.end.text}`);
153
+ }
154
+ else {
155
+ lines.push('To call a tool, respond with:');
156
+ lines.push('```json:toolCall');
157
+ lines.push('{"name": "tool_name", "arguments": {"param": "value"}}');
158
+ lines.push('```');
159
+ }
160
+ }
161
+ return lines.join('\n');
162
+ }
163
+ //# sourceMappingURL=tool-call-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-call-parser.js","sourceRoot":"","sources":["../../src/mlx-ml/tool-call-parser.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,16 @@ export interface MlxMlModelOptions {
26
26
  [key: string]: number | undefined;
27
27
  }
28
28
  export type { ChatRestrictions, ApiStrategy };
29
+ /**
30
+ * ツール呼び出しフォーマット
31
+ */
32
+ export interface ToolCallFormat {
33
+ toolParserType?: string;
34
+ callStart?: string;
35
+ callEnd?: string;
36
+ responseStart?: string;
37
+ responseEnd?: string;
38
+ }
29
39
  /**
30
40
  * チャットテンプレート情報
31
41
  */
@@ -34,6 +44,7 @@ export interface ChatTemplateInfo {
34
44
  supportedRoles: string[];
35
45
  preview?: string;
36
46
  constraints: Record<string, unknown>;
47
+ toolCallFormat?: ToolCallFormat;
37
48
  }
38
49
  /**
39
50
  * モデルの機能情報
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/mlx-ml/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AAGD,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wBAAwB;IACxB,eAAe,EAAE,OAAO,CAAC;IAEzB,YAAY;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,cAAc;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,mBAAmB;IACnB,YAAY,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,kBAAkB;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB,aAAa;IACb,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,gBAAgB,CAAC,CAAC;IAE/D,aAAa;IACb,QAAQ,EAAE,aAAa,CAAC;IAExB,iCAAiC;IACjC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/mlx-ml/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AAGD,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wBAAwB;IACxB,eAAe,EAAE,OAAO,CAAC;IAEzB,YAAY;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,cAAc;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,mBAAmB;IACnB,YAAY,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,kBAAkB;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB,aAAa;IACb,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,gBAAgB,CAAC,CAAC;IAE/D,aAAa;IACb,QAAQ,EAAE,aAAa,CAAC;IAExB,iCAAiC;IACjC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modular-prompt/driver",
3
- "version": "0.6.3",
3
+ "version": "0.8.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -13,6 +13,7 @@
13
13
  "files": [
14
14
  "dist",
15
15
  "scripts",
16
+ "skills",
16
17
  "src/mlx-ml/python"
17
18
  ],
18
19
  "dependencies": {
@@ -23,8 +24,8 @@
23
24
  "google-auth-library": "^9.15.1",
24
25
  "js-yaml": "^4.1.0",
25
26
  "openai": "^5.19.1",
26
- "@modular-prompt/core": "0.1.12",
27
- "@modular-prompt/utils": "0.2.3"
27
+ "@modular-prompt/core": "0.1.13",
28
+ "@modular-prompt/utils": "0.2.4"
28
29
  },
29
30
  "devDependencies": {
30
31
  "@eslint/js": "^9.35.0",
@@ -54,7 +55,8 @@
54
55
  "download-model": "node scripts/download-model.js",
55
56
  "lint": "eslint src/**/*.ts",
56
57
  "typecheck": "tsc --noEmit",
57
- "clean": "rm -rf dist tsconfig.tsbuildinfo",
58
+ "copy-skills": "mkdir -p skills/driver-usage && cp ../../skills/driver-usage/SKILL.md skills/driver-usage/SKILL.md",
59
+ "clean": "rm -rf dist skills tsconfig.tsbuildinfo",
58
60
  "postinstall": "node scripts/setup-mlx.js || true",
59
61
  "setup-mlx": "node scripts/setup-mlx.js"
60
62
  }
@@ -0,0 +1,432 @@
1
+ ---
2
+ name: driver-usage
3
+ description: modular-promptのドライバー(AIDriver)の使い方ガイド。各ドライバーの初期化、Config、query/streamQuery、ツール定義、構造化出力、AIServiceによるモデル選択を参照する。
4
+ ---
5
+
6
+ # ドライバー使い方ガイド
7
+
8
+ ## ドライバーとは
9
+
10
+ `@modular-prompt/driver` は、コンパイル済みプロンプト(CompiledPrompt)をAIモデルに送信し、結果を受け取るための統一インターフェースを提供する。各AIサービスのAPI差異をドライバー層が吸収するため、プロンプト側のコードを変えずにモデルを切り替えられる。
11
+
12
+ ### 基本的な使い方
13
+
14
+ ```typescript
15
+ import { compile } from '@modular-prompt/core';
16
+ import { OpenAIDriver } from '@modular-prompt/driver';
17
+
18
+ const driver = new OpenAIDriver({ model: 'gpt-4o' });
19
+ const compiled = compile(myModule, context);
20
+
21
+ // 通常クエリ
22
+ const result = await driver.query(compiled);
23
+ console.log(result.content);
24
+
25
+ // ストリーミング
26
+ const { stream, result: resultPromise } = await driver.streamQuery(compiled);
27
+ for await (const chunk of stream) {
28
+ process.stdout.write(chunk);
29
+ }
30
+ const finalResult = await resultPromise;
31
+
32
+ await driver.close();
33
+ ```
34
+
35
+ ## AIDriver インターフェース
36
+
37
+ 全ドライバーが実装する共通インターフェース:
38
+
39
+ ```typescript
40
+ interface AIDriver {
41
+ query(prompt: CompiledPrompt, options?: QueryOptions): Promise<QueryResult>;
42
+ streamQuery(prompt: CompiledPrompt, options?: QueryOptions): Promise<StreamResult>;
43
+ close(): Promise<void>;
44
+ }
45
+ ```
46
+
47
+ ### QueryOptions
48
+
49
+ ```typescript
50
+ interface QueryOptions {
51
+ temperature?: number;
52
+ maxTokens?: number;
53
+ topP?: number;
54
+ stream?: boolean;
55
+ tools?: ToolDefinition[];
56
+ toolChoice?: ToolChoice;
57
+ }
58
+ ```
59
+
60
+ ### QueryResult
61
+
62
+ ```typescript
63
+ interface QueryResult {
64
+ content: string; // テキストレスポンス
65
+ structuredOutput?: unknown; // 構造化出力(schema指定時)
66
+ usage?: {
67
+ promptTokens: number;
68
+ completionTokens: number;
69
+ totalTokens: number;
70
+ };
71
+ toolCalls?: ToolCall[]; // ツール呼び出し
72
+ finishReason?: FinishReason; // 'stop' | 'length' | 'error' | 'tool_calls'
73
+ }
74
+ ```
75
+
76
+ ### StreamResult
77
+
78
+ ```typescript
79
+ interface StreamResult {
80
+ stream: AsyncIterable<string>; // テキストチャンクのストリーム
81
+ result: Promise<QueryResult>; // 最終結果(ストリーム完了後に解決)
82
+ }
83
+ ```
84
+
85
+ ## 各ドライバーのConfig
86
+
87
+ ### OpenAIDriver
88
+
89
+ ```typescript
90
+ import { OpenAIDriver } from '@modular-prompt/driver';
91
+
92
+ const driver = new OpenAIDriver({
93
+ apiKey: process.env.OPENAI_API_KEY, // 環境変数で代替可
94
+ model: 'gpt-4o-mini', // デフォルト: 'gpt-4o-mini'
95
+ baseURL: 'https://...', // カスタムエンドポイント(オプション)
96
+ organization: '...', // Organization ID(オプション)
97
+ defaultOptions: {
98
+ temperature: 0.7,
99
+ maxTokens: 2000,
100
+ frequencyPenalty: 0, // OpenAI固有
101
+ presencePenalty: 0, // OpenAI固有
102
+ stop: ['---'], // 停止シーケンス
103
+ responseFormat: { type: 'json_object' },
104
+ seed: 42
105
+ }
106
+ });
107
+ ```
108
+
109
+ ### AnthropicDriver
110
+
111
+ ```typescript
112
+ import { AnthropicDriver } from '@modular-prompt/driver';
113
+
114
+ const driver = new AnthropicDriver({
115
+ apiKey: process.env.ANTHROPIC_API_KEY, // 環境変数で代替可
116
+ model: 'claude-3-5-sonnet-20241022', // デフォルト
117
+ defaultOptions: {
118
+ maxTokens: 4096,
119
+ temperature: 0.7,
120
+ topK: 40, // Anthropic固有
121
+ stopSequences: ['---']
122
+ }
123
+ });
124
+ ```
125
+
126
+ ### VertexAIDriver
127
+
128
+ ```typescript
129
+ import { VertexAIDriver } from '@modular-prompt/driver';
130
+
131
+ const driver = new VertexAIDriver({
132
+ project: 'my-gcp-project', // 環境変数 GOOGLE_CLOUD_PROJECT で代替可
133
+ location: 'us-central1', // デフォルト: 'us-central1'
134
+ model: 'gemini-2.0-flash-001', // デフォルト
135
+ temperature: 0.05,
136
+ defaultOptions: {
137
+ maxTokens: 1000,
138
+ topP: 0.95,
139
+ topK: 40
140
+ }
141
+ });
142
+ ```
143
+
144
+ Google Cloud認証(ADCまたはサービスアカウント)が必要。
145
+
146
+ ### GoogleGenAIDriver
147
+
148
+ ```typescript
149
+ import { GoogleGenAIDriver } from '@modular-prompt/driver';
150
+
151
+ const driver = new GoogleGenAIDriver({
152
+ apiKey: process.env.GOOGLE_GENAI_API_KEY, // 必須
153
+ model: 'gemini-2.0-flash-exp',
154
+ temperature: 0.7,
155
+ defaultOptions: {
156
+ maxTokens: 2048,
157
+ topP: 0.95,
158
+ topK: 40,
159
+ thinkingConfig: { thinkingLevel: 'HIGH' } // GoogleGenAI固有
160
+ }
161
+ });
162
+ ```
163
+
164
+ APIキーのみで利用可能(Google AI Studioから取得)。
165
+
166
+ ### OllamaDriver
167
+
168
+ ```typescript
169
+ import { OllamaDriver } from '@modular-prompt/driver';
170
+
171
+ const driver = new OllamaDriver({
172
+ baseURL: 'http://localhost:11434/v1', // デフォルト
173
+ model: 'llama3.2' // デフォルト
174
+ });
175
+ ```
176
+
177
+ OpenAI互換APIでローカルLLMにアクセス。
178
+
179
+ ### MlxDriver
180
+
181
+ ```typescript
182
+ import { MlxDriver } from '@modular-prompt/driver';
183
+
184
+ const driver = new MlxDriver({
185
+ model: 'mlx-community/Llama-3.2-3B-Instruct-4bit', // 必須
186
+ defaultOptions: {
187
+ temperature: 0.7,
188
+ maxTokens: 500,
189
+ repetitionPenalty: 1.1, // MLX固有
190
+ repetitionContextSize: 20 // MLX固有
191
+ }
192
+ });
193
+
194
+ // 使用後は必ずclose()(Pythonサブプロセス終了)
195
+ await driver.close();
196
+ ```
197
+
198
+ Apple Silicon専用。Python 3.11以上が必要。
199
+
200
+ ### テスト・デバッグ用ドライバー
201
+
202
+ ```typescript
203
+ import { TestDriver, EchoDriver } from '@modular-prompt/driver';
204
+
205
+ // TestDriver: モックレスポンス
206
+ const testDriver = new TestDriver({
207
+ responses: ['応答1', '応答2'], // キューから順に返す
208
+ delay: 100 // レイテンシのシミュレート(ms)
209
+ });
210
+
211
+ // レスポンスプロバイダ関数
212
+ const testDriver2 = new TestDriver({
213
+ responses: (prompt, options) => {
214
+ if (prompt.metadata?.outputSchema) {
215
+ return JSON.stringify({ result: 'ok' });
216
+ }
217
+ return 'テキスト応答';
218
+ }
219
+ });
220
+
221
+ // EchoDriver: フォーマット済みプロンプトをそのまま返す(AI呼び出しなし)
222
+ const echoDriver = new EchoDriver({
223
+ format: 'debug', // 'text' | 'messages' | 'raw' | 'both' | 'debug'
224
+ includeMetadata: true
225
+ });
226
+ ```
227
+
228
+ ## ツール定義(Function Calling)
229
+
230
+ ### ToolDefinition
231
+
232
+ ```typescript
233
+ const tools: ToolDefinition[] = [
234
+ {
235
+ name: 'get_weather',
236
+ description: '指定都市の天気を取得',
237
+ parameters: {
238
+ type: 'object',
239
+ properties: {
240
+ city: { type: 'string', description: '都市名' },
241
+ unit: { type: 'string', enum: ['celsius', 'fahrenheit'] }
242
+ },
243
+ required: ['city']
244
+ }
245
+ }
246
+ ];
247
+ ```
248
+
249
+ ### ToolChoice
250
+
251
+ ```typescript
252
+ type ToolChoice =
253
+ | 'auto' // モデルが自動判断(デフォルト)
254
+ | 'none' // ツール使用禁止
255
+ | 'required' // 必ず1つ以上のツールを使用
256
+ | { name: string }; // 特定ツールを強制
257
+ ```
258
+
259
+ ### ツール呼び出しの処理
260
+
261
+ ```typescript
262
+ const result = await driver.query(compiled, { tools, toolChoice: 'auto' });
263
+
264
+ if (result.toolCalls) {
265
+ for (const call of result.toolCalls) {
266
+ console.log(call.name); // 関数名
267
+ console.log(call.id); // 呼び出しID
268
+ console.log(call.arguments); // 引数オブジェクト
269
+ }
270
+ }
271
+ ```
272
+
273
+ 対応ドライバー: OpenAI、Anthropic、VertexAI、GoogleGenAI
274
+
275
+ ### ツール結果の返し方(会話ループ)
276
+
277
+ ツール呼び出し結果をモデルに返す会話ループは利用者側で実装する。`QueryOptions.messages` にツール結果を含めて再クエリする。
278
+
279
+ ```typescript
280
+ const result1 = await driver.query(compiled, { tools, toolChoice: 'auto' });
281
+
282
+ if (result1.toolCalls) {
283
+ // ツールを実行して結果を収集
284
+ const toolResults = await Promise.all(
285
+ result1.toolCalls.map(async (tc) => {
286
+ const data = await executeFunction(tc.name, tc.arguments);
287
+ return {
288
+ role: 'tool' as const,
289
+ toolCallId: tc.id,
290
+ name: tc.name,
291
+ kind: 'data' as const, // 'text' | 'data' | 'error'
292
+ value: data
293
+ };
294
+ })
295
+ );
296
+
297
+ // ツール結果を含めて再クエリ
298
+ const result2 = await driver.query(compiled, {
299
+ tools,
300
+ messages: [
301
+ { role: 'assistant', content: result1.content, toolCalls: result1.toolCalls },
302
+ ...toolResults
303
+ ]
304
+ });
305
+ }
306
+ ```
307
+
308
+ ### ToolResultKind
309
+
310
+ ツール結果の種類を示すタグ:
311
+ - `'text'` - プレーンテキスト
312
+ - `'data'` - 構造化データ(オブジェクト等)
313
+ - `'error'` - エラー情報
314
+
315
+ ## 構造化出力
316
+
317
+ プロンプトの `schema` セクションに JSONElement を定義すると、ドライバーが自動的に構造化出力を処理する。
318
+
319
+ ```typescript
320
+ const myModule: PromptModule = {
321
+ objective: ['ユーザー情報を抽出する'],
322
+ schema: [{
323
+ type: 'json',
324
+ content: {
325
+ type: 'object',
326
+ properties: {
327
+ name: { type: 'string' },
328
+ age: { type: 'number' }
329
+ },
330
+ required: ['name', 'age']
331
+ }
332
+ }]
333
+ };
334
+
335
+ const result = await driver.query(compile(myModule, ctx));
336
+ const data = result.structuredOutput as { name: string; age: number };
337
+ ```
338
+
339
+ ドライバーごとの実装方式:
340
+ - **ネイティブサポート**: OpenAI(`response_format`)、VertexAI / GoogleGenAI(`responseSchema`)
341
+ - **JSON抽出型**: Anthropic、MLX(プロンプト指示 + レスポンスからJSON抽出)
342
+
343
+ ## AIService(モデル選択)
344
+
345
+ 複数モデルを登録し、能力(capabilities)ベースで最適なモデルを自動選択する。
346
+
347
+ ### 設定
348
+
349
+ ```typescript
350
+ import { AIService } from '@modular-prompt/driver';
351
+
352
+ const service = new AIService({
353
+ models: [
354
+ {
355
+ model: 'gpt-4o',
356
+ provider: 'openai',
357
+ capabilities: ['streaming', 'japanese', 'tools', 'structured'],
358
+ priority: 10,
359
+ cost: { input: 0.01, output: 0.03 }
360
+ },
361
+ {
362
+ model: 'claude-3-5-sonnet-20241022',
363
+ provider: 'anthropic',
364
+ capabilities: ['streaming', 'japanese', 'tools', 'reasoning'],
365
+ priority: 8
366
+ }
367
+ ],
368
+ drivers: {
369
+ openai: { apiKey: process.env.OPENAI_API_KEY },
370
+ anthropic: { apiKey: process.env.ANTHROPIC_API_KEY }
371
+ },
372
+ defaultOptions: {
373
+ temperature: 0.7,
374
+ maxTokens: 2048
375
+ }
376
+ });
377
+ ```
378
+
379
+ ### ModelSpec
380
+
381
+ ```typescript
382
+ interface ModelSpec {
383
+ model: string;
384
+ provider: DriverProvider;
385
+ capabilities: DriverCapability[];
386
+ priority?: number; // 高いほど優先
387
+ disabled?: boolean; // 無効化フラグ
388
+ maxInputTokens?: number;
389
+ maxOutputTokens?: number;
390
+ maxTotalTokens?: number;
391
+ tokensPerMinute?: number; // TPM制限
392
+ requestsPerMinute?: number; // RPM制限
393
+ cost?: { input: number; output: number };
394
+ metadata?: Record<string, unknown>;
395
+ }
396
+ ```
397
+
398
+ ### DriverCapability(能力フラグ)
399
+
400
+ | 能力 | 説明 |
401
+ |------|------|
402
+ | `streaming` | ストリーミング応答 |
403
+ | `local` | ローカル実行 |
404
+ | `fast` | 高速応答 |
405
+ | `large-context` | 大規模コンテキスト |
406
+ | `multilingual` | 多言語対応 |
407
+ | `japanese` | 日本語特化 |
408
+ | `coding` | コーディング特化 |
409
+ | `reasoning` | 推論・思考特化 |
410
+ | `chat` | チャット特化 |
411
+ | `tools` | ツール使用 |
412
+ | `vision` | 画像認識 |
413
+ | `audio` | 音声処理 |
414
+ | `structured` | 構造化出力 |
415
+ | `json` | JSON出力 |
416
+ | `function-calling` | 関数呼び出し |
417
+
418
+ ### モデル選択
419
+
420
+ ```typescript
421
+ // 能力ベースでドライバーを自動作成
422
+ const driver = await service.createDriverFromCapabilities(
423
+ ['japanese', 'streaming'],
424
+ {
425
+ preferLocal: true, // ローカル優先
426
+ preferProvider: 'anthropic', // 特定プロバイダー優先
427
+ excludeProviders: ['openai'],
428
+ preferFast: true, // 高速優先
429
+ lenient: true // 条件緩和モード(条件を後ろから減らして再検索)
430
+ }
431
+ );
432
+ ```