@gitwand/core 2.4.1 → 2.5.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/dist/__tests__/corpus.d.ts.map +1 -1
- package/dist/__tests__/corpus.js +262 -0
- package/dist/__tests__/corpus.js.map +1 -1
- package/dist/__tests__/patterns/llm-proposed.test.d.ts +10 -0
- package/dist/__tests__/patterns/llm-proposed.test.d.ts.map +1 -0
- package/dist/__tests__/patterns/llm-proposed.test.js +306 -0
- package/dist/__tests__/patterns/llm-proposed.test.js.map +1 -0
- package/dist/classifier.d.ts.map +1 -1
- package/dist/classifier.js +3 -0
- package/dist/classifier.js.map +1 -1
- package/dist/config.d.ts +29 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +26 -1
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/patterns/llm-proposed.d.ts +8 -0
- package/dist/patterns/llm-proposed.d.ts.map +1 -0
- package/dist/patterns/llm-proposed.js +66 -0
- package/dist/patterns/llm-proposed.js.map +1 -0
- package/dist/resolver/index.d.ts.map +1 -1
- package/dist/resolver/index.js +19 -2
- package/dist/resolver/index.js.map +1 -1
- package/dist/resolver/llm-pipeline.d.ts +33 -0
- package/dist/resolver/llm-pipeline.d.ts.map +1 -0
- package/dist/resolver/llm-pipeline.js +218 -0
- package/dist/resolver/llm-pipeline.js.map +1 -0
- package/dist/resolver/policy.d.ts.map +1 -1
- package/dist/resolver/policy.js +2 -0
- package/dist/resolver/policy.js.map +1 -1
- package/dist/resolvers/llm-fallback.d.ts +41 -0
- package/dist/resolvers/llm-fallback.d.ts.map +1 -0
- package/dist/resolvers/llm-fallback.js +231 -0
- package/dist/resolvers/llm-fallback.js.map +1 -0
- package/dist/types.d.ts +123 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/resolver/index.js
CHANGED
|
@@ -22,6 +22,8 @@ import { isGeneratedFile, reclassifyIfGenerated } from "./generated-detection.js
|
|
|
22
22
|
import { CONFIDENCE_ORDER, DEFAULT_OPTIONS, applyFileFrequencyPenalty, computeEffectiveMinConfidence, computeEffectivePolicy, } from "./policy.js";
|
|
23
23
|
import { dispatchFormatAware } from "./format-dispatch.js";
|
|
24
24
|
import { assembleResolution } from "./assemble.js";
|
|
25
|
+
import { setLlmFallbackEnabled } from "../patterns/llm-proposed.js";
|
|
26
|
+
import { runLlmFallbackPhase } from "./llm-pipeline.js";
|
|
25
27
|
/**
|
|
26
28
|
* Résout automatiquement un hunk de conflit.
|
|
27
29
|
*
|
|
@@ -200,10 +202,25 @@ export async function resolveAsync(conflictedContent, filePath, userOptions = {}
|
|
|
200
202
|
}
|
|
201
203
|
}
|
|
202
204
|
// ─── 2. Résolution hunk-par-hunk (synchrone) ─────────────────────────────
|
|
205
|
+
// Si le LLM fallback est activé, on positionne le flag avant la classification
|
|
206
|
+
// pour que `llmProposed.detect()` retourne true sur les hunks complex.
|
|
207
|
+
// Le flag est réinitialisé immédiatement après `resolve()` — il ne doit pas
|
|
208
|
+
// persister entre appels (module-level state, potentiellement partagé).
|
|
209
|
+
const llmEnabled = !!(options.llmFallback?.enabled && options.llmFallback?.endpoint);
|
|
210
|
+
if (llmEnabled)
|
|
211
|
+
setLlmFallbackEnabled(true);
|
|
203
212
|
const result = resolve(conflictedContent, filePath, userOptions);
|
|
204
|
-
|
|
213
|
+
if (llmEnabled)
|
|
214
|
+
setLlmFallbackEnabled(false);
|
|
215
|
+
if (options.verbose && llmEnabled && result.resolutions.some((r) => !r.autoResolved && r.hunk.type === "llm_proposed")) {
|
|
216
|
+
console.error("[GitWand] LLM fallback activé — phase 5 en attente des hunks llm_proposed non résolus.");
|
|
217
|
+
}
|
|
218
|
+
// Rien à valider si la résolution n'est pas complète et pas de LLM fallback
|
|
205
219
|
if (result.mergedContent === null) {
|
|
206
|
-
|
|
220
|
+
if (!llmEnabled)
|
|
221
|
+
return result;
|
|
222
|
+
// Phase 5 — LLM fallback pour les hunks llm_proposed non résolus
|
|
223
|
+
return runLlmFallbackPhase(conflictedContent, result, filePath, options, structuralOpts);
|
|
207
224
|
}
|
|
208
225
|
// ─── 3. v2.4 — Validation parse-tree ─────────────────────────────────────
|
|
209
226
|
// Skipped when validationLevel === "off" (performance mode).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resolver/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAYH,OAAO,EACL,yBAAyB,EACzB,oBAAoB,EACpB,oBAAoB,GAErB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAC1F,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAClF,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,yBAAyB,EACzB,6BAA6B,EAC7B,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resolver/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.5 — LLM fallback pipeline (phase 5 de resolveAsync).
|
|
3
|
+
*
|
|
4
|
+
* Après la résolution hunk-par-hunk et la validation parse-tree, cette phase
|
|
5
|
+
* tente de résoudre les hunks `complex` restants via le fallback LLM.
|
|
6
|
+
*
|
|
7
|
+
* ## Intégration dans resolveAsync
|
|
8
|
+
*
|
|
9
|
+
* La fonction `runLlmFallbackPhase` est appelée par `resolveAsync()` uniquement si :
|
|
10
|
+
* - `options.llmFallback.enabled === true`
|
|
11
|
+
* - `options.llmFallback.endpoint` est injecté
|
|
12
|
+
* - Il reste des hunks `complex` non résolus dans `result.resolutions`
|
|
13
|
+
*
|
|
14
|
+
* ## Reconstruction du mergedContent
|
|
15
|
+
*
|
|
16
|
+
* Les `HunkResolution` sont mises à jour en place. Le `mergedContent` est
|
|
17
|
+
* reconstruit à partir des segments parsés de `conflictedContent` en appliquant
|
|
18
|
+
* les nouvelles résolutions.
|
|
19
|
+
*/
|
|
20
|
+
import type { GitWandOptions, MergeResult } from "../types.js";
|
|
21
|
+
import type { StructuralLoaderOptions } from "../structural/index.js";
|
|
22
|
+
/**
|
|
23
|
+
* Applique le fallback LLM sur les hunks `complex` non résolus.
|
|
24
|
+
*
|
|
25
|
+
* Retourne le `MergeResult` mis à jour avec :
|
|
26
|
+
* - Les `HunkResolution` patchées (llm_proposed ou toujours complex)
|
|
27
|
+
* - La `DecisionTrace` enrichie avec `llmTrace` pour chaque résolution LLM
|
|
28
|
+
* - Le `mergedContent` reconstruit
|
|
29
|
+
* - Les stats mises à jour
|
|
30
|
+
* - La validation post-merge re-exécutée si toutes les résolutions passent
|
|
31
|
+
*/
|
|
32
|
+
export declare function runLlmFallbackPhase(conflictedContent: string, result: MergeResult, filePath: string, options: Required<GitWandOptions>, structuralOpts?: StructuralLoaderOptions): Promise<MergeResult>;
|
|
33
|
+
//# sourceMappingURL=llm-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-pipeline.d.ts","sourceRoot":"","sources":["../../src/resolver/llm-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAEV,cAAc,EAGd,WAAW,EAEZ,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AA0EtE;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACvC,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,QAAQ,CAAC,cAAc,CAAC,EACjC,cAAc,GAAE,uBAA4B,GAC3C,OAAO,CAAC,WAAW,CAAC,CAmJtB"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.5 — LLM fallback pipeline (phase 5 de resolveAsync).
|
|
3
|
+
*
|
|
4
|
+
* Après la résolution hunk-par-hunk et la validation parse-tree, cette phase
|
|
5
|
+
* tente de résoudre les hunks `complex` restants via le fallback LLM.
|
|
6
|
+
*
|
|
7
|
+
* ## Intégration dans resolveAsync
|
|
8
|
+
*
|
|
9
|
+
* La fonction `runLlmFallbackPhase` est appelée par `resolveAsync()` uniquement si :
|
|
10
|
+
* - `options.llmFallback.enabled === true`
|
|
11
|
+
* - `options.llmFallback.endpoint` est injecté
|
|
12
|
+
* - Il reste des hunks `complex` non résolus dans `result.resolutions`
|
|
13
|
+
*
|
|
14
|
+
* ## Reconstruction du mergedContent
|
|
15
|
+
*
|
|
16
|
+
* Les `HunkResolution` sont mises à jour en place. Le `mergedContent` est
|
|
17
|
+
* reconstruit à partir des segments parsés de `conflictedContent` en appliquant
|
|
18
|
+
* les nouvelles résolutions.
|
|
19
|
+
*/
|
|
20
|
+
import { parseConflictMarkers } from "../parser.js";
|
|
21
|
+
import { tryLlmFallbackResolve } from "../resolvers/llm-fallback.js";
|
|
22
|
+
import { checkParseTreeValid, applyPostMergeRiskPenalty } from "./validate-parse-tree.js";
|
|
23
|
+
import { validateMergedContent } from "./validation.js";
|
|
24
|
+
// ─── Helpers ──────────────────────────────────────────────
|
|
25
|
+
/**
|
|
26
|
+
* Extrait les lignes de contexte autour d'un hunk dans le contenu original.
|
|
27
|
+
* Utilisé pour construire le prompt LLM.
|
|
28
|
+
*
|
|
29
|
+
* @param conflictedContent - Contenu original avec marqueurs de conflit
|
|
30
|
+
* @param hunk - Hunk de conflit
|
|
31
|
+
* @param contextLines - Nombre de lignes de contexte de chaque côté
|
|
32
|
+
*/
|
|
33
|
+
function extractHunkContext(conflictedContent, hunk, contextLines) {
|
|
34
|
+
const allLines = conflictedContent.split("\n");
|
|
35
|
+
const startIdx = Math.max(0, hunk.startLine - 1 - contextLines);
|
|
36
|
+
const endIdx = Math.min(allLines.length, hunk.startLine + contextLines);
|
|
37
|
+
return allLines.slice(startIdx, endIdx).join("\n");
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Reconstruit le `mergedContent` à partir du contenu original et des résolutions.
|
|
41
|
+
* Remplace chaque hunk par ses lignes résolues, ou restore les marqueurs de conflit.
|
|
42
|
+
*
|
|
43
|
+
* Retourne :
|
|
44
|
+
* - La string fusionnée si toutes les résolutions sont résolues (`allResolved = true`)
|
|
45
|
+
* - `null` si des conflits subsistent
|
|
46
|
+
*/
|
|
47
|
+
function reconstructMergedContent(conflictedContent, resolutions) {
|
|
48
|
+
const { segments } = parseConflictMarkers(conflictedContent);
|
|
49
|
+
const outputLines = [];
|
|
50
|
+
let hunkIndex = 0;
|
|
51
|
+
let allResolved = true;
|
|
52
|
+
for (const segment of segments) {
|
|
53
|
+
if (segment.type === "text") {
|
|
54
|
+
outputLines.push(...segment.lines);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const resolution = resolutions[hunkIndex++];
|
|
58
|
+
if (resolution?.autoResolved && resolution.resolvedLines !== null) {
|
|
59
|
+
outputLines.push(...resolution.resolvedLines);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
// Restore conflict markers
|
|
63
|
+
const h = resolution?.hunk;
|
|
64
|
+
if (h) {
|
|
65
|
+
outputLines.push(`<<<<<<< ours`);
|
|
66
|
+
outputLines.push(...h.oursLines);
|
|
67
|
+
if (h.baseLines.length > 0) {
|
|
68
|
+
outputLines.push(`||||||| base`);
|
|
69
|
+
outputLines.push(...h.baseLines);
|
|
70
|
+
}
|
|
71
|
+
outputLines.push(`=======`);
|
|
72
|
+
outputLines.push(...h.theirsLines);
|
|
73
|
+
outputLines.push(`>>>>>>> theirs`);
|
|
74
|
+
}
|
|
75
|
+
allResolved = false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return { content: outputLines.join("\n"), allResolved };
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Applique le fallback LLM sur les hunks `complex` non résolus.
|
|
82
|
+
*
|
|
83
|
+
* Retourne le `MergeResult` mis à jour avec :
|
|
84
|
+
* - Les `HunkResolution` patchées (llm_proposed ou toujours complex)
|
|
85
|
+
* - La `DecisionTrace` enrichie avec `llmTrace` pour chaque résolution LLM
|
|
86
|
+
* - Le `mergedContent` reconstruit
|
|
87
|
+
* - Les stats mises à jour
|
|
88
|
+
* - La validation post-merge re-exécutée si toutes les résolutions passent
|
|
89
|
+
*/
|
|
90
|
+
export async function runLlmFallbackPhase(conflictedContent, result, filePath, options, structuralOpts = {}) {
|
|
91
|
+
const llmConfig = options.llmFallback ?? { enabled: false };
|
|
92
|
+
if (!llmConfig.enabled || !llmConfig.endpoint) {
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
const contextLines = llmConfig.contextLines ?? 50;
|
|
96
|
+
// Identifier les hunks llm_proposed non résolus.
|
|
97
|
+
// Quand setLlmFallbackEnabled(true) était actif pendant resolve(), les hunks
|
|
98
|
+
// qui auraient été "complex" ont été classifiés "llm_proposed". Leur score
|
|
99
|
+
// (dataRisk: 60) étant trop bas pour une auto-résolution, ils restent non résolus.
|
|
100
|
+
const complexUnresolved = result.resolutions
|
|
101
|
+
.map((r, idx) => ({ r, idx }))
|
|
102
|
+
.filter(({ r }) => !r.autoResolved && r.hunk.type === "llm_proposed");
|
|
103
|
+
if (complexUnresolved.length === 0) {
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
// Cloner les résolutions pour mutation
|
|
107
|
+
const updatedResolutions = result.resolutions.map((r) => ({ ...r }));
|
|
108
|
+
const updatedHunks = result.hunks.map((h) => ({
|
|
109
|
+
...h,
|
|
110
|
+
trace: { ...h.trace, steps: [...h.trace.steps] },
|
|
111
|
+
confidence: {
|
|
112
|
+
...h.confidence,
|
|
113
|
+
dimensions: { ...h.confidence.dimensions },
|
|
114
|
+
},
|
|
115
|
+
}));
|
|
116
|
+
// Traiter chaque hunk complex en séquence
|
|
117
|
+
// (séquentiel pour respecter l'ordre et éviter les race conditions d'endpoint)
|
|
118
|
+
for (const { r, idx } of complexUnresolved) {
|
|
119
|
+
const hunk = r.hunk;
|
|
120
|
+
const fileContext = extractHunkContext(conflictedContent, hunk, contextLines);
|
|
121
|
+
const llmResult = await tryLlmFallbackResolve(hunk, filePath, fileContext, llmConfig);
|
|
122
|
+
if (llmResult.lines !== null) {
|
|
123
|
+
// Résolution acceptée — mettre à jour le hunk et la résolution
|
|
124
|
+
const updatedHunk = {
|
|
125
|
+
...updatedHunks[idx],
|
|
126
|
+
type: "llm_proposed",
|
|
127
|
+
trace: {
|
|
128
|
+
...updatedHunks[idx].trace,
|
|
129
|
+
selected: "llm_proposed",
|
|
130
|
+
summary: `LLM fallback (${llmConfig.model ?? "claude-sonnet-4-6"}) — ${llmResult.reason}`,
|
|
131
|
+
llmTrace: llmResult.llmTrace,
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
updatedHunks[idx] = updatedHunk;
|
|
135
|
+
updatedResolutions[idx] = {
|
|
136
|
+
hunk: updatedHunk,
|
|
137
|
+
resolvedLines: llmResult.lines,
|
|
138
|
+
autoResolved: true,
|
|
139
|
+
resolutionReason: llmResult.reason,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
// Résolution refusée — enrichir la trace avec llmTrace pour l'audit
|
|
144
|
+
const updatedHunk = {
|
|
145
|
+
...updatedHunks[idx],
|
|
146
|
+
trace: {
|
|
147
|
+
...updatedHunks[idx].trace,
|
|
148
|
+
summary: `${updatedHunks[idx].trace.summary} | LLM refusé: ${llmResult.reason}`,
|
|
149
|
+
llmTrace: llmResult.llmTrace,
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
updatedHunks[idx] = updatedHunk;
|
|
153
|
+
updatedResolutions[idx] = {
|
|
154
|
+
...updatedResolutions[idx],
|
|
155
|
+
hunk: updatedHunk,
|
|
156
|
+
resolutionReason: `${updatedResolutions[idx].resolutionReason} | LLM refusé: ${llmResult.reason}`,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Reconstruire le mergedContent depuis les résolutions mises à jour
|
|
161
|
+
const { content: newMergedContent, allResolved } = reconstructMergedContent(conflictedContent, updatedResolutions);
|
|
162
|
+
// Calculer les nouvelles stats
|
|
163
|
+
const autoResolvedCount = updatedResolutions.filter((r) => r.autoResolved).length;
|
|
164
|
+
const updatedStats = {
|
|
165
|
+
...result.stats,
|
|
166
|
+
autoResolved: autoResolvedCount,
|
|
167
|
+
remaining: updatedResolutions.length - autoResolvedCount,
|
|
168
|
+
byType: {},
|
|
169
|
+
};
|
|
170
|
+
for (const hunk of updatedHunks) {
|
|
171
|
+
updatedStats.byType[hunk.type] = (updatedStats.byType[hunk.type] || 0) + 1;
|
|
172
|
+
}
|
|
173
|
+
if (!allResolved) {
|
|
174
|
+
// Des conflits subsistent — pas de mergedContent
|
|
175
|
+
return {
|
|
176
|
+
...result,
|
|
177
|
+
hunks: updatedHunks,
|
|
178
|
+
resolutions: updatedResolutions,
|
|
179
|
+
stats: updatedStats,
|
|
180
|
+
mergedContent: null,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
// Tout est résolu — re-valider le mergedContent complet
|
|
184
|
+
const validation = validateMergedContent(newMergedContent, filePath);
|
|
185
|
+
// Re-vérification parse-tree sur le contenu post-LLM
|
|
186
|
+
if (options.validationLevel !== "off") {
|
|
187
|
+
const parseTreeValid = await checkParseTreeValid(newMergedContent, filePath, structuralOpts);
|
|
188
|
+
if (parseTreeValid === false) {
|
|
189
|
+
// Parse-tree invalide après fallback LLM → rétraction de tout
|
|
190
|
+
const retractedResolutions = updatedResolutions.map((r) => r.autoResolved ? applyPostMergeRiskPenalty(r) : r);
|
|
191
|
+
return {
|
|
192
|
+
...result,
|
|
193
|
+
hunks: updatedHunks,
|
|
194
|
+
resolutions: retractedResolutions,
|
|
195
|
+
stats: { ...updatedStats, autoResolved: 0, remaining: updatedStats.totalConflicts },
|
|
196
|
+
mergedContent: null,
|
|
197
|
+
validation: { ...validation, isValid: false, parseTreeValid: false, externalValidation: null },
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
...result,
|
|
202
|
+
hunks: updatedHunks,
|
|
203
|
+
resolutions: updatedResolutions,
|
|
204
|
+
stats: updatedStats,
|
|
205
|
+
mergedContent: newMergedContent,
|
|
206
|
+
validation: { ...validation, parseTreeValid, externalValidation: null },
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
...result,
|
|
211
|
+
hunks: updatedHunks,
|
|
212
|
+
resolutions: updatedResolutions,
|
|
213
|
+
stats: updatedStats,
|
|
214
|
+
mergedContent: newMergedContent,
|
|
215
|
+
validation: { ...validation, parseTreeValid: null, externalValidation: null },
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=llm-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-pipeline.js","sourceRoot":"","sources":["../../src/resolver/llm-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/resolver/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,cAAc,CAAC;AAEtB,0BAA0B;AAC1B,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,cAAc,
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/resolver/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,cAAc,CAAC;AAEtB,0BAA0B;AAC1B,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,cAAc,CAgBpD,CAAC;AAEF,2CAA2C;AAC3C,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAKvD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,QAAQ,CAAC,cAAc,CAAC,GAChC;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,GAAG,EAAE,YAAY,CAAA;CAAE,CAO5C;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,YAAY,EACvB,OAAO,EAAE,QAAQ,CAAC,cAAc,CAAC,GAChC,UAAU,CAIZ;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,YAAY,EAClB,iBAAiB,EAAE,MAAM,GACxB,YAAY,CAiCd"}
|
package/dist/resolver/policy.js
CHANGED
|
@@ -29,6 +29,8 @@ export const DEFAULT_OPTIONS = {
|
|
|
29
29
|
// v2.4 — validation post-merge
|
|
30
30
|
validationLevel: "balanced",
|
|
31
31
|
validationTools: ["tsc"],
|
|
32
|
+
// v2.5 — LLM fallback (désactivé par défaut)
|
|
33
|
+
llmFallback: { enabled: false },
|
|
32
34
|
};
|
|
33
35
|
/** Ordre de confiance pour comparaison. */
|
|
34
36
|
export const CONFIDENCE_ORDER = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/resolver/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,cAAc,GAGf,MAAM,cAAc,CAAC;AAEtB,0BAA0B;AAC1B,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,iBAAiB,EAAE,IAAI;IACvB,qBAAqB,EAAE,IAAI;IAC3B,aAAa,EAAE,MAAM;IACrB,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,KAAK;IAClB,MAAM,EAAE,cAAc;IACtB,gBAAgB,EAAE,EAAE;IACpB,cAAc,EAAE,EAAE;IAClB,6CAA6C;IAC7C,qBAAqB,EAAE,KAAK;IAC5B,+BAA+B;IAC/B,eAAe,EAAE,UAAU;IAC3B,eAAe,EAAE,CAAC,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/resolver/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,cAAc,GAGf,MAAM,cAAc,CAAC;AAEtB,0BAA0B;AAC1B,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,iBAAiB,EAAE,IAAI;IACvB,qBAAqB,EAAE,IAAI;IAC3B,aAAa,EAAE,MAAM;IACrB,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,KAAK;IAClB,MAAM,EAAE,cAAc;IACtB,gBAAgB,EAAE,EAAE;IACpB,cAAc,EAAE,EAAE;IAClB,6CAA6C;IAC7C,qBAAqB,EAAE,KAAK;IAC5B,+BAA+B;IAC/B,eAAe,EAAE,UAAU;IAC3B,eAAe,EAAE,CAAC,KAAK,CAAC;IACxB,6CAA6C;IAC7C,WAAW,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;CAChC,CAAC;AAEF,2CAA2C;AAC3C,MAAM,CAAC,MAAM,gBAAgB,GAA+B;IAC1D,OAAO,EAAE,CAAC;IACV,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,CAAC;IACT,GAAG,EAAE,CAAC;CACP,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAAgB,EAChB,OAAiC;IAEjC,MAAM,MAAM,GAAG,sBAAsB,CACnC,QAAQ,EACR,OAAO,CAAC,MAAM,EACd,OAAO,CAAC,gBAAgB,CACzB,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;AACjD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,6BAA6B,CAC3C,SAAuB,EACvB,OAAiC;IAEjC,OAAO,gBAAgB,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,gBAAgB,CAAC,OAAO,CAAC,aAAa,CAAC;QACxF,CAAC,CAAC,SAAS,CAAC,aAAa;QACzB,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;AAC5B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,yBAAyB,CACvC,IAAkB,EAClB,iBAAyB;IAEzB,IAAI,iBAAiB,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,iBAAiB,GAAG,EAAE,CAAC,CAAC;IACjD,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;IACrC,MAAM,GAAG,GACP,CAAC,CAAC,kBAAkB;UAClB,CAAC,CAAC,QAAQ,GAAU,IAAI;UACxB,CAAC,CAAC,WAAW,GAAO,IAAI;UACxB,EAAE,GAAkB,IAAI;UACxB,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7D,MAAM,QAAQ,GACZ,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS;QAC1B,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM;YACzB,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ;gBAC3B,CAAC,CAAC,KAAK,CAAC;IAEV,OAAO;QACL,GAAG,IAAI;QACP,UAAU,EAAE;YACV,GAAG,IAAI,CAAC,UAAU;YAClB,KAAK,EAAE,QAAQ;YACf,KAAK,EAAE,QAAQ;YACf,UAAU,EAAE,EAAE,GAAG,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE;YACvC,SAAS,EAAE;gBACT,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS;gBAC5B,iBAAiB,iBAAiB,QAAQ,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,YAAY,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,+BAA+B,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO;aACnL;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.5 — LLM fallback resolver.
|
|
3
|
+
*
|
|
4
|
+
* Sérialise un hunk de conflit + son contexte, envoie le prompt à l'endpoint
|
|
5
|
+
* LLM injecté par le consommateur, valide le résultat proposé, et retourne
|
|
6
|
+
* la résolution avec une trace d'audit complète.
|
|
7
|
+
*
|
|
8
|
+
* ### Contrainte browser
|
|
9
|
+
* Ce module n'utilise aucun module Node.js natif (`fs`, `crypto`, `child_process`…).
|
|
10
|
+
* Le hash SHA-256 est calculé via l'API Web Crypto (`globalThis.crypto.subtle`),
|
|
11
|
+
* disponible en browser, Node.js ≥ 18, et Tauri.
|
|
12
|
+
*/
|
|
13
|
+
import type { ConflictHunk, LlmFallbackConfig, LlmTrace } from "../types.js";
|
|
14
|
+
/** Résultat de la tentative de résolution LLM d'un hunk. */
|
|
15
|
+
export interface LlmResolveResult {
|
|
16
|
+
/** Lignes résolues (null = résolution refusée) */
|
|
17
|
+
lines: string[] | null;
|
|
18
|
+
/** Raison lisible de l'acceptation ou du refus */
|
|
19
|
+
reason: string;
|
|
20
|
+
/** Trace d'audit complète (toujours présente, même en cas de refus) */
|
|
21
|
+
llmTrace: LlmTrace;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Tente de résoudre un hunk de conflit via le fallback LLM.
|
|
25
|
+
*
|
|
26
|
+
* Pipeline :
|
|
27
|
+
* 1. Construit le prompt (sérialisation hunk + contexte + trace partielle)
|
|
28
|
+
* 2. Calcule le hash SHA-256 du prompt (audit de reproductibilité)
|
|
29
|
+
* 3. Appelle `config.endpoint.call(prompt)` (fourni par le consommateur)
|
|
30
|
+
* 4. Parse la réponse (extrait les lignes résolues)
|
|
31
|
+
* 5. Valide le résultat (`validateMergedContent`)
|
|
32
|
+
* 6. Accepte si `score ≥ minPostMergeScore`, refuse sinon
|
|
33
|
+
* 7. Retourne `LlmResolveResult` avec la trace complète
|
|
34
|
+
*
|
|
35
|
+
* @param hunk - Hunk de conflit à résoudre
|
|
36
|
+
* @param filePath - Chemin du fichier (pour validation post-merge)
|
|
37
|
+
* @param fileContext - ±N lignes autour du hunk (fournies par l'appelant)
|
|
38
|
+
* @param config - Configuration LLM fallback (avec endpoint injecté)
|
|
39
|
+
*/
|
|
40
|
+
export declare function tryLlmFallbackResolve(hunk: ConflictHunk, filePath: string, fileContext: string, config: LlmFallbackConfig): Promise<LlmResolveResult>;
|
|
41
|
+
//# sourceMappingURL=llm-fallback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-fallback.d.ts","sourceRoot":"","sources":["../../src/resolvers/llm-fallback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAK7E,4DAA4D;AAC5D,MAAM,WAAW,gBAAgB;IAC/B,kDAAkD;IAClD,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACvB,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,QAAQ,EAAE,QAAQ,CAAC;CACpB;AA+HD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,gBAAgB,CAAC,CAsG3B"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.5 — LLM fallback resolver.
|
|
3
|
+
*
|
|
4
|
+
* Sérialise un hunk de conflit + son contexte, envoie le prompt à l'endpoint
|
|
5
|
+
* LLM injecté par le consommateur, valide le résultat proposé, et retourne
|
|
6
|
+
* la résolution avec une trace d'audit complète.
|
|
7
|
+
*
|
|
8
|
+
* ### Contrainte browser
|
|
9
|
+
* Ce module n'utilise aucun module Node.js natif (`fs`, `crypto`, `child_process`…).
|
|
10
|
+
* Le hash SHA-256 est calculé via l'API Web Crypto (`globalThis.crypto.subtle`),
|
|
11
|
+
* disponible en browser, Node.js ≥ 18, et Tauri.
|
|
12
|
+
*/
|
|
13
|
+
import { validateMergedContent } from "../resolver/validation.js";
|
|
14
|
+
// ─── Helpers internes ──────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* Calcule le hash SHA-256 d'une chaîne en hexadécimal.
|
|
17
|
+
* Utilise Web Crypto (browser + Node.js ≥ 18 + Tauri) — pas de `node:crypto`.
|
|
18
|
+
*/
|
|
19
|
+
async function sha256Hex(text) {
|
|
20
|
+
const encoder = new TextEncoder();
|
|
21
|
+
const data = encoder.encode(text);
|
|
22
|
+
const hashBuffer = await globalThis.crypto.subtle.digest("SHA-256", data);
|
|
23
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
24
|
+
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Calcule un score de validation (0–100) à partir d'un `ValidationResult`.
|
|
28
|
+
*
|
|
29
|
+
* | Condition | Score |
|
|
30
|
+
* |----------------------------------------|-------|
|
|
31
|
+
* | Marqueurs résiduels détectés | 0 |
|
|
32
|
+
* | Erreur de syntaxe structurée | 0 |
|
|
33
|
+
* | Parse-tree invalide | 0 |
|
|
34
|
+
* | Validation externe échouée (tsc/eslint)| 50 |
|
|
35
|
+
* | Tout OK | 100 |
|
|
36
|
+
*/
|
|
37
|
+
function computeValidationScore(validation, parseTreeValid, externalValidationPassed) {
|
|
38
|
+
if (validation.hasResidualMarkers)
|
|
39
|
+
return 0;
|
|
40
|
+
if (validation.syntaxError !== null)
|
|
41
|
+
return 0;
|
|
42
|
+
if (parseTreeValid === false)
|
|
43
|
+
return 0;
|
|
44
|
+
if (externalValidationPassed === false)
|
|
45
|
+
return 50;
|
|
46
|
+
return 100;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Construit le prompt structuré envoyé au LLM.
|
|
50
|
+
*
|
|
51
|
+
* Format :
|
|
52
|
+
* - Contexte autour du hunk (±contextLines lignes)
|
|
53
|
+
* - Sérialisation complète du hunk (base/ours/theirs)
|
|
54
|
+
* - Résumé de la DecisionTrace partielle
|
|
55
|
+
* - Instructions explicites (output uniquement en code block)
|
|
56
|
+
*/
|
|
57
|
+
function buildPrompt(hunk, filePath, fileContext, config) {
|
|
58
|
+
const contextLines = config.contextLines ?? 50;
|
|
59
|
+
const base = hunk.baseLines.join("\n");
|
|
60
|
+
const ours = hunk.oursLines.join("\n");
|
|
61
|
+
const theirs = hunk.theirsLines.join("\n");
|
|
62
|
+
const traceSteps = hunk.trace.steps
|
|
63
|
+
.map((s) => ` [${s.passed ? "✓" : "✗"}] ${s.type}: ${s.reason}`)
|
|
64
|
+
.join("\n");
|
|
65
|
+
const hasBase = hunk.baseLines.length > 0;
|
|
66
|
+
const conflictBlock = hasBase
|
|
67
|
+
? `<<<<<<< ours\n${ours}\n||||||| base\n${base}\n=======\n${theirs}\n>>>>>>> theirs`
|
|
68
|
+
: `<<<<<<< ours\n${ours}\n=======\n${theirs}\n>>>>>>> theirs`;
|
|
69
|
+
return `You are an expert Git merge conflict resolver. Your task is to resolve the conflict below.
|
|
70
|
+
|
|
71
|
+
## File: ${filePath}
|
|
72
|
+
|
|
73
|
+
## Context (±${contextLines} lines around the conflict):
|
|
74
|
+
\`\`\`
|
|
75
|
+
${fileContext}
|
|
76
|
+
\`\`\`
|
|
77
|
+
|
|
78
|
+
## Conflict hunk to resolve (line ${hunk.startLine}):
|
|
79
|
+
\`\`\`
|
|
80
|
+
${conflictBlock}
|
|
81
|
+
\`\`\`
|
|
82
|
+
|
|
83
|
+
## Analysis (partial decision trace):
|
|
84
|
+
${traceSteps || " No patterns matched — conflict is complex."}
|
|
85
|
+
|
|
86
|
+
## Instructions:
|
|
87
|
+
- Output ONLY the resolved lines inside a single fenced code block (\`\`\`)
|
|
88
|
+
- Do NOT include conflict markers (<<<<<<<, =======, >>>>>>>, |||||||)
|
|
89
|
+
- Preserve indentation, coding style, and surrounding context
|
|
90
|
+
- If you cannot resolve this conflict safely, output exactly: CANNOT_RESOLVE
|
|
91
|
+
- Do not explain your reasoning — only output the code block or CANNOT_RESOLVE
|
|
92
|
+
|
|
93
|
+
## Resolution:`.trim();
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Extrait les lignes résolues depuis la réponse brute du LLM.
|
|
97
|
+
*
|
|
98
|
+
* Accepte :
|
|
99
|
+
* - Une réponse contenant un bloc de code fencé (\`\`\`...\`\`\`)
|
|
100
|
+
* - Une réponse contenant "CANNOT_RESOLVE"
|
|
101
|
+
* - Une réponse brute (fallback : toutes les lignes sauf la première si vide)
|
|
102
|
+
*
|
|
103
|
+
* @returns Les lignes résolues, ou `null` si le LLM a refusé ou si la réponse est vide.
|
|
104
|
+
*/
|
|
105
|
+
function parseResponse(raw) {
|
|
106
|
+
const trimmed = raw.trim();
|
|
107
|
+
if (!trimmed || trimmed === "CANNOT_RESOLVE" || trimmed.includes("CANNOT_RESOLVE")) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
// Extraire le contenu du premier bloc fencé
|
|
111
|
+
const fenceMatch = trimmed.match(/```(?:\w+)?\n?([\s\S]*?)```/);
|
|
112
|
+
if (fenceMatch) {
|
|
113
|
+
const content = fenceMatch[1];
|
|
114
|
+
// Retirer le trailing newline du bloc mais garder les lignes internes
|
|
115
|
+
return content.replace(/\n$/, "").split("\n");
|
|
116
|
+
}
|
|
117
|
+
// Fallback : retourner les lignes brutes (sans la première ligne si elle est vide)
|
|
118
|
+
const lines = trimmed.split("\n");
|
|
119
|
+
return lines.length > 0 ? lines : null;
|
|
120
|
+
}
|
|
121
|
+
// ─── Résolveur principal ───────────────────────────────────
|
|
122
|
+
/**
|
|
123
|
+
* Tente de résoudre un hunk de conflit via le fallback LLM.
|
|
124
|
+
*
|
|
125
|
+
* Pipeline :
|
|
126
|
+
* 1. Construit le prompt (sérialisation hunk + contexte + trace partielle)
|
|
127
|
+
* 2. Calcule le hash SHA-256 du prompt (audit de reproductibilité)
|
|
128
|
+
* 3. Appelle `config.endpoint.call(prompt)` (fourni par le consommateur)
|
|
129
|
+
* 4. Parse la réponse (extrait les lignes résolues)
|
|
130
|
+
* 5. Valide le résultat (`validateMergedContent`)
|
|
131
|
+
* 6. Accepte si `score ≥ minPostMergeScore`, refuse sinon
|
|
132
|
+
* 7. Retourne `LlmResolveResult` avec la trace complète
|
|
133
|
+
*
|
|
134
|
+
* @param hunk - Hunk de conflit à résoudre
|
|
135
|
+
* @param filePath - Chemin du fichier (pour validation post-merge)
|
|
136
|
+
* @param fileContext - ±N lignes autour du hunk (fournies par l'appelant)
|
|
137
|
+
* @param config - Configuration LLM fallback (avec endpoint injecté)
|
|
138
|
+
*/
|
|
139
|
+
export async function tryLlmFallbackResolve(hunk, filePath, fileContext, config) {
|
|
140
|
+
const calledAt = new Date().toISOString();
|
|
141
|
+
const model = config.model ?? "claude-sonnet-4-6";
|
|
142
|
+
const minPostMergeScore = config.minPostMergeScore ?? 80;
|
|
143
|
+
// Vérification de l'endpoint (requis pour que le fallback fonctionne)
|
|
144
|
+
if (!config.endpoint) {
|
|
145
|
+
const trace = {
|
|
146
|
+
calledAt,
|
|
147
|
+
model,
|
|
148
|
+
latencyMs: 0,
|
|
149
|
+
promptHash: "",
|
|
150
|
+
rawResponseTruncated: "",
|
|
151
|
+
validationScore: 0,
|
|
152
|
+
accepted: false,
|
|
153
|
+
};
|
|
154
|
+
return {
|
|
155
|
+
lines: null,
|
|
156
|
+
reason: "LLM fallback ignoré : aucun endpoint injecté (config.endpoint manquant).",
|
|
157
|
+
llmTrace: trace,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const prompt = buildPrompt(hunk, filePath, fileContext, config);
|
|
161
|
+
const promptHash = await sha256Hex(prompt);
|
|
162
|
+
const t0 = Date.now();
|
|
163
|
+
let rawResponse;
|
|
164
|
+
try {
|
|
165
|
+
rawResponse = await config.endpoint.call(prompt);
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
const latencyMs = Date.now() - t0;
|
|
169
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
170
|
+
const trace = {
|
|
171
|
+
calledAt,
|
|
172
|
+
model,
|
|
173
|
+
latencyMs,
|
|
174
|
+
promptHash,
|
|
175
|
+
rawResponseTruncated: "",
|
|
176
|
+
validationScore: 0,
|
|
177
|
+
accepted: false,
|
|
178
|
+
};
|
|
179
|
+
return {
|
|
180
|
+
lines: null,
|
|
181
|
+
reason: `LLM endpoint erreur : ${errMsg}`,
|
|
182
|
+
llmTrace: trace,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
const latencyMs = Date.now() - t0;
|
|
186
|
+
const rawResponseTruncated = rawResponse.slice(0, 500);
|
|
187
|
+
// Parse la réponse brute
|
|
188
|
+
const proposedLines = parseResponse(rawResponse);
|
|
189
|
+
if (proposedLines === null) {
|
|
190
|
+
const trace = {
|
|
191
|
+
calledAt,
|
|
192
|
+
model,
|
|
193
|
+
latencyMs,
|
|
194
|
+
promptHash,
|
|
195
|
+
rawResponseTruncated,
|
|
196
|
+
validationScore: 0,
|
|
197
|
+
accepted: false,
|
|
198
|
+
};
|
|
199
|
+
return {
|
|
200
|
+
lines: null,
|
|
201
|
+
reason: "LLM a refusé de résoudre ce conflit (CANNOT_RESOLVE ou réponse vide).",
|
|
202
|
+
llmTrace: trace,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
// Validation post-merge du contenu proposé
|
|
206
|
+
const candidateContent = proposedLines.join("\n");
|
|
207
|
+
const validation = validateMergedContent(candidateContent, filePath);
|
|
208
|
+
const validationScore = computeValidationScore(validation);
|
|
209
|
+
const accepted = validation.isValid && validationScore >= minPostMergeScore;
|
|
210
|
+
const trace = {
|
|
211
|
+
calledAt,
|
|
212
|
+
model,
|
|
213
|
+
latencyMs,
|
|
214
|
+
promptHash,
|
|
215
|
+
rawResponseTruncated,
|
|
216
|
+
validationScore,
|
|
217
|
+
accepted,
|
|
218
|
+
};
|
|
219
|
+
if (!accepted) {
|
|
220
|
+
const reason = !validation.isValid
|
|
221
|
+
? `LLM résolution refusée : validation échouée (marqueurs résiduels: ${validation.hasResidualMarkers}, syntaxe: ${validation.syntaxError ?? "ok"}).`
|
|
222
|
+
: `LLM résolution refusée : score de validation ${validationScore} < minimum requis ${minPostMergeScore}.`;
|
|
223
|
+
return { lines: null, reason, llmTrace: trace };
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
lines: proposedLines,
|
|
227
|
+
reason: `LLM résolution acceptée (score: ${validationScore}/100, latence: ${latencyMs}ms, modèle: ${model}).`,
|
|
228
|
+
llmTrace: trace,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=llm-fallback.js.map
|