@nahisaho/musubix-expert-delegation 3.2.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.
- package/README.md +208 -0
- package/dist/delegation/advisory-mode.d.ts +47 -0
- package/dist/delegation/advisory-mode.d.ts.map +1 -0
- package/dist/delegation/advisory-mode.js +135 -0
- package/dist/delegation/advisory-mode.js.map +1 -0
- package/dist/delegation/delegation-engine.d.ts +91 -0
- package/dist/delegation/delegation-engine.d.ts.map +1 -0
- package/dist/delegation/delegation-engine.js +272 -0
- package/dist/delegation/delegation-engine.js.map +1 -0
- package/dist/delegation/implementation-mode.d.ts +55 -0
- package/dist/delegation/implementation-mode.d.ts.map +1 -0
- package/dist/delegation/implementation-mode.js +225 -0
- package/dist/delegation/implementation-mode.js.map +1 -0
- package/dist/delegation/index.d.ts +10 -0
- package/dist/delegation/index.d.ts.map +1 -0
- package/dist/delegation/index.js +10 -0
- package/dist/delegation/index.js.map +1 -0
- package/dist/delegation/prompt-builder.d.ts +52 -0
- package/dist/delegation/prompt-builder.d.ts.map +1 -0
- package/dist/delegation/prompt-builder.js +220 -0
- package/dist/delegation/prompt-builder.js.map +1 -0
- package/dist/delegation/retry-handler.d.ts +90 -0
- package/dist/delegation/retry-handler.d.ts.map +1 -0
- package/dist/delegation/retry-handler.js +186 -0
- package/dist/delegation/retry-handler.js.map +1 -0
- package/dist/experts/architect.d.ts +16 -0
- package/dist/experts/architect.d.ts.map +1 -0
- package/dist/experts/architect.js +68 -0
- package/dist/experts/architect.js.map +1 -0
- package/dist/experts/code-reviewer.d.ts +15 -0
- package/dist/experts/code-reviewer.d.ts.map +1 -0
- package/dist/experts/code-reviewer.js +70 -0
- package/dist/experts/code-reviewer.js.map +1 -0
- package/dist/experts/ears-analyst.d.ts +16 -0
- package/dist/experts/ears-analyst.d.ts.map +1 -0
- package/dist/experts/ears-analyst.js +88 -0
- package/dist/experts/ears-analyst.js.map +1 -0
- package/dist/experts/expert-interface.d.ts +21 -0
- package/dist/experts/expert-interface.d.ts.map +1 -0
- package/dist/experts/expert-interface.js +22 -0
- package/dist/experts/expert-interface.js.map +1 -0
- package/dist/experts/expert-manager.d.ts +81 -0
- package/dist/experts/expert-manager.d.ts.map +1 -0
- package/dist/experts/expert-manager.js +176 -0
- package/dist/experts/expert-manager.js.map +1 -0
- package/dist/experts/formal-verifier.d.ts +16 -0
- package/dist/experts/formal-verifier.d.ts.map +1 -0
- package/dist/experts/formal-verifier.js +87 -0
- package/dist/experts/formal-verifier.js.map +1 -0
- package/dist/experts/index.d.ts +19 -0
- package/dist/experts/index.d.ts.map +1 -0
- package/dist/experts/index.js +28 -0
- package/dist/experts/index.js.map +1 -0
- package/dist/experts/ontology-reasoner.d.ts +16 -0
- package/dist/experts/ontology-reasoner.d.ts.map +1 -0
- package/dist/experts/ontology-reasoner.js +95 -0
- package/dist/experts/ontology-reasoner.js.map +1 -0
- package/dist/experts/plan-reviewer.d.ts +16 -0
- package/dist/experts/plan-reviewer.d.ts.map +1 -0
- package/dist/experts/plan-reviewer.js +75 -0
- package/dist/experts/plan-reviewer.js.map +1 -0
- package/dist/experts/security-analyst.d.ts +15 -0
- package/dist/experts/security-analyst.d.ts.map +1 -0
- package/dist/experts/security-analyst.js +67 -0
- package/dist/experts/security-analyst.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/handlers.d.ts +142 -0
- package/dist/mcp/handlers.d.ts.map +1 -0
- package/dist/mcp/handlers.js +309 -0
- package/dist/mcp/handlers.js.map +1 -0
- package/dist/mcp/index.d.ts +7 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +7 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/schemas.d.ts +80 -0
- package/dist/mcp/schemas.d.ts.map +1 -0
- package/dist/mcp/schemas.js +318 -0
- package/dist/mcp/schemas.js.map +1 -0
- package/dist/providers/index.d.ts +9 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +8 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/model-selector.d.ts +54 -0
- package/dist/providers/model-selector.d.ts.map +1 -0
- package/dist/providers/model-selector.js +83 -0
- package/dist/providers/model-selector.js.map +1 -0
- package/dist/providers/provider-interface.d.ts +9 -0
- package/dist/providers/provider-interface.d.ts.map +1 -0
- package/dist/providers/provider-interface.js +9 -0
- package/dist/providers/provider-interface.js.map +1 -0
- package/dist/providers/usage-statistics.d.ts +59 -0
- package/dist/providers/usage-statistics.d.ts.map +1 -0
- package/dist/providers/usage-statistics.js +141 -0
- package/dist/providers/usage-statistics.js.map +1 -0
- package/dist/providers/vscode-lm-provider.d.ts +82 -0
- package/dist/providers/vscode-lm-provider.d.ts.map +1 -0
- package/dist/providers/vscode-lm-provider.js +232 -0
- package/dist/providers/vscode-lm-provider.js.map +1 -0
- package/dist/test/helpers.d.ts +54 -0
- package/dist/test/helpers.d.ts.map +1 -0
- package/dist/test/helpers.js +135 -0
- package/dist/test/helpers.js.map +1 -0
- package/dist/test/index.d.ts +7 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/index.js +7 -0
- package/dist/test/index.js.map +1 -0
- package/dist/test/mocks.d.ts +128 -0
- package/dist/test/mocks.d.ts.map +1 -0
- package/dist/test/mocks.js +170 -0
- package/dist/test/mocks.js.map +1 -0
- package/dist/triggers/index.d.ts +10 -0
- package/dist/triggers/index.d.ts.map +1 -0
- package/dist/triggers/index.js +8 -0
- package/dist/triggers/index.js.map +1 -0
- package/dist/triggers/proactive-delegation.d.ts +88 -0
- package/dist/triggers/proactive-delegation.d.ts.map +1 -0
- package/dist/triggers/proactive-delegation.js +201 -0
- package/dist/triggers/proactive-delegation.js.map +1 -0
- package/dist/triggers/semantic-router.d.ts +57 -0
- package/dist/triggers/semantic-router.d.ts.map +1 -0
- package/dist/triggers/semantic-router.js +139 -0
- package/dist/triggers/semantic-router.js.map +1 -0
- package/dist/triggers/trigger-patterns.d.ts +21 -0
- package/dist/triggers/trigger-patterns.d.ts.map +1 -0
- package/dist/triggers/trigger-patterns.js +90 -0
- package/dist/triggers/trigger-patterns.js.map +1 -0
- package/dist/types/errors.d.ts +56 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +98 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/index.d.ts +190 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +9 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/musubix-expert-delegation
|
|
3
|
+
* Usage Statistics
|
|
4
|
+
*
|
|
5
|
+
* DES-PRV-002
|
|
6
|
+
* Traces to: REQ-PRV-002
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* UsageStatisticsを作成するファクトリ関数
|
|
10
|
+
*/
|
|
11
|
+
export function createUsageStatistics() {
|
|
12
|
+
return new UsageStatistics();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* 使用統計管理
|
|
16
|
+
*
|
|
17
|
+
* モデルごとの成功/失敗回数、レイテンシなどを記録する。
|
|
18
|
+
*/
|
|
19
|
+
export class UsageStatistics {
|
|
20
|
+
stats = new Map();
|
|
21
|
+
/**
|
|
22
|
+
* 成功を記録
|
|
23
|
+
* @param model - モデルID
|
|
24
|
+
* @param latencyMs - レイテンシ(ミリ秒)
|
|
25
|
+
*/
|
|
26
|
+
recordSuccess(model, latencyMs) {
|
|
27
|
+
const existing = this.stats.get(model);
|
|
28
|
+
if (existing) {
|
|
29
|
+
const newTotal = existing.totalLatencyMs + latencyMs;
|
|
30
|
+
const newCount = existing.successCount + 1;
|
|
31
|
+
this.stats.set(model, {
|
|
32
|
+
model,
|
|
33
|
+
successCount: newCount,
|
|
34
|
+
failureCount: existing.failureCount,
|
|
35
|
+
totalLatencyMs: newTotal,
|
|
36
|
+
avgLatencyMs: newTotal / newCount,
|
|
37
|
+
lastUsed: new Date(),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
this.stats.set(model, {
|
|
42
|
+
model,
|
|
43
|
+
successCount: 1,
|
|
44
|
+
failureCount: 0,
|
|
45
|
+
totalLatencyMs: latencyMs,
|
|
46
|
+
avgLatencyMs: latencyMs,
|
|
47
|
+
lastUsed: new Date(),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* 失敗を記録
|
|
53
|
+
* @param model - モデルID
|
|
54
|
+
* @param _error - エラー(将来の分析用)
|
|
55
|
+
*/
|
|
56
|
+
recordFailure(model, _error) {
|
|
57
|
+
const existing = this.stats.get(model);
|
|
58
|
+
if (existing) {
|
|
59
|
+
this.stats.set(model, {
|
|
60
|
+
...existing,
|
|
61
|
+
failureCount: existing.failureCount + 1,
|
|
62
|
+
lastUsed: new Date(),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
this.stats.set(model, {
|
|
67
|
+
model,
|
|
68
|
+
successCount: 0,
|
|
69
|
+
failureCount: 1,
|
|
70
|
+
totalLatencyMs: 0,
|
|
71
|
+
avgLatencyMs: 0,
|
|
72
|
+
lastUsed: new Date(),
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* 全モデルの統計を取得
|
|
78
|
+
*/
|
|
79
|
+
getStats() {
|
|
80
|
+
return Array.from(this.stats.values());
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* 特定モデルの統計を取得
|
|
84
|
+
* @param model - モデルID
|
|
85
|
+
*/
|
|
86
|
+
getModelStats(model) {
|
|
87
|
+
return this.stats.get(model) ?? null;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 成功率を計算
|
|
91
|
+
* @param model - モデルID
|
|
92
|
+
*/
|
|
93
|
+
getSuccessRate(model) {
|
|
94
|
+
const stats = this.stats.get(model);
|
|
95
|
+
if (!stats) {
|
|
96
|
+
return 0;
|
|
97
|
+
}
|
|
98
|
+
const total = stats.successCount + stats.failureCount;
|
|
99
|
+
if (total === 0) {
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
return stats.successCount / total;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* 最も信頼性の高いモデルを取得
|
|
106
|
+
*/
|
|
107
|
+
getMostReliable() {
|
|
108
|
+
let bestModel = null;
|
|
109
|
+
let bestScore = -1;
|
|
110
|
+
for (const [model, stats] of this.stats) {
|
|
111
|
+
const total = stats.successCount + stats.failureCount;
|
|
112
|
+
if (total < 3) {
|
|
113
|
+
// 最低3回の使用が必要
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
const successRate = stats.successCount / total;
|
|
117
|
+
if (successRate > bestScore) {
|
|
118
|
+
bestScore = successRate;
|
|
119
|
+
bestModel = model;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return bestModel;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 統計をリセット
|
|
126
|
+
*/
|
|
127
|
+
reset() {
|
|
128
|
+
this.stats.clear();
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* JSON形式でエクスポート
|
|
132
|
+
*/
|
|
133
|
+
toJSON() {
|
|
134
|
+
const result = {};
|
|
135
|
+
for (const [model, stats] of this.stats) {
|
|
136
|
+
result[model] = stats;
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=usage-statistics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-statistics.js","sourceRoot":"","sources":["../../src/providers/usage-statistics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/musubix-expert-delegation
|
|
3
|
+
* VS Code LM Provider
|
|
4
|
+
*
|
|
5
|
+
* DES-PRV-001
|
|
6
|
+
* Traces to: REQ-PRV-001
|
|
7
|
+
*/
|
|
8
|
+
import type { LMProvider, RequestOptions, ProviderResponse, ModelInfo, ModelCriteria } from '../types/index.js';
|
|
9
|
+
type Thenable<T> = PromiseLike<T>;
|
|
10
|
+
interface VSCodeLM {
|
|
11
|
+
selectChatModels(selector?: {
|
|
12
|
+
family?: string;
|
|
13
|
+
vendor?: string;
|
|
14
|
+
}): Thenable<VSCodeLanguageModelChat[]>;
|
|
15
|
+
}
|
|
16
|
+
interface VSCodeLanguageModelChat {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
family: string;
|
|
20
|
+
vendor: string;
|
|
21
|
+
maxInputTokens: number;
|
|
22
|
+
sendRequest(messages: VSCodeLanguageModelChatMessage[], options?: unknown, token?: {
|
|
23
|
+
isCancellationRequested: boolean;
|
|
24
|
+
}): Thenable<AsyncIterable<string>>;
|
|
25
|
+
}
|
|
26
|
+
interface VSCodeLanguageModelChatMessage {
|
|
27
|
+
role: string;
|
|
28
|
+
content: string;
|
|
29
|
+
}
|
|
30
|
+
interface VSCodeNamespace {
|
|
31
|
+
lm: VSCodeLM;
|
|
32
|
+
LanguageModelChatMessage: {
|
|
33
|
+
User(content: string): VSCodeLanguageModelChatMessage;
|
|
34
|
+
Assistant(content: string): VSCodeLanguageModelChatMessage;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* VSCodeLMProviderを作成するファクトリ関数
|
|
39
|
+
* @param vscodeAPI - VS Code API(オプション、テスト用)
|
|
40
|
+
*/
|
|
41
|
+
export declare function createVSCodeLMProvider(vscodeAPI?: VSCodeNamespace): VSCodeLMProvider;
|
|
42
|
+
/**
|
|
43
|
+
* VS Code Language Model Provider
|
|
44
|
+
*
|
|
45
|
+
* VS Code LM APIを使用してLLMにアクセスするプロバイダー。
|
|
46
|
+
* GitHub Copilotの認証を活用し、追加のAPIキー設定を不要にする。
|
|
47
|
+
*/
|
|
48
|
+
export declare class VSCodeLMProvider implements LMProvider {
|
|
49
|
+
private vscode;
|
|
50
|
+
private currentModel;
|
|
51
|
+
constructor(vscodeAPI?: VSCodeNamespace);
|
|
52
|
+
/**
|
|
53
|
+
* VS Code APIを遅延取得
|
|
54
|
+
*/
|
|
55
|
+
private getVSCode;
|
|
56
|
+
/**
|
|
57
|
+
* プロンプトを送信してレスポンスを取得
|
|
58
|
+
*/
|
|
59
|
+
sendRequest(options: RequestOptions): Promise<ProviderResponse>;
|
|
60
|
+
/**
|
|
61
|
+
* ストリームレスポンスを収集
|
|
62
|
+
*/
|
|
63
|
+
private collectResponse;
|
|
64
|
+
/**
|
|
65
|
+
* 利用可能なモデル一覧を取得
|
|
66
|
+
*/
|
|
67
|
+
listModels(): Promise<ModelInfo[]>;
|
|
68
|
+
/**
|
|
69
|
+
* 条件に合うモデルを選択
|
|
70
|
+
*/
|
|
71
|
+
selectModel(criteria: ModelCriteria): Promise<ModelInfo | null>;
|
|
72
|
+
/**
|
|
73
|
+
* プロバイダーが利用可能かチェック
|
|
74
|
+
*/
|
|
75
|
+
isAvailable(): Promise<boolean>;
|
|
76
|
+
/**
|
|
77
|
+
* 現在選択されているモデルを取得
|
|
78
|
+
*/
|
|
79
|
+
getCurrentModel(): ModelInfo | null;
|
|
80
|
+
}
|
|
81
|
+
export {};
|
|
82
|
+
//# sourceMappingURL=vscode-lm-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vscode-lm-provider.d.ts","sourceRoot":"","sources":["../../src/providers/vscode-lm-provider.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,aAAa,EACd,MAAM,mBAAmB,CAAC;AAI3B,KAAK,QAAQ,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;AAGlC,UAAU,QAAQ;IAChB,gBAAgB,CAAC,QAAQ,CAAC,EAAE;QAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,QAAQ,CAAC,uBAAuB,EAAE,CAAC,CAAC;CACzC;AAED,UAAU,uBAAuB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CACT,QAAQ,EAAE,8BAA8B,EAAE,EAC1C,OAAO,CAAC,EAAE,OAAO,EACjB,KAAK,CAAC,EAAE;QAAE,uBAAuB,EAAE,OAAO,CAAA;KAAE,GAC3C,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;CACpC;AAED,UAAU,8BAA8B;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,eAAe;IACvB,EAAE,EAAE,QAAQ,CAAC;IACb,wBAAwB,EAAE;QACxB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,8BAA8B,CAAC;QACtD,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,8BAA8B,CAAC;KAC5D,CAAC;CACH;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,CAAC,EAAE,eAAe,GAAG,gBAAgB,CAEpF;AAED;;;;;GAKG;AACH,qBAAa,gBAAiB,YAAW,UAAU;IACjD,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,YAAY,CAAwC;gBAEhD,SAAS,CAAC,EAAE,eAAe;IAIvC;;OAEG;YACW,SAAS;IAkBvB;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA2FrE;;OAEG;YACW,eAAe;IAU7B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAuBxC;;OAEG;IACG,WAAW,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IA2CrE;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAUrC;;OAEG;IACH,eAAe,IAAI,SAAS,GAAG,IAAI;CAapC"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/musubix-expert-delegation
|
|
3
|
+
* VS Code LM Provider
|
|
4
|
+
*
|
|
5
|
+
* DES-PRV-001
|
|
6
|
+
* Traces to: REQ-PRV-001
|
|
7
|
+
*/
|
|
8
|
+
import { DelegationError } from '../types/errors.js';
|
|
9
|
+
/**
|
|
10
|
+
* VSCodeLMProviderを作成するファクトリ関数
|
|
11
|
+
* @param vscodeAPI - VS Code API(オプション、テスト用)
|
|
12
|
+
*/
|
|
13
|
+
export function createVSCodeLMProvider(vscodeAPI) {
|
|
14
|
+
return new VSCodeLMProvider(vscodeAPI);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* VS Code Language Model Provider
|
|
18
|
+
*
|
|
19
|
+
* VS Code LM APIを使用してLLMにアクセスするプロバイダー。
|
|
20
|
+
* GitHub Copilotの認証を活用し、追加のAPIキー設定を不要にする。
|
|
21
|
+
*/
|
|
22
|
+
export class VSCodeLMProvider {
|
|
23
|
+
vscode = null;
|
|
24
|
+
currentModel = null;
|
|
25
|
+
constructor(vscodeAPI) {
|
|
26
|
+
this.vscode = vscodeAPI ?? null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* VS Code APIを遅延取得
|
|
30
|
+
*/
|
|
31
|
+
async getVSCode() {
|
|
32
|
+
if (this.vscode) {
|
|
33
|
+
return this.vscode;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
// VS Code環境で動的にインポート
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
38
|
+
const vscodeModule = require('vscode');
|
|
39
|
+
this.vscode = vscodeModule;
|
|
40
|
+
return vscodeModule;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
throw DelegationError.fromCode('PROVIDER_UNAVAILABLE', {
|
|
44
|
+
reason: 'VS Code environment not available',
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* プロンプトを送信してレスポンスを取得
|
|
50
|
+
*/
|
|
51
|
+
async sendRequest(options) {
|
|
52
|
+
try {
|
|
53
|
+
const vscode = await this.getVSCode();
|
|
54
|
+
// モデル選択
|
|
55
|
+
let model;
|
|
56
|
+
if (options.model) {
|
|
57
|
+
const models = await vscode.lm.selectChatModels();
|
|
58
|
+
const found = models.find((m) => m.id === options.model);
|
|
59
|
+
if (!found) {
|
|
60
|
+
throw DelegationError.fromCode('MODEL_NOT_AVAILABLE', {
|
|
61
|
+
requestedModel: options.model,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
model = found;
|
|
65
|
+
}
|
|
66
|
+
else if (this.currentModel) {
|
|
67
|
+
model = this.currentModel;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const models = await vscode.lm.selectChatModels();
|
|
71
|
+
if (models.length === 0) {
|
|
72
|
+
throw DelegationError.fromCode('MODEL_NOT_AVAILABLE', {
|
|
73
|
+
reason: 'No models available',
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
model = models[0];
|
|
77
|
+
}
|
|
78
|
+
// メッセージをフォーマット
|
|
79
|
+
const userContent = options.messages
|
|
80
|
+
.filter(m => m.role === 'user')
|
|
81
|
+
.map(m => m.content)
|
|
82
|
+
.join('\n\n');
|
|
83
|
+
const systemContent = options.messages
|
|
84
|
+
.filter(m => m.role === 'system')
|
|
85
|
+
.map(m => m.content)
|
|
86
|
+
.join('\n\n');
|
|
87
|
+
const prompt = systemContent
|
|
88
|
+
? `${systemContent}\n\n---\n\n${userContent}`
|
|
89
|
+
: userContent;
|
|
90
|
+
// メッセージ作成
|
|
91
|
+
const messages = [vscode.LanguageModelChatMessage.User(prompt)];
|
|
92
|
+
// リクエスト送信
|
|
93
|
+
const response = await model.sendRequest(messages, undefined, options.cancellationToken);
|
|
94
|
+
// ストリームレスポンスを収集
|
|
95
|
+
const content = await this.collectResponse(response);
|
|
96
|
+
return {
|
|
97
|
+
content,
|
|
98
|
+
finishReason: 'stop',
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
if (error instanceof DelegationError) {
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
// タイムアウト判定
|
|
106
|
+
if (error instanceof Error && error.message.includes('timeout')) {
|
|
107
|
+
throw DelegationError.fromCode('TIMEOUT', {
|
|
108
|
+
originalError: error.message,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// 認証エラー判定
|
|
112
|
+
if (error instanceof Error && error.message.includes('auth')) {
|
|
113
|
+
throw DelegationError.fromCode('AUTHENTICATION_FAILED', {
|
|
114
|
+
originalError: error.message,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
// レート制限判定
|
|
118
|
+
if (error instanceof Error && error.message.includes('rate')) {
|
|
119
|
+
throw DelegationError.fromCode('RATE_LIMITED', {
|
|
120
|
+
originalError: error.message,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
throw DelegationError.fromCode('PROVIDER_UNAVAILABLE', {
|
|
124
|
+
originalError: error instanceof Error ? error.message : String(error),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* ストリームレスポンスを収集
|
|
130
|
+
*/
|
|
131
|
+
async collectResponse(stream) {
|
|
132
|
+
const chunks = [];
|
|
133
|
+
for await (const chunk of stream) {
|
|
134
|
+
chunks.push(chunk);
|
|
135
|
+
}
|
|
136
|
+
return chunks.join('');
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* 利用可能なモデル一覧を取得
|
|
140
|
+
*/
|
|
141
|
+
async listModels() {
|
|
142
|
+
try {
|
|
143
|
+
const vscode = await this.getVSCode();
|
|
144
|
+
const models = await vscode.lm.selectChatModels();
|
|
145
|
+
return models.map((m) => ({
|
|
146
|
+
id: m.id,
|
|
147
|
+
name: m.name,
|
|
148
|
+
family: m.family,
|
|
149
|
+
version: '', // VS Code LM APIにはversionがない
|
|
150
|
+
vendor: m.vendor,
|
|
151
|
+
maxInputTokens: m.maxInputTokens,
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
if (error instanceof DelegationError) {
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
throw DelegationError.fromCode('PROVIDER_UNAVAILABLE', {
|
|
159
|
+
originalError: error instanceof Error ? error.message : String(error),
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* 条件に合うモデルを選択
|
|
165
|
+
*/
|
|
166
|
+
async selectModel(criteria) {
|
|
167
|
+
try {
|
|
168
|
+
const vscode = await this.getVSCode();
|
|
169
|
+
const models = await vscode.lm.selectChatModels({
|
|
170
|
+
family: criteria.family,
|
|
171
|
+
vendor: criteria.vendor,
|
|
172
|
+
});
|
|
173
|
+
// 最小トークン数でフィルタ
|
|
174
|
+
const filtered = criteria.minTokens
|
|
175
|
+
? models.filter((m) => m.maxInputTokens >= criteria.minTokens)
|
|
176
|
+
: models;
|
|
177
|
+
if (filtered.length === 0) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
// 最もトークン数が多いモデルを選択
|
|
181
|
+
const selected = filtered.reduce((best, current) => current.maxInputTokens > best.maxInputTokens ? current : best);
|
|
182
|
+
// 現在のモデルとして保持
|
|
183
|
+
this.currentModel = models.find((m) => m.id === selected.id) ?? null;
|
|
184
|
+
return {
|
|
185
|
+
id: selected.id,
|
|
186
|
+
name: selected.name,
|
|
187
|
+
family: selected.family,
|
|
188
|
+
version: '', // VS Code LM APIにはversionがない
|
|
189
|
+
vendor: selected.vendor,
|
|
190
|
+
maxInputTokens: selected.maxInputTokens,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
if (error instanceof DelegationError) {
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
throw DelegationError.fromCode('PROVIDER_UNAVAILABLE', {
|
|
198
|
+
originalError: error instanceof Error ? error.message : String(error),
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* プロバイダーが利用可能かチェック
|
|
204
|
+
*/
|
|
205
|
+
async isAvailable() {
|
|
206
|
+
try {
|
|
207
|
+
const vscode = await this.getVSCode();
|
|
208
|
+
const models = await vscode.lm.selectChatModels();
|
|
209
|
+
return models.length > 0;
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* 現在選択されているモデルを取得
|
|
217
|
+
*/
|
|
218
|
+
getCurrentModel() {
|
|
219
|
+
if (!this.currentModel) {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
id: this.currentModel.id,
|
|
224
|
+
name: this.currentModel.name,
|
|
225
|
+
family: this.currentModel.family,
|
|
226
|
+
version: '', // VS Code LM APIにはversionがない
|
|
227
|
+
vendor: this.currentModel.vendor,
|
|
228
|
+
maxInputTokens: this.currentModel.maxInputTokens,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=vscode-lm-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vscode-lm-provider.js","sourceRoot":"","sources":["../../src/providers/vscode-lm-provider.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAuCrD;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAA2B;IAChE,OAAO,IAAI,gBAAgB,CAAC,SAAS,CAAC,CAAC;AACzC,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,gBAAgB;IACnB,MAAM,GAA2B,IAAI,CAAC;IACtC,YAAY,GAAmC,IAAI,CAAC;IAE5D,YAAY,SAA2B;QACrC,IAAI,CAAC,MAAM,GAAG,SAAS,IAAI,IAAI,CAAC;IAClC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,SAAS;QACrB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;QAED,IAAI,CAAC;YACH,qBAAqB;YACrB,iEAAiE;YACjE,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAoB,CAAC;YAC1D,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC;YAC3B,OAAO,YAAY,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,eAAe,CAAC,QAAQ,CAAC,sBAAsB,EAAE;gBACrD,MAAM,EAAE,mCAAmC;aAC5C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,OAAuB;QACvC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YAEtC,QAAQ;YACR,IAAI,KAA8B,CAAC;YACnC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBAClB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC;gBAClD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAA0B,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;gBAClF,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,MAAM,eAAe,CAAC,QAAQ,CAAC,qBAAqB,EAAE;wBACpD,cAAc,EAAE,OAAO,CAAC,KAAK;qBAC9B,CAAC,CAAC;gBACL,CAAC;gBACD,KAAK,GAAG,KAAK,CAAC;YAChB,CAAC;iBAAM,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBAC7B,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;YAC5B,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC;gBAClD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACxB,MAAM,eAAe,CAAC,QAAQ,CAAC,qBAAqB,EAAE;wBACpD,MAAM,EAAE,qBAAqB;qBAC9B,CAAC,CAAC;gBACL,CAAC;gBACD,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACpB,CAAC;YAED,eAAe;YACf,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ;iBACjC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;iBAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;iBACnB,IAAI,CAAC,MAAM,CAAC,CAAC;YAEhB,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ;iBACnC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;iBAChC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;iBACnB,IAAI,CAAC,MAAM,CAAC,CAAC;YAEhB,MAAM,MAAM,GAAG,aAAa;gBAC1B,CAAC,CAAC,GAAG,aAAa,cAAc,WAAW,EAAE;gBAC7C,CAAC,CAAC,WAAW,CAAC;YAEhB,UAAU;YACV,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,wBAAwB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAEhE,UAAU;YACV,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,WAAW,CACtC,QAAQ,EACR,SAAS,EACT,OAAO,CAAC,iBAAiB,CAC1B,CAAC;YAEF,gBAAgB;YAChB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAErD,OAAO;gBACL,OAAO;gBACP,YAAY,EAAE,MAAM;aACrB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;gBACrC,MAAM,KAAK,CAAC;YACd,CAAC;YAED,WAAW;YACX,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBAChE,MAAM,eAAe,CAAC,QAAQ,CAAC,SAAS,EAAE;oBACxC,aAAa,EAAE,KAAK,CAAC,OAAO;iBAC7B,CAAC,CAAC;YACL,CAAC;YAED,UAAU;YACV,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC7D,MAAM,eAAe,CAAC,QAAQ,CAAC,uBAAuB,EAAE;oBACtD,aAAa,EAAE,KAAK,CAAC,OAAO;iBAC7B,CAAC,CAAC;YACL,CAAC;YAED,UAAU;YACV,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC7D,MAAM,eAAe,CAAC,QAAQ,CAAC,cAAc,EAAE;oBAC7C,aAAa,EAAE,KAAK,CAAC,OAAO;iBAC7B,CAAC,CAAC;YACL,CAAC;YAED,MAAM,eAAe,CAAC,QAAQ,CAAC,sBAAsB,EAAE;gBACrD,aAAa,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aACtE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,eAAe,CAC3B,MAA6B;QAE7B,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACjC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC;YAElD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAA0B,EAAE,EAAE,CAAC,CAAC;gBACjD,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,OAAO,EAAE,EAAE,EAAE,6BAA6B;gBAC1C,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,cAAc,EAAE,CAAC,CAAC,cAAc;aACjC,CAAC,CAAC,CAAC;QACN,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;gBACrC,MAAM,KAAK,CAAC;YACd,CAAC;YACD,MAAM,eAAe,CAAC,QAAQ,CAAC,sBAAsB,EAAE;gBACrD,aAAa,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aACtE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,QAAuB;QACvC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,gBAAgB,CAAC;gBAC9C,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;aACxB,CAAC,CAAC;YAEH,eAAe;YACf,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS;gBACjC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAA0B,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,IAAI,QAAQ,CAAC,SAAU,CAAC;gBACxF,CAAC,CAAC,MAAM,CAAC;YAEX,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO,IAAI,CAAC;YACd,CAAC;YAED,mBAAmB;YACnB,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAA6B,EAAE,OAAgC,EAAE,EAAE,CACnG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAC9D,CAAC;YAEF,cAAc;YACd,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAA0B,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;YAE9F,OAAO;gBACL,EAAE,EAAE,QAAQ,CAAC,EAAE;gBACf,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,OAAO,EAAE,EAAE,EAAE,6BAA6B;gBAC1C,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,cAAc,EAAE,QAAQ,CAAC,cAAc;aACxC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;gBACrC,MAAM,KAAK,CAAC;YACd,CAAC;YACD,MAAM,eAAe,CAAC,QAAQ,CAAC,sBAAsB,EAAE;gBACrD,aAAa,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aACtE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC;YAClD,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,eAAe;QACb,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,EAAE;YACxB,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI;YAC5B,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM;YAChC,OAAO,EAAE,EAAE,EAAE,6BAA6B;YAC1C,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM;YAChC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,cAAc;SACjD,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/musubix-expert-delegation
|
|
3
|
+
* Test Helpers
|
|
4
|
+
*
|
|
5
|
+
* DES-TST-001
|
|
6
|
+
* Traces to: REQ-TST-001
|
|
7
|
+
*/
|
|
8
|
+
import type { Expert, ExpertType, DelegationContext, DelegationTask, DelegationResult, TraceLink } from '../types/index.js';
|
|
9
|
+
import { MockVSCodeLMProvider } from './mocks.js';
|
|
10
|
+
/**
|
|
11
|
+
* テスト用のエキスパートを作成
|
|
12
|
+
*/
|
|
13
|
+
export declare function createTestExpert(type: ExpertType, overrides?: Partial<Expert>): Expert;
|
|
14
|
+
/**
|
|
15
|
+
* テスト用のコンテキストを作成
|
|
16
|
+
*/
|
|
17
|
+
export declare function createTestContext(overrides?: Partial<DelegationContext>): DelegationContext;
|
|
18
|
+
/**
|
|
19
|
+
* テスト用のタスクを作成
|
|
20
|
+
*/
|
|
21
|
+
export declare function createTestTask(overrides?: Partial<DelegationTask>): DelegationTask;
|
|
22
|
+
/**
|
|
23
|
+
* テスト用のトレースリンクを作成
|
|
24
|
+
*/
|
|
25
|
+
export declare function createTestTraceLink(overrides?: Partial<TraceLink>): TraceLink;
|
|
26
|
+
/**
|
|
27
|
+
* テスト用の成功結果を作成
|
|
28
|
+
*/
|
|
29
|
+
export declare function createTestSuccessResult(expertType: ExpertType, content: string, overrides?: Partial<DelegationResult>): DelegationResult;
|
|
30
|
+
/**
|
|
31
|
+
* テスト用の失敗結果を作成
|
|
32
|
+
*/
|
|
33
|
+
export declare function createTestFailureResult(expertType: ExpertType, reason: string, overrides?: Partial<DelegationResult>): DelegationResult;
|
|
34
|
+
/**
|
|
35
|
+
* テスト用プロバイダーをセットアップ
|
|
36
|
+
*/
|
|
37
|
+
export declare function setupTestProvider(responses?: Record<string, string>): MockVSCodeLMProvider;
|
|
38
|
+
/**
|
|
39
|
+
* 非同期アサーション用ヘルパー
|
|
40
|
+
*/
|
|
41
|
+
export declare function expectAsync<T>(promise: Promise<T>, assertion: (result: T) => void): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* エラーを期待するヘルパー
|
|
44
|
+
*/
|
|
45
|
+
export declare function expectError(promise: Promise<unknown>, errorType?: new (...args: unknown[]) => Error): Promise<Error>;
|
|
46
|
+
/**
|
|
47
|
+
* 遅延ヘルパー
|
|
48
|
+
*/
|
|
49
|
+
export declare function delay(ms: number): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* 複数回実行ヘルパー
|
|
52
|
+
*/
|
|
53
|
+
export declare function repeatAsync<T>(fn: () => Promise<T>, times: number): Promise<T[]>;
|
|
54
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/test/helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,MAAM,EACN,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,SAAS,EACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAElD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,UAAU,EAChB,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAC1B,MAAM,CAWR;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,GACrC,iBAAiB,CAMnB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,SAAS,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAClC,cAAc,CAQhB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAC7B,SAAS,CAOX;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GACpC,gBAAgB,CAUlB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GACpC,gBAAgB,CAUlB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,oBAAoB,CAUtB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,SAAS,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,GAC7B,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EACzB,SAAS,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,KAAK,GAC5C,OAAO,CAAC,KAAK,CAAC,CAYhB;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,CAAC,EAAE,CAAC,CAMd"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/musubix-expert-delegation
|
|
3
|
+
* Test Helpers
|
|
4
|
+
*
|
|
5
|
+
* DES-TST-001
|
|
6
|
+
* Traces to: REQ-TST-001
|
|
7
|
+
*/
|
|
8
|
+
import { MockVSCodeLMProvider } from './mocks.js';
|
|
9
|
+
/**
|
|
10
|
+
* テスト用のエキスパートを作成
|
|
11
|
+
*/
|
|
12
|
+
export function createTestExpert(type, overrides) {
|
|
13
|
+
return {
|
|
14
|
+
type,
|
|
15
|
+
name: `Test ${type}`,
|
|
16
|
+
description: `Test expert for ${type}`,
|
|
17
|
+
systemPrompt: `You are a test ${type} expert.`,
|
|
18
|
+
triggers: [],
|
|
19
|
+
capabilities: [{ name: 'advisory', mode: 'advisory', description: 'Advisory mode' }],
|
|
20
|
+
ontologyClass: `test:${type}`,
|
|
21
|
+
...overrides,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* テスト用のコンテキストを作成
|
|
26
|
+
*/
|
|
27
|
+
export function createTestContext(overrides) {
|
|
28
|
+
return {
|
|
29
|
+
userMessage: 'Test message',
|
|
30
|
+
mode: 'advisory',
|
|
31
|
+
...overrides,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* テスト用のタスクを作成
|
|
36
|
+
*/
|
|
37
|
+
export function createTestTask(overrides) {
|
|
38
|
+
return {
|
|
39
|
+
id: `test-task-${Date.now()}`,
|
|
40
|
+
context: createTestContext(),
|
|
41
|
+
mode: 'advisory',
|
|
42
|
+
createdAt: new Date(),
|
|
43
|
+
...overrides,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* テスト用のトレースリンクを作成
|
|
48
|
+
*/
|
|
49
|
+
export function createTestTraceLink(overrides) {
|
|
50
|
+
return {
|
|
51
|
+
sourceId: 'REQ-TEST-001',
|
|
52
|
+
targetId: 'DES-TEST-001',
|
|
53
|
+
type: 'traces-to',
|
|
54
|
+
...overrides,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* テスト用の成功結果を作成
|
|
59
|
+
*/
|
|
60
|
+
export function createTestSuccessResult(expertType, content, overrides) {
|
|
61
|
+
return {
|
|
62
|
+
success: true,
|
|
63
|
+
expertType,
|
|
64
|
+
mode: 'advisory',
|
|
65
|
+
content,
|
|
66
|
+
confidence: 0.85,
|
|
67
|
+
metadata: {},
|
|
68
|
+
...overrides,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* テスト用の失敗結果を作成
|
|
73
|
+
*/
|
|
74
|
+
export function createTestFailureResult(expertType, reason, overrides) {
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
expertType,
|
|
78
|
+
mode: 'advisory',
|
|
79
|
+
content: reason,
|
|
80
|
+
confidence: 0,
|
|
81
|
+
metadata: { error: reason },
|
|
82
|
+
...overrides,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* テスト用プロバイダーをセットアップ
|
|
87
|
+
*/
|
|
88
|
+
export function setupTestProvider(responses) {
|
|
89
|
+
const provider = new MockVSCodeLMProvider();
|
|
90
|
+
if (responses) {
|
|
91
|
+
for (const [pattern, content] of Object.entries(responses)) {
|
|
92
|
+
provider.setResponse(pattern, { content, finishReason: 'stop' });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return provider;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 非同期アサーション用ヘルパー
|
|
99
|
+
*/
|
|
100
|
+
export async function expectAsync(promise, assertion) {
|
|
101
|
+
const result = await promise;
|
|
102
|
+
assertion(result);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* エラーを期待するヘルパー
|
|
106
|
+
*/
|
|
107
|
+
export async function expectError(promise, errorType) {
|
|
108
|
+
try {
|
|
109
|
+
await promise;
|
|
110
|
+
throw new Error('Expected promise to reject');
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
if (errorType && !(error instanceof errorType)) {
|
|
114
|
+
throw new Error(`Expected error of type ${errorType.name}, got ${error.constructor.name}`);
|
|
115
|
+
}
|
|
116
|
+
return error;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* 遅延ヘルパー
|
|
121
|
+
*/
|
|
122
|
+
export function delay(ms) {
|
|
123
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* 複数回実行ヘルパー
|
|
127
|
+
*/
|
|
128
|
+
export async function repeatAsync(fn, times) {
|
|
129
|
+
const results = [];
|
|
130
|
+
for (let i = 0; i < times; i++) {
|
|
131
|
+
results.push(await fn());
|
|
132
|
+
}
|
|
133
|
+
return results;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/test/helpers.ts"],"names":[],"mappings":"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"}
|