Rifqi Hafizuddin Claude Opus 5.5 commited on
Commit
effd6af
·
1 Parent(s): fc63682

[NOTICKET] fix(scope): lookup artefacts and typed site ids (P0-4)

Browse files

- only a `${tN.col}` value handoff marks tN as a lookup; a Pattern-A
`${t2}` data feed made the answering query a "lookup", so the line fell back
to the site lookup and read "(sebagian kueri)".
- _strip_broken_id_filters strips both FK ends: a typed
`vw_dim_site.site_id = 2009` (Check 8j rejected it, costing a retry).
- the scope line no longer prints `site_id 2009` next to `site_code IPR`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Files changed (1) hide show
  1. src/agents/scope/engine.py +20 -9
src/agents/scope/engine.py CHANGED
@@ -271,7 +271,10 @@ _QUANTIFIERS = ("semua", "seluruh", "setiap", "tiap", "per", "all", "every", "ea
271
  #: entity's own attributes (requirement #4) — the focus is not forced onto it.
272
  ENTITY_MIN_DISTINCT = 200
273
  _NEG_OPS = ("!=", "not_in")
274
- _TASK_REF_RE = re.compile(r"\$\{(t\d+)")
 
 
 
275
 
276
 
277
  def _has_quantifier(text: str) -> bool:
@@ -592,13 +595,14 @@ def _strip_broken_id_filters(
592
  a typed id, a string on the int key, a made-up `${scope.site_id}` (gate run 2: 6 of
593
  31 turns refused on these). A real handoff from a lookup task (`${t1.site_id}`)
594
  stays. True when something was dropped."""
595
- id_cols = {
596
- fk.column_id
597
- for t in in_play
598
- if t is not owner
599
- for fk in t.foreign_keys
600
- if fk.target_table_id == owner.table_id
601
- }
 
602
  kept = [f for f in ir.filters if f.column_id not in id_cols or _is_handoff(f.value)]
603
  if len(kept) == len(ir.filters):
604
  return False
@@ -1002,6 +1006,11 @@ def focus_changed(
1002
  return False
1003
 
1004
 
 
 
 
 
 
1005
  def _render_entry(entry: ScopeEntry, id_: bool) -> str:
1006
  if entry.values is None:
1007
  return f"{entry.column}: {'semua' if id_ else 'all'}"
@@ -1130,10 +1139,12 @@ def render_scope_line(
1130
  # period ran (D1a, 2026-11-03), however many other filters a query carries.
1131
  period_parts: list[str] = []
1132
  others: list[str] = []
 
1133
  for out in outputs:
1134
  for f in _meta_filters(out):
1135
  col = str(f.get("column", "")).lower()
1136
- if col in eff_cols:
 
1137
  continue
1138
  rendered = _render_filter(f)
1139
  bucket = period_parts if col in _PERIOD_COLUMNS else others
 
271
  #: entity's own attributes (requirement #4) — the focus is not forced onto it.
272
  ENTITY_MIN_DISTINCT = 200
273
  _NEG_OPS = ("!=", "not_in")
274
+ # A VALUE handoff `${tN.col}` marks tN as a lookup. A Pattern-A data feed `${tN}` (the
275
+ # rows an analyze_* tool reads) does not: counting it made the answering query a
276
+ # "lookup", the line fell back to the site lookup and read "(sebagian kueri)" (P0-4).
277
+ _TASK_REF_RE = re.compile(r"\$\{(t\d+)\.")
278
 
279
 
280
  def _has_quantifier(text: str) -> bool:
 
595
  a typed id, a string on the int key, a made-up `${scope.site_id}` (gate run 2: 6 of
596
  31 turns refused on these). A real handoff from a lookup task (`${t1.site_id}`)
597
  stays. True when something was dropped."""
598
+ fks = [
599
+ fk for t in in_play if t is not owner
600
+ for fk in t.foreign_keys if fk.target_table_id == owner.table_id
601
+ ]
602
+ # Both ends of the key: the measure table's `site_id` AND the lookup table's own
603
+ # `site_id` — a typed `vw_dim_site.site_id = 2009` is the same guess (P0-4; Check 8j
604
+ # rejected it, costing a retry, because only the FK side was stripped here).
605
+ id_cols = {fk.column_id for fk in fks} | {fk.target_column_id for fk in fks}
606
  kept = [f for f in ir.filters if f.column_id not in id_cols or _is_handoff(f.value)]
607
  if len(kept) == len(ir.filters):
608
  return False
 
1006
  return False
1007
 
1008
 
1009
+ def _stem(column: str) -> str:
1010
+ """`site_id`, `site_code`, `site_name` → `site`: one dimension, several columns."""
1011
+ return re.sub(r"_(id|code|kode|no|name|nama)$", "", column.lower())
1012
+
1013
+
1014
  def _render_entry(entry: ScopeEntry, id_: bool) -> str:
1015
  if entry.values is None:
1016
  return f"{entry.column}: {'semua' if id_ else 'all'}"
 
1139
  # period ran (D1a, 2026-11-03), however many other filters a query carries.
1140
  period_parts: list[str] = []
1141
  others: list[str] = []
1142
+ eff_stems = {_stem(c) for c in eff_cols}
1143
  for out in outputs:
1144
  for f in _meta_filters(out):
1145
  col = str(f.get("column", "")).lower()
1146
+ # `site_id 2009` is the resolved id of `site_code IPR`, already shown (P0-4).
1147
+ if col in eff_cols or _stem(col) in eff_stems:
1148
  continue
1149
  rendered = _render_filter(f)
1150
  bucket = period_parts if col in _PERIOD_COLUMNS else others