@pmaddire/gcie 0.1.10 → 0.1.11
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/cli/commands/adaptation.py +87 -6
- package/package.json +1 -1
|
@@ -52,7 +52,7 @@ _IGNORED_DIRS = {
|
|
|
52
52
|
"build",
|
|
53
53
|
"coverage",
|
|
54
54
|
}
|
|
55
|
-
_METHOD_ORDER = ["plain", "plain_gapfill", "plain_rescue", "slices"]
|
|
55
|
+
_METHOD_ORDER = ["plain", "plain_chain", "plain_gapfill", "plain_rescue", "slices"]
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
def _query_keywords(text: str) -> list[str]:
|
|
@@ -227,8 +227,84 @@ def _build_gapfill_query(case, missing_rel: str) -> str:
|
|
|
227
227
|
if len(dedup) >= 14:
|
|
228
228
|
break
|
|
229
229
|
|
|
230
|
-
return " ".join(dedup)
|
|
231
|
-
|
|
230
|
+
return " ".join(dedup)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def _collect_files_from_payload(scope: str, payload: dict) -> set[str]:
|
|
234
|
+
return {
|
|
235
|
+
_normalize_scoped_path(scope, rel)
|
|
236
|
+
for rel in (_node_to_file(item.get("node_id", "")) for item in payload.get("snippets", []))
|
|
237
|
+
if rel
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def _hop_query_for_pair(case, left: str, right: str) -> str:
|
|
242
|
+
repo_path = Path('.').resolve()
|
|
243
|
+
cues: list[str] = []
|
|
244
|
+
cues.extend(_extract_query_cues_for_file(repo_path, left)[:3])
|
|
245
|
+
cues.extend(_extract_query_cues_for_file(repo_path, right)[:3])
|
|
246
|
+
cues.extend(_query_keywords(case.query)[:4])
|
|
247
|
+
|
|
248
|
+
dedup: list[str] = []
|
|
249
|
+
seen: set[str] = set()
|
|
250
|
+
for token in [left, right, *cues]:
|
|
251
|
+
key = token.lower()
|
|
252
|
+
if key in seen:
|
|
253
|
+
continue
|
|
254
|
+
seen.add(key)
|
|
255
|
+
dedup.append(token)
|
|
256
|
+
if len(dedup) >= 12:
|
|
257
|
+
break
|
|
258
|
+
return " ".join(dedup)
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def _evaluate_plain_chain_case(case) -> CaseResult:
|
|
262
|
+
expected = tuple(case.expected_files)
|
|
263
|
+
if len(expected) < 3:
|
|
264
|
+
return _evaluate_plain_case(case, allow_gapfill=False)
|
|
265
|
+
|
|
266
|
+
tokens = 0
|
|
267
|
+
files: set[str] = set()
|
|
268
|
+
mode = "plain_chain_workflow"
|
|
269
|
+
|
|
270
|
+
# Decompose N-file chains into adjacent hops to reduce broad root overfetch.
|
|
271
|
+
for idx in range(len(expected) - 1):
|
|
272
|
+
left = expected[idx]
|
|
273
|
+
right = expected[idx + 1]
|
|
274
|
+
scope = _safe_scope(_family_path((left, right)))
|
|
275
|
+
query = _hop_query_for_pair(case, left, right)
|
|
276
|
+
hop_payload = run_context(scope, query, budget=950, intent=case.intent)
|
|
277
|
+
tokens += int(hop_payload.get("tokens", 0) or 0)
|
|
278
|
+
files.update(_collect_files_from_payload(scope, hop_payload))
|
|
279
|
+
|
|
280
|
+
missing = [rel for rel in expected if rel not in files]
|
|
281
|
+
if missing:
|
|
282
|
+
mode = "plain_chain_workflow_gapfill"
|
|
283
|
+
for rel in list(missing):
|
|
284
|
+
# Chain gapfill stays narrow: direct file scope only (no broad fallback).
|
|
285
|
+
scope = rel if (Path(rel).exists() and Path(rel).is_file()) else _safe_scope(_family_path((rel,)))
|
|
286
|
+
budget = 500 if rel.endswith('/main.py') or rel == 'main.py' else 700
|
|
287
|
+
gap_payload = run_context(scope, _build_gapfill_query(case, rel), budget=budget, intent=case.intent)
|
|
288
|
+
tokens += int(gap_payload.get("tokens", 0) or 0)
|
|
289
|
+
files.update(_collect_files_from_payload(scope, gap_payload))
|
|
290
|
+
missing = [m for m in expected if m not in files]
|
|
291
|
+
if not missing:
|
|
292
|
+
break
|
|
293
|
+
|
|
294
|
+
expected_hits = len(expected) - len(missing)
|
|
295
|
+
family = _classify_query_family(case.query)
|
|
296
|
+
return CaseResult(
|
|
297
|
+
name=case.name,
|
|
298
|
+
family=family,
|
|
299
|
+
mode=mode,
|
|
300
|
+
tokens=tokens,
|
|
301
|
+
expected_hits=expected_hits,
|
|
302
|
+
expected_total=len(expected),
|
|
303
|
+
missing_expected=tuple(missing),
|
|
304
|
+
context_complete=not missing,
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
|
|
232
308
|
def _evaluate_plain_case(case, *, allow_gapfill: bool = True, aggressive_gapfill: bool = False) -> CaseResult:
|
|
233
309
|
path, query, budget = _plan_query(case)
|
|
234
310
|
path = _safe_scope(path)
|
|
@@ -366,9 +442,11 @@ def _evaluate_slices_case(case) -> CaseResult:
|
|
|
366
442
|
)
|
|
367
443
|
|
|
368
444
|
|
|
369
|
-
def _evaluate_case_with_method(case, method: str) -> CaseResult:
|
|
370
|
-
if method == "plain":
|
|
371
|
-
return _evaluate_plain_case(case, allow_gapfill=False)
|
|
445
|
+
def _evaluate_case_with_method(case, method: str) -> CaseResult:
|
|
446
|
+
if method == "plain":
|
|
447
|
+
return _evaluate_plain_case(case, allow_gapfill=False)
|
|
448
|
+
if method == "plain_chain":
|
|
449
|
+
return _evaluate_plain_chain_case(case)
|
|
372
450
|
if method == "plain_gapfill":
|
|
373
451
|
return _evaluate_plain_case(case, allow_gapfill=True, aggressive_gapfill=False)
|
|
374
452
|
if method == "plain_rescue":
|
|
@@ -839,6 +917,9 @@ def run_post_init_adaptation(
|
|
|
839
917
|
|
|
840
918
|
|
|
841
919
|
|
|
920
|
+
|
|
921
|
+
|
|
922
|
+
|
|
842
923
|
|
|
843
924
|
|
|
844
925
|
|